aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar/ipc.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/ipc.c')
-rw-r--r--swaybar/ipc.c128
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
257void ipc_get_workspaces(struct swaybar *bar) { 265bool 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
305static void ipc_get_outputs(struct swaybar *bar) { 319static 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
348bool ipc_initialize(struct swaybar *bar, const char *bar_id) { 362bool 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
384static 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
398static 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
366bool handle_ipc_readable(struct swaybar *bar) { 429bool 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}