diff options
author | 2018-09-21 15:36:08 -0400 | |
---|---|---|
committer | 2018-09-21 15:36:08 -0400 | |
commit | d2a0a3cc0a29b3c3145bfedeb00ec68c1b8c5057 (patch) | |
tree | 56f257c17c0d97666c498d2eb35012838c82b451 /swaybar/bar.c | |
parent | Merge pull request #2672 from ianyfan/swaybar (diff) | |
parent | Merge branch 'master' into swaybar-hotplug (diff) | |
download | sway-d2a0a3cc0a29b3c3145bfedeb00ec68c1b8c5057.tar.gz sway-d2a0a3cc0a29b3c3145bfedeb00ec68c1b8c5057.tar.zst sway-d2a0a3cc0a29b3c3145bfedeb00ec68c1b8c5057.zip |
Merge pull request #2666 from emersion/swaybar-hotplug
swaybar: handle hotplugging
Diffstat (limited to 'swaybar/bar.c')
-rw-r--r-- | swaybar/bar.c | 112 |
1 files changed, 71 insertions, 41 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c index 3ae730f7..69069f40 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 | } |
@@ -529,6 +558,7 @@ void bar_run(struct swaybar *bar) { | |||
529 | } | 558 | } |
530 | while (1) { | 559 | while (1) { |
531 | event_loop_poll(); | 560 | event_loop_poll(); |
561 | wl_display_flush(bar->display); | ||
532 | } | 562 | } |
533 | } | 563 | } |
534 | 564 | ||