aboutsummaryrefslogtreecommitdiff
path: root/i3bar/src/workspaces.c
diff options
context:
space:
mode:
Diffstat (limited to 'i3bar/src/workspaces.c')
-rw-r--r--i3bar/src/workspaces.c94
1 files changed, 53 insertions, 41 deletions
diff --git a/i3bar/src/workspaces.c b/i3bar/src/workspaces.c
index bd56f5d0..10c9fcf0 100644
--- a/i3bar/src/workspaces.c
+++ b/i3bar/src/workspaces.c
@@ -19,7 +19,8 @@ struct workspaces_json_params {
struct ws_head *workspaces;
i3_ws *workspaces_walk;
char *cur_key;
- char *json;
+ bool need_output;
+ bool parsing_rect;
};
/*
@@ -71,26 +72,23 @@ static int workspaces_integer_cb(void *params_, long long val) {
return 1;
}
+ /* rect is unused, so we don't bother to save it */
if (!strcmp(params->cur_key, "x")) {
- params->workspaces_walk->rect.x = (int)val;
FREE(params->cur_key);
return 1;
}
if (!strcmp(params->cur_key, "y")) {
- params->workspaces_walk->rect.y = (int)val;
FREE(params->cur_key);
return 1;
}
if (!strcmp(params->cur_key, "width")) {
- params->workspaces_walk->rect.w = (int)val;
FREE(params->cur_key);
return 1;
}
if (!strcmp(params->cur_key, "height")) {
- params->workspaces_walk->rect.h = (int)val;
FREE(params->cur_key);
return 1;
}
@@ -156,15 +154,16 @@ static int workspaces_string_cb(void *params_, const unsigned char *val, size_t
sasprintf(&output_name, "%.*s", len, val);
i3_output *target = get_output_by_name(output_name);
+ i3_ws *ws = params->workspaces_walk;
if (target != NULL) {
- params->workspaces_walk->output = target;
-
- TAILQ_INSERT_TAIL(params->workspaces_walk->output->workspaces,
- params->workspaces_walk,
- tailq);
+ ws->output = target;
+ TAILQ_INSERT_TAIL(ws->output->workspaces, ws, tailq);
}
+ params->need_output = false;
FREE(output_name);
+ FREE(params->cur_key);
+
return 1;
}
@@ -172,28 +171,42 @@ static int workspaces_string_cb(void *params_, const unsigned char *val, size_t
}
/*
- * We hit the start of a JSON map (rect or a new output)
+ * We hit the start of a JSON map (rect or a new workspace)
*
*/
static int workspaces_start_map_cb(void *params_) {
struct workspaces_json_params *params = (struct workspaces_json_params *)params_;
- i3_ws *new_workspace = NULL;
-
if (params->cur_key == NULL) {
- new_workspace = smalloc(sizeof(i3_ws));
+ i3_ws *new_workspace = scalloc(1, sizeof(i3_ws));
new_workspace->num = -1;
- new_workspace->name = NULL;
- new_workspace->visible = 0;
- new_workspace->focused = 0;
- new_workspace->urgent = 0;
- memset(&new_workspace->rect, 0, sizeof(rect));
- new_workspace->output = NULL;
params->workspaces_walk = new_workspace;
+ params->need_output = true;
+ params->parsing_rect = false;
+ } else {
+ params->parsing_rect = true;
+ }
+
+ return 1;
+}
+
+static int workspaces_end_map_cb(void *params_) {
+ struct workspaces_json_params *params = (struct workspaces_json_params *)params_;
+ i3_ws *ws = params->workspaces_walk;
+ const bool parsing_rect = params->parsing_rect;
+ params->parsing_rect = false;
+
+ if (parsing_rect || !ws || !ws->name || !params->need_output) {
return 1;
}
+ ws->output = get_output_by_name("primary");
+ if (ws->output == NULL) {
+ ws->output = SLIST_FIRST(outputs);
+ }
+ TAILQ_INSERT_TAIL(ws->output->workspaces, ws, tailq);
+
return 1;
}
@@ -216,43 +229,42 @@ static yajl_callbacks workspaces_callbacks = {
.yajl_integer = workspaces_integer_cb,
.yajl_string = workspaces_string_cb,
.yajl_start_map = workspaces_start_map_cb,
+ .yajl_end_map = workspaces_end_map_cb,
.yajl_map_key = workspaces_map_key_cb,
};
/*
- * Start parsing the received JSON string
+ * Parse the received JSON string
*
*/
-void parse_workspaces_json(char *json) {
- /* FIXME: Fasciliate stream processing, i.e. allow starting to interpret
- * JSON in chunks */
- struct workspaces_json_params params;
-
+void parse_workspaces_json(const unsigned char *json, size_t size) {
free_workspaces();
- params.workspaces_walk = NULL;
- params.cur_key = NULL;
- params.json = json;
-
- yajl_handle handle;
- yajl_status state;
- handle = yajl_alloc(&workspaces_callbacks, NULL, (void *)&params);
-
- state = yajl_parse(handle, (const unsigned char *)json, strlen(json));
+ struct workspaces_json_params params = {0};
+ yajl_handle handle = yajl_alloc(&workspaces_callbacks, NULL, (void *)&params);
+ yajl_status state = yajl_parse(handle, json, size);
/* FIXME: Proper error handling for JSON parsing */
switch (state) {
case yajl_status_ok:
break;
case yajl_status_client_canceled:
- case yajl_status_error:
- ELOG("Could not parse workspaces reply!\n");
- exit(EXIT_FAILURE);
+ case yajl_status_error: {
+ unsigned char *err = yajl_get_error(handle, 1, json, size);
+ ELOG("Could not parse workspaces reply, error:\n%s\njson:---%s---\n", err, json);
+ yajl_free_error(handle, err);
+
+ if (config.workspace_command) {
+ kill_ws_child();
+ set_workspace_button_error("Could not parse workspace_command's JSON");
+ } else {
+ exit(EXIT_FAILURE);
+ }
break;
+ }
}
yajl_free(handle);
-
FREE(params.cur_key);
}
@@ -261,14 +273,14 @@ void parse_workspaces_json(char *json) {
*
*/
void free_workspaces(void) {
- i3_output *outputs_walk;
if (outputs == NULL) {
return;
}
- i3_ws *ws_walk;
+ i3_output *outputs_walk;
SLIST_FOREACH (outputs_walk, outputs, slist) {
if (outputs_walk->workspaces != NULL && !TAILQ_EMPTY(outputs_walk->workspaces)) {
+ i3_ws *ws_walk;
TAILQ_FOREACH (ws_walk, outputs_walk->workspaces, tailq) {
I3STRING_FREE(ws_walk->name);
FREE(ws_walk->canonical_name);