diff options
author | emersion <contact@emersion.fr> | 2018-09-19 11:37:24 +0200 |
---|---|---|
committer | emersion <contact@emersion.fr> | 2018-09-20 18:37:51 +0200 |
commit | 82f1393cbb7383179eab2d10ff679a975d1f5c43 (patch) | |
tree | 97fd40cb652ac233fdbf03929da1977bc89d1bcb | |
parent | Merge pull request #2671 from emersion/output-execute-no-focus (diff) | |
download | sway-82f1393cbb7383179eab2d10ff679a975d1f5c43.tar.gz sway-82f1393cbb7383179eab2d10ff679a975d1f5c43.tar.zst sway-82f1393cbb7383179eab2d10ff679a975d1f5c43.zip |
swaybar: handle hotplugging
Don't kill and respawn swaybars on hotplug.
-rw-r--r-- | include/sway/config.h | 4 | ||||
-rw-r--r-- | sway/config/bar.c | 26 | ||||
-rw-r--r-- | sway/main.c | 1 | ||||
-rw-r--r-- | sway/tree/output.c | 2 | ||||
-rw-r--r-- | swaybar/bar.c | 111 | ||||
-rw-r--r-- | swaybar/render.c | 3 |
6 files changed, 81 insertions, 66 deletions
diff --git a/include/sway/config.h b/include/sway/config.h index b53c1f1f..36d78ec6 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -512,9 +512,7 @@ void free_sway_binding(struct sway_binding *sb); | |||
512 | 512 | ||
513 | void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding); | 513 | void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding); |
514 | 514 | ||
515 | void load_swaybars(); | 515 | void load_swaybars(void); |
516 | |||
517 | void invoke_swaybar(struct bar_config *bar); | ||
518 | 516 | ||
519 | void terminate_swaybg(pid_t pid); | 517 | void terminate_swaybg(pid_t pid); |
520 | 518 | ||
diff --git a/sway/config/bar.c b/sway/config/bar.c index f83b37d1..48a632fb 100644 --- a/sway/config/bar.c +++ b/sway/config/bar.c | |||
@@ -165,7 +165,7 @@ cleanup: | |||
165 | return NULL; | 165 | return NULL; |
166 | } | 166 | } |
167 | 167 | ||
168 | void invoke_swaybar(struct bar_config *bar) { | 168 | static void invoke_swaybar(struct bar_config *bar) { |
169 | // Pipe to communicate errors | 169 | // Pipe to communicate errors |
170 | int filedes[2]; | 170 | int filedes[2]; |
171 | if (pipe(filedes) == -1) { | 171 | if (pipe(filedes) == -1) { |
@@ -219,27 +219,13 @@ void invoke_swaybar(struct bar_config *bar) { | |||
219 | close(filedes[1]); | 219 | close(filedes[1]); |
220 | } | 220 | } |
221 | 221 | ||
222 | void load_swaybars() { | 222 | void load_swaybars(void) { |
223 | for (int i = 0; i < config->bars->length; ++i) { | 223 | for (int i = 0; i < config->bars->length; ++i) { |
224 | struct bar_config *bar = config->bars->items[i]; | 224 | struct bar_config *bar = config->bars->items[i]; |
225 | bool apply = false; | 225 | if (bar->pid != 0) { |
226 | if (bar->outputs) { | 226 | terminate_swaybar(bar->pid); |
227 | for (int j = 0; j < bar->outputs->length; ++j) { | ||
228 | char *o = bar->outputs->items[j]; | ||
229 | if (!strcmp(o, "*") || output_by_name(o)) { | ||
230 | apply = true; | ||
231 | break; | ||
232 | } | ||
233 | } | ||
234 | } else { | ||
235 | apply = true; | ||
236 | } | ||
237 | if (apply) { | ||
238 | if (bar->pid != 0) { | ||
239 | terminate_swaybar(bar->pid); | ||
240 | } | ||
241 | wlr_log(WLR_DEBUG, "Invoking swaybar for bar id '%s'", bar->id); | ||
242 | invoke_swaybar(bar); | ||
243 | } | 227 | } |
228 | wlr_log(WLR_DEBUG, "Invoking swaybar for bar id '%s'", bar->id); | ||
229 | invoke_swaybar(bar); | ||
244 | } | 230 | } |
245 | } | 231 | } |
diff --git a/sway/main.c b/sway/main.c index fb4f0d8c..3d7cd158 100644 --- a/sway/main.c +++ b/sway/main.c | |||
@@ -424,6 +424,7 @@ int main(int argc, char **argv) { | |||
424 | } | 424 | } |
425 | 425 | ||
426 | config->active = true; | 426 | config->active = true; |
427 | load_swaybars(); | ||
427 | // Execute commands until there are none left | 428 | // Execute commands until there are none left |
428 | wlr_log(WLR_DEBUG, "Running deferred commands"); | 429 | wlr_log(WLR_DEBUG, "Running deferred commands"); |
429 | while (config->cmd_queue->length) { | 430 | while (config->cmd_queue->length) { |
diff --git a/sway/tree/output.c b/sway/tree/output.c index 1976ad51..06933dc4 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c | |||
@@ -109,8 +109,6 @@ void output_enable(struct sway_output *output, struct output_config *oc) { | |||
109 | 109 | ||
110 | wl_signal_emit(&root->events.new_node, &output->node); | 110 | wl_signal_emit(&root->events.new_node, &output->node); |
111 | 111 | ||
112 | load_swaybars(); | ||
113 | |||
114 | arrange_layers(output); | 112 | arrange_layers(output); |
115 | arrange_root(); | 113 | arrange_root(); |
116 | } | 114 | } |
diff --git a/swaybar/bar.c b/swaybar/bar.c index 3ae730f7..49a8ece1 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c | |||
@@ -48,8 +48,13 @@ static void swaybar_output_free(struct swaybar_output *output) { | |||
48 | return; | 48 | return; |
49 | } | 49 | } |
50 | wlr_log(WLR_DEBUG, "Removing output %s", output->name); | 50 | wlr_log(WLR_DEBUG, "Removing output %s", output->name); |
51 | zwlr_layer_surface_v1_destroy(output->layer_surface); | 51 | if (output->layer_surface != NULL) { |
52 | wl_surface_destroy(output->surface); | 52 | zwlr_layer_surface_v1_destroy(output->layer_surface); |
53 | } | ||
54 | if (output->surface != NULL) { | ||
55 | wl_surface_destroy(output->surface); | ||
56 | } | ||
57 | zxdg_output_v1_destroy(output->xdg_output); | ||
53 | wl_output_destroy(output->output); | 58 | wl_output_destroy(output->output); |
54 | destroy_buffer(&output->buffers[0]); | 59 | destroy_buffer(&output->buffers[0]); |
55 | destroy_buffer(&output->buffers[1]); | 60 | destroy_buffer(&output->buffers[1]); |
@@ -283,6 +288,37 @@ const struct wl_seat_listener seat_listener = { | |||
283 | .name = seat_handle_name, | 288 | .name = seat_handle_name, |
284 | }; | 289 | }; |
285 | 290 | ||
291 | static void add_layer_surface(struct swaybar_output *output) { | ||
292 | if (output->surface != NULL) { | ||
293 | return; | ||
294 | } | ||
295 | struct swaybar *bar = output->bar; | ||
296 | |||
297 | output->surface = wl_compositor_create_surface(bar->compositor); | ||
298 | assert(output->surface); | ||
299 | output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( | ||
300 | bar->layer_shell, output->surface, output->output, | ||
301 | ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); | ||
302 | assert(output->layer_surface); | ||
303 | zwlr_layer_surface_v1_add_listener(output->layer_surface, | ||
304 | &layer_surface_listener, output); | ||
305 | zwlr_layer_surface_v1_set_anchor(output->layer_surface, | ||
306 | bar->config->position); | ||
307 | } | ||
308 | |||
309 | static bool bar_uses_output(struct swaybar *bar, const char *name) { | ||
310 | if (bar->config->all_outputs) { | ||
311 | return true; | ||
312 | } | ||
313 | struct config_output *coutput; | ||
314 | wl_list_for_each(coutput, &bar->config->outputs, link) { | ||
315 | if (strcmp(coutput->name, name) == 0) { | ||
316 | return true; | ||
317 | } | ||
318 | } | ||
319 | return false; | ||
320 | } | ||
321 | |||
286 | static void output_geometry(void *data, struct wl_output *output, int32_t x, | 322 | static void output_geometry(void *data, struct wl_output *output, int32_t x, |
287 | int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, | 323 | int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, |
288 | const char *make, const char *model, int32_t transform) { | 324 | const char *make, const char *model, int32_t transform) { |
@@ -326,7 +362,22 @@ static void xdg_output_handle_logical_size(void *data, | |||
326 | 362 | ||
327 | static void xdg_output_handle_done(void *data, | 363 | static void xdg_output_handle_done(void *data, |
328 | struct zxdg_output_v1 *xdg_output) { | 364 | struct zxdg_output_v1 *xdg_output) { |
329 | // Who cares | 365 | struct swaybar_output *output = data; |
366 | struct swaybar *bar = output->bar; | ||
367 | |||
368 | assert(output->name != NULL); | ||
369 | if (!bar_uses_output(bar, output->name)) { | ||
370 | swaybar_output_free(output); | ||
371 | return; | ||
372 | } | ||
373 | |||
374 | if (wl_list_empty(&output->link)) { | ||
375 | wl_list_remove(&output->link); | ||
376 | wl_list_insert(&bar->outputs, &output->link); | ||
377 | |||
378 | add_layer_surface(output); | ||
379 | render_frame(bar, output); | ||
380 | } | ||
330 | } | 381 | } |
331 | 382 | ||
332 | static void xdg_output_handle_name(void *data, | 383 | static void xdg_output_handle_name(void *data, |
@@ -349,17 +400,15 @@ struct zxdg_output_v1_listener xdg_output_listener = { | |||
349 | .description = xdg_output_handle_description, | 400 | .description = xdg_output_handle_description, |
350 | }; | 401 | }; |
351 | 402 | ||
352 | static bool bar_uses_output(struct swaybar *bar, const char *name) { | 403 | static void add_xdg_output(struct swaybar_output *output) { |
353 | if (bar->config->all_outputs) { | 404 | if (output->xdg_output != NULL) { |
354 | return true; | 405 | return; |
355 | } | ||
356 | struct config_output *coutput; | ||
357 | wl_list_for_each(coutput, &bar->config->outputs, link) { | ||
358 | if (strcmp(coutput->name, name) == 0) { | ||
359 | return true; | ||
360 | } | ||
361 | } | 406 | } |
362 | return false; | 407 | assert(output->bar->xdg_output_manager != NULL); |
408 | output->xdg_output = zxdg_output_manager_v1_get_xdg_output( | ||
409 | output->bar->xdg_output_manager, output->output); | ||
410 | zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, | ||
411 | output); | ||
363 | } | 412 | } |
364 | 413 | ||
365 | static void handle_global(void *data, struct wl_registry *registry, | 414 | static void handle_global(void *data, struct wl_registry *registry, |
@@ -386,7 +435,10 @@ static void handle_global(void *data, struct wl_registry *registry, | |||
386 | output->wl_name = name; | 435 | output->wl_name = name; |
387 | wl_list_init(&output->workspaces); | 436 | wl_list_init(&output->workspaces); |
388 | wl_list_init(&output->hotspots); | 437 | wl_list_init(&output->hotspots); |
389 | wl_list_insert(&bar->outputs, &output->link); | 438 | wl_list_init(&output->link); |
439 | if (bar->xdg_output_manager != NULL) { | ||
440 | add_xdg_output(output); | ||
441 | } | ||
390 | } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { | 442 | } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { |
391 | bar->layer_shell = wl_registry_bind( | 443 | bar->layer_shell = wl_registry_bind( |
392 | registry, name, &zwlr_layer_shell_v1_interface, 1); | 444 | registry, name, &zwlr_layer_shell_v1_interface, 1); |
@@ -416,7 +468,9 @@ static const struct wl_registry_listener registry_listener = { | |||
416 | static void render_all_frames(struct swaybar *bar) { | 468 | static void render_all_frames(struct swaybar *bar) { |
417 | struct swaybar_output *output; | 469 | struct swaybar_output *output; |
418 | wl_list_for_each(output, &bar->outputs, link) { | 470 | wl_list_for_each(output, &bar->outputs, link) { |
419 | render_frame(bar, output); | 471 | if (output->surface != NULL) { |
472 | render_frame(bar, output); | ||
473 | } | ||
420 | } | 474 | } |
421 | } | 475 | } |
422 | 476 | ||
@@ -443,23 +497,10 @@ void bar_setup(struct swaybar *bar, | |||
443 | 497 | ||
444 | struct swaybar_output *output; | 498 | struct swaybar_output *output; |
445 | wl_list_for_each(output, &bar->outputs, link) { | 499 | wl_list_for_each(output, &bar->outputs, link) { |
446 | output->xdg_output = zxdg_output_manager_v1_get_xdg_output( | 500 | add_xdg_output(output); |
447 | bar->xdg_output_manager, output->output); | ||
448 | zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, | ||
449 | output); | ||
450 | } | 501 | } |
451 | wl_display_roundtrip(bar->display); | 502 | wl_display_roundtrip(bar->display); |
452 | 503 | ||
453 | struct swaybar_output *output_tmp; | ||
454 | wl_list_for_each_safe(output, output_tmp, &bar->outputs, link) { | ||
455 | if (!bar_uses_output(bar, output->name)) { | ||
456 | zxdg_output_v1_destroy(output->xdg_output); | ||
457 | wl_output_destroy(output->output); | ||
458 | wl_list_remove(&output->link); | ||
459 | free(output); | ||
460 | } | ||
461 | } | ||
462 | |||
463 | struct swaybar_pointer *pointer = &bar->pointer; | 504 | struct swaybar_pointer *pointer = &bar->pointer; |
464 | 505 | ||
465 | int max_scale = 1; | 506 | int max_scale = 1; |
@@ -479,18 +520,6 @@ void bar_setup(struct swaybar *bar, | |||
479 | pointer->cursor_surface = wl_compositor_create_surface(bar->compositor); | 520 | pointer->cursor_surface = wl_compositor_create_surface(bar->compositor); |
480 | assert(pointer->cursor_surface); | 521 | assert(pointer->cursor_surface); |
481 | 522 | ||
482 | wl_list_for_each(output, &bar->outputs, link) { | ||
483 | output->surface = wl_compositor_create_surface(bar->compositor); | ||
484 | assert(output->surface); | ||
485 | output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( | ||
486 | bar->layer_shell, output->surface, output->output, | ||
487 | ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); | ||
488 | assert(output->layer_surface); | ||
489 | zwlr_layer_surface_v1_add_listener(output->layer_surface, | ||
490 | &layer_surface_listener, output); | ||
491 | zwlr_layer_surface_v1_set_anchor(output->layer_surface, | ||
492 | bar->config->position); | ||
493 | } | ||
494 | ipc_get_workspaces(bar); | 523 | ipc_get_workspaces(bar); |
495 | render_all_frames(bar); | 524 | render_all_frames(bar); |
496 | } | 525 | } |
diff --git a/swaybar/render.c b/swaybar/render.c index 97690338..1f2dcc30 100644 --- a/swaybar/render.c +++ b/swaybar/render.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | 1 | #define _POSIX_C_SOURCE 200809L |
2 | #include <assert.h> | ||
2 | #include <limits.h> | 3 | #include <limits.h> |
3 | #include <stdlib.h> | 4 | #include <stdlib.h> |
4 | #include <stdint.h> | 5 | #include <stdint.h> |
@@ -480,6 +481,8 @@ static uint32_t render_to_cairo(cairo_t *cairo, | |||
480 | } | 481 | } |
481 | 482 | ||
482 | void render_frame(struct swaybar *bar, struct swaybar_output *output) { | 483 | void render_frame(struct swaybar *bar, struct swaybar_output *output) { |
484 | assert(output->surface != NULL); | ||
485 | |||
483 | struct swaybar_hotspot *hotspot, *tmp; | 486 | struct swaybar_hotspot *hotspot, *tmp; |
484 | wl_list_for_each_safe(hotspot, tmp, &output->hotspots, link) { | 487 | wl_list_for_each_safe(hotspot, tmp, &output->hotspots, link) { |
485 | if (hotspot->destroy) { | 488 | if (hotspot->destroy) { |