aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2023-03-23 22:12:54 +0100
committerNathan Reiner <nathan@nathanreiner.xyz>2023-03-23 22:12:54 +0100
commit22e35ad5945c55cd896b4d222494f0304f71c640 (patch)
tree24d36db29f21d7e8056e8b4ef0fca6999b17ba64
parent65dc155a9c67f3f99a2e4a097182a1855a1dcf12 (diff)
fixed output removal crash
-rw-r--r--dbar.c84
1 files 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;
}