diff options
Diffstat (limited to 'swaybar/ipc.c')
-rw-r--r-- | swaybar/ipc.c | 128 |
1 files changed, 97 insertions, 31 deletions
diff --git a/swaybar/ipc.c b/swaybar/ipc.c index a67814c1..e1b30b52 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -152,12 +152,12 @@ static bool ipc_parse_config( json_object_put(bar_config); return false; } - json_object *markup, *mode, *hidden_bar, *position, *status_command; + json_object *markup, *mode, *hidden_state, *position, *status_command; json_object *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers; json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs; json_object *bindings; json_object_object_get_ex(bar_config, "mode", &mode); - json_object_object_get_ex(bar_config, "hidden_bar", &hidden_bar); + json_object_object_get_ex(bar_config, "hidden_state", &hidden_state); json_object_object_get_ex(bar_config, "position", &position); json_object_object_get_ex(bar_config, "status_command", &status_command); json_object_object_get_ex(bar_config, "font", &font); @@ -220,6 +220,14 @@ static bool ipc_parse_config( list_add(config->bindings, binding); } } + if (hidden_state) { + free(config->hidden_state); + config->hidden_state = strdup(json_object_get_string(hidden_state)); + } + if (mode) { + free(config->mode); + config->mode = strdup(json_object_get_string(mode)); + } struct config_output *output, *tmp; wl_list_for_each_safe(output, tmp, &config->outputs, link) { @@ -254,7 +262,7 @@ static bool ipc_parse_config( return true; } -void ipc_get_workspaces(struct swaybar *bar) { +bool ipc_get_workspaces(struct swaybar *bar) { struct swaybar_output *output; wl_list_for_each(output, &bar->outputs, link) { free_workspaces(&output->workspaces); @@ -266,8 +274,10 @@ void ipc_get_workspaces(struct swaybar *bar) { json_object *results = json_tokener_parse(res); if (!results) { free(res); - return; + return false; } + + bar->visible_by_urgency = false; size_t length = json_object_array_length(results); json_object *ws_json; json_object *num, *name, *visible, *focused, *out, *urgent; @@ -294,12 +304,16 @@ void ipc_get_workspaces(struct swaybar *bar) { output->focused = true; } ws->urgent = json_object_get_boolean(urgent); + if (ws->urgent) { + bar->visible_by_urgency = true; + } wl_list_insert(&output->workspaces, &ws->link); } } } json_object_put(results); free(res); + return determine_bar_visibility(bar, false); } static void ipc_get_outputs(struct swaybar *bar) { @@ -345,10 +359,10 @@ void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind) { IPC_COMMAND, bind->command, &len)); } -bool ipc_initialize(struct swaybar *bar, const char *bar_id) { - uint32_t len = strlen(bar_id); +bool ipc_initialize(struct swaybar *bar) { + uint32_t len = strlen(bar->id); char *res = ipc_single_command(bar->ipc_socketfd, - IPC_GET_BAR_CONFIG, bar_id, &len); + IPC_GET_BAR_CONFIG, bar->id, &len); if (!ipc_parse_config(bar->config, res)) { free(res); return false; @@ -356,56 +370,108 @@ bool ipc_initialize(struct swaybar *bar, const char *bar_id) { free(res); ipc_get_outputs(bar); - const char *subscribe = "[ \"workspace\", \"mode\" ]"; - len = strlen(subscribe); + struct swaybar_config *config = bar->config; + char subscribe[128]; // suitably large buffer + len = snprintf(subscribe, 128, + "[ \"barconfig_update\" , \"bar_state_update\" %s %s ]", + config->binding_mode_indicator ? ", \"mode\"" : "", + config->workspace_buttons ? ", \"workspace\"" : ""); free(ipc_single_command(bar->ipc_event_socketfd, IPC_SUBSCRIBE, subscribe, &len)); return true; } +static bool handle_bar_state_update(struct swaybar *bar, json_object *event) { + json_object *json_id; + json_object_object_get_ex(event, "id", &json_id); + const char *id = json_object_get_string(json_id); + if (strcmp(id, bar->id) != 0) { + return false; + } + + json_object *visible_by_modifier; + json_object_object_get_ex(event, "visible_by_modifier", &visible_by_modifier); + bar->visible_by_modifier = json_object_get_boolean(visible_by_modifier); + return determine_bar_visibility(bar, false); +} + +static bool handle_barconfig_update(struct swaybar *bar, + json_object *json_config) { + json_object *json_id; + json_object_object_get_ex(json_config, "id", &json_id); + const char *id = json_object_get_string(json_id); + if (strcmp(id, bar->id) != 0) { + return false; + } + + struct swaybar_config *config = bar->config; + + json_object *json_state; + json_object_object_get_ex(json_config, "hidden_state", &json_state); + const char *new_state = json_object_get_string(json_state); + char *old_state = config->hidden_state; + if (strcmp(new_state, old_state) != 0) { + wlr_log(WLR_DEBUG, "Changing bar hidden state to %s", new_state); + free(old_state); + config->hidden_state = strdup(new_state); + return determine_bar_visibility(bar, false); + } + + free(config->mode); + json_object *json_mode; + json_object_object_get_ex(json_config, "mode", &json_mode); + config->mode = strdup(json_object_get_string(json_mode)); + wlr_log(WLR_DEBUG, "Changing bar mode to %s", config->mode); + + return determine_bar_visibility(bar, true); +} + bool handle_ipc_readable(struct swaybar *bar) { struct ipc_response *resp = ipc_recv_response(bar->ipc_event_socketfd); if (!resp) { return false; } + + json_object *result = json_tokener_parse(resp->payload); + if (!result) { + wlr_log(WLR_ERROR, "failed to parse payload as json"); + free_ipc_response(resp); + return false; + } + + bool bar_is_dirty = true; switch (resp->type) { case IPC_EVENT_WORKSPACE: - ipc_get_workspaces(bar); + bar_is_dirty = ipc_get_workspaces(bar); break; case IPC_EVENT_MODE: { - json_object *result = json_tokener_parse(resp->payload); - if (!result) { - free_ipc_response(resp); - wlr_log(WLR_ERROR, "failed to parse payload as json"); - return false; - } json_object *json_change, *json_pango_markup; if (json_object_object_get_ex(result, "change", &json_change)) { const char *change = json_object_get_string(json_change); - free(bar->config->mode); - if (strcmp(change, "default") == 0) { - bar->config->mode = NULL; - } else { - bar->config->mode = strdup(change); - } + free(bar->mode); + bar->mode = strcmp(change, "default") != 0 ? strdup(change) : NULL; } else { wlr_log(WLR_ERROR, "failed to parse response"); - json_object_put(result); - free_ipc_response(resp); - return false; + bar_is_dirty = false; + break; } if (json_object_object_get_ex(result, "pango_markup", &json_pango_markup)) { - bar->config->mode_pango_markup = json_object_get_boolean( - json_pango_markup); + bar->mode_pango_markup = json_object_get_boolean(json_pango_markup); } - json_object_put(result); break; } + case IPC_EVENT_BARCONFIG_UPDATE: + bar_is_dirty = handle_barconfig_update(bar, result); + break; + case IPC_EVENT_BAR_STATE_UPDATE: + bar_is_dirty = handle_bar_state_update(bar, result); + break; default: - free_ipc_response(resp); - return false; + bar_is_dirty = false; + break; } + json_object_put(result); free_ipc_response(resp); - return true; + return bar_is_dirty; } |