summaryrefslogtreecommitdiffstats
path: root/swaybar
diff options
context:
space:
mode:
authorLibravatar Ian Fan <ianfan0@gmail.com>2018-10-12 20:32:48 +0100
committerLibravatar Ian Fan <ianfan0@gmail.com>2018-10-14 13:33:12 +0100
commitbcc61e5147fb57a3b4bfb9a2a33065a0cf6da67b (patch)
tree873a09eca473242c15299ea1053966e9d163f6c6 /swaybar
parentswaybar: streamline ipc handling (diff)
downloadsway-bcc61e5147fb57a3b4bfb9a2a33065a0cf6da67b.tar.gz
sway-bcc61e5147fb57a3b4bfb9a2a33065a0cf6da67b.tar.zst
sway-bcc61e5147fb57a3b4bfb9a2a33065a0cf6da67b.zip
swaybar: handle mode/hidden_state changes
As well as adding the hidden_state property to the bar config struct, this commit handles barconfig_update events when the mode or hidden_state changes, and uses a new function determine_bar_visibility to hide or show the bar as required, using, respectively, destroy_layer_surface, which is also newly added, and add_layer_surface, which has been changed to allow dynamically adding the surface.
Diffstat (limited to 'swaybar')
-rw-r--r--swaybar/bar.c62
-rw-r--r--swaybar/config.c4
-rw-r--r--swaybar/ipc.c46
-rw-r--r--swaybar/render.c7
4 files changed, 108 insertions, 11 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c
index 77294136..6894383d 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -32,6 +32,7 @@
32 32
33static void bar_init(struct swaybar *bar) { 33static void bar_init(struct swaybar *bar) {
34 bar->config = init_config(); 34 bar->config = init_config();
35 bar->visible = true;
35 wl_list_init(&bar->outputs); 36 wl_list_init(&bar->outputs);
36} 37}
37 38
@@ -338,21 +339,65 @@ const struct wl_seat_listener seat_listener = {
338}; 339};
339 340
340static void add_layer_surface(struct swaybar_output *output) { 341static void add_layer_surface(struct swaybar_output *output) {
341 if (output->surface != NULL) { 342 if (output->layer_surface) {
342 return; 343 return;
343 } 344 }
344 struct swaybar *bar = output->bar; 345 struct swaybar *bar = output->bar;
345 346
346 output->surface = wl_compositor_create_surface(bar->compositor); 347 struct swaybar_config *config = bar->config;
347 assert(output->surface); 348 bool hidden = strcmp(config->mode, "hide") == 0;
348 output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( 349 output->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
349 bar->layer_shell, output->surface, output->output, 350 bar->layer_shell, output->surface, output->output,
351 hidden ? ZWLR_LAYER_SHELL_V1_LAYER_TOP :
350 ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); 352 ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel");
351 assert(output->layer_surface); 353 assert(output->layer_surface);
352 zwlr_layer_surface_v1_add_listener(output->layer_surface, 354 zwlr_layer_surface_v1_add_listener(output->layer_surface,
353 &layer_surface_listener, output); 355 &layer_surface_listener, output);
354 zwlr_layer_surface_v1_set_anchor(output->layer_surface, 356
355 bar->config->position); 357 zwlr_layer_surface_v1_set_anchor(output->layer_surface, config->position);
358 if (hidden) {
359 zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, -1);
360 }
361}
362
363static void destroy_layer_surface(struct swaybar_output *output) {
364 if (!output->layer_surface) {
365 return;
366 }
367 zwlr_layer_surface_v1_destroy(output->layer_surface);
368 wl_surface_attach(output->surface, NULL, 0, 0); // detach buffer
369 output->layer_surface = NULL;
370 output->height = 0;
371 output->width = 0;
372 output->frame_scheduled = false;
373}
374
375bool determine_bar_visibility(struct swaybar *bar, bool moving_layer) {
376 struct swaybar_config *config = bar->config;
377 bool visible = !(strcmp(config->mode, "invisible") == 0 ||
378 (strcmp(config->mode, config->hidden_state) == 0 // both "hide"
379 && !bar->visible_by_modifier && !bar->visible_by_urgency));
380
381 struct swaybar_output *output;
382 if (visible == bar->visible) {
383 if (visible && moving_layer) {
384 // need to destroy layer surface to move to a different layer
385 wl_list_for_each(output, &bar->outputs, link) {
386 destroy_layer_surface(output);
387 add_layer_surface(output);
388 }
389 }
390 } else {
391 bar->visible = visible;
392 wl_list_for_each(output, &bar->outputs, link) {
393 if (visible) {
394 add_layer_surface(output);
395 } else {
396 destroy_layer_surface(output);
397 }
398 }
399 }
400 return visible;
356} 401}
357 402
358static bool bar_uses_output(struct swaybar *bar, const char *name) { 403static bool bar_uses_output(struct swaybar *bar, const char *name) {
@@ -423,8 +468,11 @@ static void xdg_output_handle_done(void *data,
423 wl_list_remove(&output->link); 468 wl_list_remove(&output->link);
424 wl_list_insert(&bar->outputs, &output->link); 469 wl_list_insert(&bar->outputs, &output->link);
425 470
426 add_layer_surface(output); 471 output->surface = wl_compositor_create_surface(bar->compositor);
427 set_output_dirty(output); 472 assert(output->surface);
473 if (bar->visible) {
474 add_layer_surface(output);
475 }
428 } 476 }
429} 477}
430 478
diff --git a/swaybar/config.c b/swaybar/config.c
index 09d40c24..eafb0b69 100644
--- a/swaybar/config.c
+++ b/swaybar/config.c
@@ -30,7 +30,8 @@ struct swaybar_config *init_config(void) {
30 config->pango_markup = false; 30 config->pango_markup = false;
31 config->position = parse_position("bottom"); 31 config->position = parse_position("bottom");
32 config->font = strdup("monospace 10"); 32 config->font = strdup("monospace 10");
33 config->mode = NULL; 33 config->mode = strdup("dock");
34 config->hidden_state = strdup("hide");
34 config->sep_symbol = NULL; 35 config->sep_symbol = NULL;
35 config->strip_workspace_numbers = false; 36 config->strip_workspace_numbers = false;
36 config->binding_mode_indicator = true; 37 config->binding_mode_indicator = true;
@@ -84,6 +85,7 @@ void free_config(struct swaybar_config *config) {
84 free(config->status_command); 85 free(config->status_command);
85 free(config->font); 86 free(config->font);
86 free(config->mode); 87 free(config->mode);
88 free(config->hidden_state);
87 free(config->sep_symbol); 89 free(config->sep_symbol);
88 for (int i = 0; i < config->bindings->length; i++) { 90 for (int i = 0; i < config->bindings->length; i++) {
89 struct swaybar_binding *binding = config->bindings->items[i]; 91 struct swaybar_binding *binding = config->bindings->items[i];
diff --git a/swaybar/ipc.c b/swaybar/ipc.c
index 6013c2de..56379fdb 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) {
@@ -367,6 +375,37 @@ bool ipc_initialize(struct swaybar *bar) {
367 return true; 375 return true;
368} 376}
369 377
378static bool handle_barconfig_update(struct swaybar *bar,
379 json_object *json_config) {
380 json_object *json_id;
381 json_object_object_get_ex(json_config, "id", &json_id);
382 const char *id = json_object_get_string(json_id);
383 if (strcmp(id, bar->id) != 0) {
384 return false;
385 }
386
387 struct swaybar_config *config = bar->config;
388
389 json_object *json_state;
390 json_object_object_get_ex(json_config, "hidden_state", &json_state);
391 const char *new_state = json_object_get_string(json_state);
392 char *old_state = config->hidden_state;
393 if (strcmp(new_state, old_state) != 0) {
394 wlr_log(WLR_DEBUG, "Changing bar hidden state to %s", new_state);
395 free(old_state);
396 config->hidden_state = strdup(new_state);
397 return determine_bar_visibility(bar, false);
398 }
399
400 free(config->mode);
401 json_object *json_mode;
402 json_object_object_get_ex(json_config, "mode", &json_mode);
403 config->mode = strdup(json_object_get_string(json_mode));
404 wlr_log(WLR_DEBUG, "Changing bar mode to %s", config->mode);
405
406 return determine_bar_visibility(bar, true);
407}
408
370bool handle_ipc_readable(struct swaybar *bar) { 409bool handle_ipc_readable(struct swaybar *bar) {
371 struct ipc_response *resp = ipc_recv_response(bar->ipc_event_socketfd); 410 struct ipc_response *resp = ipc_recv_response(bar->ipc_event_socketfd);
372 if (!resp) { 411 if (!resp) {
@@ -402,6 +441,9 @@ bool handle_ipc_readable(struct swaybar *bar) {
402 } 441 }
403 break; 442 break;
404 } 443 }
444 case IPC_EVENT_BARCONFIG_UPDATE:
445 bar_is_dirty = handle_barconfig_update(bar, result);
446 break;
405 default: 447 default:
406 bar_is_dirty = false; 448 bar_is_dirty = false;
407 break; 449 break;
diff --git a/swaybar/render.c b/swaybar/render.c
index d226ba32..670630cf 100644
--- a/swaybar/render.c
+++ b/swaybar/render.c
@@ -494,6 +494,9 @@ static const struct wl_callback_listener output_frame_listener = {
494 494
495void render_frame(struct swaybar_output *output) { 495void render_frame(struct swaybar_output *output) {
496 assert(output->surface != NULL); 496 assert(output->surface != NULL);
497 if (!output->layer_surface) {
498 return;
499 }
497 500
498 free_hotspots(&output->hotspots); 501 free_hotspots(&output->hotspots);
499 502
@@ -519,7 +522,9 @@ void render_frame(struct swaybar_output *output) {
519 if (height != output->height) { 522 if (height != output->height) {
520 // Reconfigure surface 523 // Reconfigure surface
521 zwlr_layer_surface_v1_set_size(output->layer_surface, 0, height); 524 zwlr_layer_surface_v1_set_size(output->layer_surface, 0, height);
522 zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, height); 525 if (strcmp(output->bar->config->mode, "dock") == 0) {
526 zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, height);
527 }
523 // TODO: this could infinite loop if the compositor assigns us a 528 // TODO: this could infinite loop if the compositor assigns us a
524 // different height than what we asked for 529 // different height than what we asked for
525 wl_surface_commit(output->surface); 530 wl_surface_commit(output->surface);