summaryrefslogtreecommitdiff
path: root/wlock.c
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2023-03-23 22:03:46 +0100
committerNathan Reiner <nathan@nathanreiner.xyz>2023-03-23 22:03:46 +0100
commit500dbf33fa9baec979abda070a64daa6d2605072 (patch)
tree21c0b1b0eb395d8ba9054a919c653cd162d97f72 /wlock.c
parent92889ffc654ab0fa69efcce6eec14138c7b6e6ad (diff)
handle output removal to fix crash
Diffstat (limited to 'wlock.c')
-rw-r--r--wlock.c86
1 files changed, 69 insertions, 17 deletions
diff --git a/wlock.c b/wlock.c
index c657731..8fb695a 100644
--- a/wlock.c
+++ b/wlock.c
@@ -61,8 +61,8 @@ typedef struct Monitor Monitor;
struct Monitor {
uint32_t width;
uint32_t height;
+ uint32_t registry_name;
Canvas *canvas;
- struct zdwl_output_v1 *dwl_output;
struct wl_output *output;
struct wl_surface *surface;
struct zwlr_layer_surface_v1 *wlr_surface;
@@ -74,19 +74,22 @@ static void draw_to_monitor(Monitor *mon);
static void update_time();
static void setup();
static Monitor *add_monitor();
+static void remove_monitor(Monitor *mon);
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 seat_capabilities(void *data, struct wl_seat *seat, uint32_t capabilities);
static void wlr_layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t w, uint32_t h);
static void keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size);
static void keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state);
static void keyboard_repeat_info(void *data, struct wl_keyboard *keyboard, int32_t rate, int32_t delay);
static void handle_keyboard_event();
+static void register_monitor(Monitor *mon);
static void dummy() {}
/* global variables */
static const struct wl_registry_listener registry_listnener = {
.global = registry_global,
- .global_remove = dummy
+ .global_remove = remove_global
};
static const struct zwlr_layer_surface_v1_listener wlr_layer_surface_listener = {
@@ -117,6 +120,7 @@ const char *username;
char timestr[64];
Font *username_font;
Font *clock_font;
+int ready = 0;
/* function implementations */
void
@@ -174,6 +178,19 @@ add_monitor()
return mon;
}
+
+void
+remove_monitor(Monitor *mon)
+{
+ fprintf(stderr, "remove monitor\n");
+ wl_surface_destroy(mon->surface);
+ zwlr_layer_surface_v1_destroy(mon->wlr_surface);
+ wl_output_destroy(mon->output);
+ free_drw(mon->canvas);
+ free(mon);
+}
+
+
void
registry_global(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface, uint32_t version)
{
@@ -188,11 +205,37 @@ registry_global(void *data, struct wl_registry *wl_registry, uint32_t name, cons
or_match match_then_bind(output, wl_output_interface, 1)
monitor = add_monitor();
monitor->output = output;
+ monitor->registry_name = name;
+ if (ready) {
+ register_monitor(monitor);
+ }
end_match
}
void
+remove_global(void *data, struct wl_registry *wl_registry, uint32_t name)
+{
+ Monitor *mon = monitors;
+ Monitor *prev = 0;
+ for (; mon; mon = mon->next) {
+ if (mon->registry_name == name) {
+ if (prev) {
+ prev->next = mon->next;
+ } else {
+ monitors = mon->next;
+ }
+
+ remove_monitor(mon);
+ break;
+ }
+
+ prev = mon;
+ }
+}
+
+
+void
seat_capabilities(void *data, struct wl_seat *seat, uint32_t capabilities)
{
int has_keyboard = capabilities & WL_SEAT_CAPABILITY_KEYBOARD;
@@ -331,10 +374,10 @@ handle_keyboard_event()
}
}
+
void
-setup()
+register_monitor(Monitor *mon)
{
- Monitor *mon;
char namespace[] = "dmenu-wl";
uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP;
uint32_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
@@ -342,6 +385,25 @@ setup()
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
+ mon->surface = wl_compositor_create_surface(client.compositor);
+ mon->wlr_surface = zwlr_layer_shell_v1_get_layer_surface(client.layer, mon->surface, mon->output, layer, namespace);
+
+ zwlr_layer_surface_v1_set_exclusive_zone(mon->wlr_surface, -1);
+ zwlr_layer_surface_v1_set_keyboard_interactivity(monitors->wlr_surface, 1);
+
+ zwlr_layer_surface_v1_add_listener(mon->wlr_surface, &wlr_layer_surface_listener, mon);
+
+ zwlr_layer_surface_v1_set_anchor(mon->wlr_surface, anchor);
+
+ wl_surface_commit(mon->surface);
+ wl_display_roundtrip(client.display);
+}
+
+
+void
+setup()
+{
+ Monitor *mon;
username_font = create_font(fontpath, username_fontsize * 1.5);
clock_font = create_font(fontpath, clock_fontsize * 1.5);
client.repeat.timer = timerfd_create(CLOCK_MONOTONIC, 0);
@@ -352,20 +414,10 @@ setup()
wl_display_roundtrip(client.display);
for (mon = monitors; mon; mon = mon->next) {
-
- mon->surface = wl_compositor_create_surface(client.compositor);
- mon->wlr_surface = zwlr_layer_shell_v1_get_layer_surface(client.layer, mon->surface, mon->output, layer, namespace);
-
- zwlr_layer_surface_v1_set_exclusive_zone(mon->wlr_surface, -1);
- zwlr_layer_surface_v1_set_keyboard_interactivity(monitors->wlr_surface, 1);
-
- zwlr_layer_surface_v1_add_listener(mon->wlr_surface, &wlr_layer_surface_listener, mon);
-
- zwlr_layer_surface_v1_set_anchor(mon->wlr_surface, anchor);
-
- wl_surface_commit(mon->surface);
- wl_display_roundtrip(client.display);
+ register_monitor(mon);
}
+
+ ready = 1;
}