From 22e35ad5945c55cd896b4d222494f0304f71c640 Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Thu, 23 Mar 2023 22:12:54 +0100 Subject: fixed output removal crash --- dbar.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 16 deletions(-) diff --git a/dbar.c b/dbar.c index ddbc42d..ac7b33e 100644 --- a/dbar.c +++ b/dbar.c @@ -28,6 +28,7 @@ struct Bar { uint32_t layout; char progname[256]; uint32_t update_count; + uint32_t registry_name; Canvas *canvas; struct zdwl_output_v1 *dwl_output; struct wl_output *wl_output; @@ -39,7 +40,9 @@ struct Bar { /* function declarations */ static void update_bar(Bar *bar); static void wl_buffer_release(void *data, struct wl_buffer *wl_buffer); +static void remove_bar(Bar *bar); static void registry_global(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface, uint32_t version); +static void remove_global(void *data, struct wl_registry *wl_registry, uint32_t name); static void layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t w, uint32_t h); static void layer_surface_closed(void *data, struct zwlr_layer_surface_v1 *surface); static void dwl_manager_tag(void *data, struct zdwl_manager_v1 *zdwl_manager_v1, const char *name); @@ -50,6 +53,7 @@ static void dwl_output_title(void *data, struct zdwl_output_v1 *zdwl_output_v1, static void dwl_output_layout(void *data, struct zdwl_output_v1 *zdwl_output_v1, uint32_t layout); static void dummy(); static void wayland_flush(); +static void register_bar(Bar *bar); static void setup(); struct wl_buffer *draw_frame(Bar *bar); static Bar *add_bar(); @@ -62,7 +66,7 @@ static const struct wl_buffer_listener wl_buffer_listener = { static const struct wl_registry_listener wl_registry_listener = { .global = registry_global, - .global_remove = dummy, + .global_remove = remove_global, }; static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { @@ -90,6 +94,7 @@ static char statusline[1024] = ""; struct client_state bar_state = { 0 }; struct pollfd pollfds[2]; int displayfd; +int ready = 0; /* configuration */ #include "config.h" @@ -200,6 +205,32 @@ registry_global(void *data, struct wl_registry *wl_registry, uint32_t name, cons } else if (strcmp(interface, wl_output_interface.name) == 0) { bar = add_bar(); bar->wl_output = wl_registry_bind(wl_registry, name, &wl_output_interface, 1); + + if (ready) { + register_bar(bar); + } + } +} + + +void +remove_global(void *data, struct wl_registry *wl_registry, uint32_t name) +{ + Bar *bar = bars; + Bar *prev = 0; + for (; bar; bar = bar->next) { + if (bar->registry_name == name) { + if (prev) { + prev->next = bar->next; + } else { + bars = bar->next; + } + + remove_bar(bar); + break; + } + + prev = bar; } } @@ -374,13 +405,45 @@ add_bar() void -setup() +remove_bar(Bar *bar) +{ + wl_surface_destroy(bar->wl_surface); + zwlr_layer_surface_v1_destroy(bar->zwlr_surface); + wl_output_destroy(bar->wl_output); + zdwl_output_v1_destroy(bar->dwl_output); + free_drw(bar->canvas); + free(bar); +} + + +void +register_bar(Bar *bar) { - Bar *bar; char *namespace = "dbar"; uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP; uint32_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; + bar->dwl_output = zdwl_manager_v1_get_output(bar_state.dwl_manager, bar->wl_output); + zdwl_output_v1_add_listener(bar->dwl_output, &dwl_output_listener, bar); + + bar->wl_surface = wl_compositor_create_surface(bar_state.wl_compositor); + bar->zwlr_surface = zwlr_layer_shell_v1_get_layer_surface(bar_state.zwlr_layer, bar->wl_surface, bar->wl_output, layer, namespace); + + zwlr_layer_surface_v1_add_listener(bar->zwlr_surface, &layer_surface_listener, bar); + + zwlr_layer_surface_v1_set_size(bar->zwlr_surface, bar->width, height); + zwlr_layer_surface_v1_set_anchor(bar->zwlr_surface, anchor); + + wl_surface_commit(bar->wl_surface); + wl_display_roundtrip(bar_state.wl_display); +} + + +void +setup() +{ + Bar *bar; + bar_state.wl_display = wl_display_connect(NULL); bar_state.wl_registry = wl_display_get_registry(bar_state.wl_display); wl_registry_add_listener(bar_state.wl_registry, &wl_registry_listener, &bar_state); @@ -390,21 +453,10 @@ setup() wl_display_roundtrip(bar_state.wl_display); for (bar = bars; bar; bar = bar->next) { - bar->dwl_output = zdwl_manager_v1_get_output(bar_state.dwl_manager, bar->wl_output); - zdwl_output_v1_add_listener(bar->dwl_output, &dwl_output_listener, bar); - - bar->wl_surface = wl_compositor_create_surface(bar_state.wl_compositor); - bar->zwlr_surface = zwlr_layer_shell_v1_get_layer_surface(bar_state.zwlr_layer, bar->wl_surface, bar->wl_output, layer, namespace); - - zwlr_layer_surface_v1_add_listener(bar->zwlr_surface, &layer_surface_listener, bar); - - zwlr_layer_surface_v1_set_size(bar->zwlr_surface, bar->width, height); - zwlr_layer_surface_v1_set_anchor(bar->zwlr_surface, anchor); - - wl_surface_commit(bar->wl_surface); - wl_display_roundtrip(bar_state.wl_display); + register_bar(bar); } + ready = 1; } -- cgit v1.2.3-70-g09d2