diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-10-14 15:13:50 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-14 15:13:50 +0200 |
commit | 4a05fbf8ab364657763b1d1058bdf9b4c2727b76 (patch) | |
tree | c405121528d191ba74fe329fdb18093810d9b73c /swaybar/ipc.c | |
parent | Merge pull request #2808 from RedSoxFan/bar-subcommands (diff) | |
parent | swaybar: add documentation for hide/hidden_state subcommands (diff) | |
download | sway-4a05fbf8ab364657763b1d1058bdf9b4c2727b76.tar.gz sway-4a05fbf8ab364657763b1d1058bdf9b4c2727b76.tar.zst sway-4a05fbf8ab364657763b1d1058bdf9b4c2727b76.zip |
Merge pull request #2751 from ianyfan/swaybar
Bar mode/hidden_state events
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( | |||
152 | json_object_put(bar_config); | 152 | json_object_put(bar_config); |
153 | return false; | 153 | return false; |
154 | } | 154 | } |
155 | json_object *markup, *mode, *hidden_bar, *position, *status_command; | 155 | json_object *markup, *mode, *hidden_state, *position, *status_command; |
156 | json_object *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers; | 156 | json_object *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers; |
157 | json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs; | 157 | json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs; |
158 | json_object *bindings; | 158 | json_object *bindings; |
159 | json_object_object_get_ex(bar_config, "mode", &mode); | 159 | json_object_object_get_ex(bar_config, "mode", &mode); |
160 | json_object_object_get_ex(bar_config, "hidden_bar", &hidden_bar); | 160 | json_object_object_get_ex(bar_config, "hidden_state", &hidden_state); |
161 | json_object_object_get_ex(bar_config, "position", &position); | 161 | json_object_object_get_ex(bar_config, "position", &position); |
162 | json_object_object_get_ex(bar_config, "status_command", &status_command); | 162 | json_object_object_get_ex(bar_config, "status_command", &status_command); |
163 | json_object_object_get_ex(bar_config, "font", &font); | 163 | json_object_object_get_ex(bar_config, "font", &font); |
@@ -220,6 +220,14 @@ static bool ipc_parse_config( | |||
220 | list_add(config->bindings, binding); | 220 | list_add(config->bindings, binding); |
221 | } | 221 | } |
222 | } | 222 | } |
223 | if (hidden_state) { | ||
224 | free(config->hidden_state); | ||
225 | config->hidden_state = strdup(json_object_get_string(hidden_state)); | ||
226 | } | ||
227 | if (mode) { | ||
228 | free(config->mode); | ||
229 | config->mode = strdup(json_object_get_string(mode)); | ||
230 | } | ||
223 | 231 | ||
224 | struct config_output *output, *tmp; | 232 | struct config_output *output, *tmp; |
225 | wl_list_for_each_safe(output, tmp, &config->outputs, link) { | 233 | wl_list_for_each_safe(output, tmp, &config->outputs, link) { |
@@ -254,7 +262,7 @@ static bool ipc_parse_config( | |||
254 | return true; | 262 | return true; |
255 | } | 263 | } |
256 | 264 | ||
257 | void ipc_get_workspaces(struct swaybar *bar) { | 265 | bool ipc_get_workspaces(struct swaybar *bar) { |
258 | struct swaybar_output *output; | 266 | struct swaybar_output *output; |
259 | wl_list_for_each(output, &bar->outputs, link) { | 267 | wl_list_for_each(output, &bar->outputs, link) { |
260 | free_workspaces(&output->workspaces); | 268 | free_workspaces(&output->workspaces); |
@@ -266,8 +274,10 @@ void ipc_get_workspaces(struct swaybar *bar) { | |||
266 | json_object *results = json_tokener_parse(res); | 274 | json_object *results = json_tokener_parse(res); |
267 | if (!results) { | 275 | if (!results) { |
268 | free(res); | 276 | free(res); |
269 | return; | 277 | return false; |
270 | } | 278 | } |
279 | |||
280 | bar->visible_by_urgency = false; | ||
271 | size_t length = json_object_array_length(results); | 281 | size_t length = json_object_array_length(results); |
272 | json_object *ws_json; | 282 | json_object *ws_json; |
273 | json_object *num, *name, *visible, *focused, *out, *urgent; | 283 | json_object *num, *name, *visible, *focused, *out, *urgent; |
@@ -294,12 +304,16 @@ void ipc_get_workspaces(struct swaybar *bar) { | |||
294 | output->focused = true; | 304 | output->focused = true; |
295 | } | 305 | } |
296 | ws->urgent = json_object_get_boolean(urgent); | 306 | ws->urgent = json_object_get_boolean(urgent); |
307 | if (ws->urgent) { | ||
308 | bar->visible_by_urgency = true; | ||
309 | } | ||
297 | wl_list_insert(&output->workspaces, &ws->link); | 310 | wl_list_insert(&output->workspaces, &ws->link); |
298 | } | 311 | } |
299 | } | 312 | } |
300 | } | 313 | } |
301 | json_object_put(results); | 314 | json_object_put(results); |
302 | free(res); | 315 | free(res); |
316 | return determine_bar_visibility(bar, false); | ||
303 | } | 317 | } |
304 | 318 | ||
305 | static void ipc_get_outputs(struct swaybar *bar) { | 319 | static void ipc_get_outputs(struct swaybar *bar) { |
@@ -345,10 +359,10 @@ void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind) { | |||
345 | IPC_COMMAND, bind->command, &len)); | 359 | IPC_COMMAND, bind->command, &len)); |
346 | } | 360 | } |
347 | 361 | ||
348 | bool ipc_initialize(struct swaybar *bar, const char *bar_id) { | 362 | bool ipc_initialize(struct swaybar *bar) { |
349 | uint32_t len = strlen(bar_id); | 363 | uint32_t len = strlen(bar->id); |
350 | char *res = ipc_single_command(bar->ipc_socketfd, | 364 | char *res = ipc_single_command(bar->ipc_socketfd, |
351 | IPC_GET_BAR_CONFIG, bar_id, &len); | 365 | IPC_GET_BAR_CONFIG, bar->id, &len); |
352 | if (!ipc_parse_config(bar->config, res)) { | 366 | if (!ipc_parse_config(bar->config, res)) { |
353 | free(res); | 367 | free(res); |
354 | return false; | 368 | return false; |
@@ -356,56 +370,108 @@ bool ipc_initialize(struct swaybar *bar, const char *bar_id) { | |||
356 | free(res); | 370 | free(res); |
357 | ipc_get_outputs(bar); | 371 | ipc_get_outputs(bar); |
358 | 372 | ||
359 | const char *subscribe = "[ \"workspace\", \"mode\" ]"; | 373 | struct swaybar_config *config = bar->config; |
360 | len = strlen(subscribe); | 374 | char subscribe[128]; // suitably large buffer |
375 | len = snprintf(subscribe, 128, | ||
376 | "[ \"barconfig_update\" , \"bar_state_update\" %s %s ]", | ||
377 | config->binding_mode_indicator ? ", \"mode\"" : "", | ||
378 | config->workspace_buttons ? ", \"workspace\"" : ""); | ||
361 | free(ipc_single_command(bar->ipc_event_socketfd, | 379 | free(ipc_single_command(bar->ipc_event_socketfd, |
362 | IPC_SUBSCRIBE, subscribe, &len)); | 380 | IPC_SUBSCRIBE, subscribe, &len)); |
363 | return true; | 381 | return true; |
364 | } | 382 | } |
365 | 383 | ||
384 | static bool handle_bar_state_update(struct swaybar *bar, json_object *event) { | ||
385 | json_object *json_id; | ||
386 | json_object_object_get_ex(event, "id", &json_id); | ||
387 | const char *id = json_object_get_string(json_id); | ||
388 | if (strcmp(id, bar->id) != 0) { | ||
389 | return false; | ||
390 | } | ||
391 | |||
392 | json_object *visible_by_modifier; | ||
393 | json_object_object_get_ex(event, "visible_by_modifier", &visible_by_modifier); | ||
394 | bar->visible_by_modifier = json_object_get_boolean(visible_by_modifier); | ||
395 | return determine_bar_visibility(bar, false); | ||
396 | } | ||
397 | |||
398 | static bool handle_barconfig_update(struct swaybar *bar, | ||
399 | json_object *json_config) { | ||
400 | json_object *json_id; | ||
401 | json_object_object_get_ex(json_config, "id", &json_id); | ||
402 | const char *id = json_object_get_string(json_id); | ||
403 | if (strcmp(id, bar->id) != 0) { | ||
404 | return false; | ||
405 | } | ||
406 | |||
407 | struct swaybar_config *config = bar->config; | ||
408 | |||
409 | json_object *json_state; | ||
410 | json_object_object_get_ex(json_config, "hidden_state", &json_state); | ||
411 | const char *new_state = json_object_get_string(json_state); | ||
412 | char *old_state = config->hidden_state; | ||
413 | if (strcmp(new_state, old_state) != 0) { | ||
414 | wlr_log(WLR_DEBUG, "Changing bar hidden state to %s", new_state); | ||
415 | free(old_state); | ||
416 | config->hidden_state = strdup(new_state); | ||
417 | return determine_bar_visibility(bar, false); | ||
418 | } | ||
419 | |||
420 | free(config->mode); | ||
421 | json_object *json_mode; | ||
422 | json_object_object_get_ex(json_config, "mode", &json_mode); | ||
423 | config->mode = strdup(json_object_get_string(json_mode)); | ||
424 | wlr_log(WLR_DEBUG, "Changing bar mode to %s", config->mode); | ||
425 | |||
426 | return determine_bar_visibility(bar, true); | ||
427 | } | ||
428 | |||
366 | bool handle_ipc_readable(struct swaybar *bar) { | 429 | bool handle_ipc_readable(struct swaybar *bar) { |
367 | struct ipc_response *resp = ipc_recv_response(bar->ipc_event_socketfd); | 430 | struct ipc_response *resp = ipc_recv_response(bar->ipc_event_socketfd); |
368 | if (!resp) { | 431 | if (!resp) { |
369 | return false; | 432 | return false; |
370 | } | 433 | } |
434 | |||
435 | json_object *result = json_tokener_parse(resp->payload); | ||
436 | if (!result) { | ||
437 | wlr_log(WLR_ERROR, "failed to parse payload as json"); | ||
438 | free_ipc_response(resp); | ||
439 | return false; | ||
440 | } | ||
441 | |||
442 | bool bar_is_dirty = true; | ||
371 | switch (resp->type) { | 443 | switch (resp->type) { |
372 | case IPC_EVENT_WORKSPACE: | 444 | case IPC_EVENT_WORKSPACE: |
373 | ipc_get_workspaces(bar); | 445 | bar_is_dirty = ipc_get_workspaces(bar); |
374 | break; | 446 | break; |
375 | case IPC_EVENT_MODE: { | 447 | case IPC_EVENT_MODE: { |
376 | json_object *result = json_tokener_parse(resp->payload); | ||
377 | if (!result) { | ||
378 | free_ipc_response(resp); | ||
379 | wlr_log(WLR_ERROR, "failed to parse payload as json"); | ||
380 | return false; | ||
381 | } | ||
382 | json_object *json_change, *json_pango_markup; | 448 | json_object *json_change, *json_pango_markup; |
383 | if (json_object_object_get_ex(result, "change", &json_change)) { | 449 | if (json_object_object_get_ex(result, "change", &json_change)) { |
384 | const char *change = json_object_get_string(json_change); | 450 | const char *change = json_object_get_string(json_change); |
385 | free(bar->config->mode); | 451 | free(bar->mode); |
386 | if (strcmp(change, "default") == 0) { | 452 | bar->mode = strcmp(change, "default") != 0 ? strdup(change) : NULL; |
387 | bar->config->mode = NULL; | ||
388 | } else { | ||
389 | bar->config->mode = strdup(change); | ||
390 | } | ||
391 | } else { | 453 | } else { |
392 | wlr_log(WLR_ERROR, "failed to parse response"); | 454 | wlr_log(WLR_ERROR, "failed to parse response"); |
393 | json_object_put(result); | 455 | bar_is_dirty = false; |
394 | free_ipc_response(resp); | 456 | break; |
395 | return false; | ||
396 | } | 457 | } |
397 | if (json_object_object_get_ex(result, | 458 | if (json_object_object_get_ex(result, |
398 | "pango_markup", &json_pango_markup)) { | 459 | "pango_markup", &json_pango_markup)) { |
399 | bar->config->mode_pango_markup = json_object_get_boolean( | 460 | bar->mode_pango_markup = json_object_get_boolean(json_pango_markup); |
400 | json_pango_markup); | ||
401 | } | 461 | } |
402 | json_object_put(result); | ||
403 | break; | 462 | break; |
404 | } | 463 | } |
464 | case IPC_EVENT_BARCONFIG_UPDATE: | ||
465 | bar_is_dirty = handle_barconfig_update(bar, result); | ||
466 | break; | ||
467 | case IPC_EVENT_BAR_STATE_UPDATE: | ||
468 | bar_is_dirty = handle_bar_state_update(bar, result); | ||
469 | break; | ||
405 | default: | 470 | default: |
406 | free_ipc_response(resp); | 471 | bar_is_dirty = false; |
407 | return false; | 472 | break; |
408 | } | 473 | } |
474 | json_object_put(result); | ||
409 | free_ipc_response(resp); | 475 | free_ipc_response(resp); |
410 | return true; | 476 | return bar_is_dirty; |
411 | } | 477 | } |