From 141a348264de2dfff1b206ce50bab21255980faf Mon Sep 17 00:00:00 2001 From: Matt Oakes Date: Mon, 10 Feb 2025 14:16:09 +0000 Subject: [PATCH 1/3] If there is a single output map it to the cursor This change ensures that if there is a single output the transformations for that output are applied before cursor events are handled in wlroots --- output.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/output.c b/output.c index f1c0419..bdb6571 100644 --- a/output.c +++ b/output.c @@ -67,6 +67,26 @@ update_output_manager_config(struct cg_server *server) wlr_output_manager_v1_set_configuration(server->output_manager_v1, config); } +static void +update_cursor_map_to_output(struct cg_server *server) +{ + struct cg_output *only_enabled_output = NULL; + struct cg_output *output; + wl_list_for_each (output, &server->outputs, link) { + if (!only_enabled_output && output->wlr_output->enabled) { + only_enabled_output = output; + } else { + only_enabled_output = NULL; + } + } + + if (only_enabled_output) { + wlr_cursor_map_to_output(server->seat->cursor, only_enabled_output->wlr_output); + } else { + wlr_cursor_map_to_output(server->seat->cursor, NULL); + } +} + static inline void output_layout_add_auto(struct cg_output *output) { @@ -112,6 +132,7 @@ output_enable(struct cg_output *output) output_layout_add_auto(output); } + update_cursor_map_to_output(output->server); update_output_manager_config(output->server); } @@ -183,6 +204,7 @@ handle_output_commit(struct wl_listener *listener, void *data) * - always update output manager configuration even if the output is now disabled */ if (event->state->committed & OUTPUT_CONFIG_UPDATED) { + update_cursor_map_to_output(output->server); update_output_manager_config(output->server); } } @@ -194,6 +216,7 @@ handle_output_request_state(struct wl_listener *listener, void *data) struct wlr_output_event_request_state *event = data; if (wlr_output_commit_state(output->wlr_output, event->state)) { + update_cursor_map_to_output(output->server); update_output_manager_config(output->server); } } @@ -204,6 +227,7 @@ handle_output_layout_change(struct wl_listener *listener, void *data) struct cg_server *server = wl_container_of(listener, server, output_layout_change); view_position_all(server); + update_cursor_map_to_output(server); update_output_manager_config(server); } @@ -331,6 +355,7 @@ handle_new_output(struct wl_listener *listener, void *data) } view_position_all(output->server); + update_cursor_map_to_output(output->server); update_output_manager_config(output->server); } From e21c155bcdc3f6bc8a3acc7c1dc362bcda3f734c Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 10 Apr 2025 18:08:15 +0200 Subject: [PATCH 2/3] seat: destroy keyboard groups on shutdown These are not destroyed automatically because they are entirely managed by the compositor. --- seat.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/seat.c b/seat.c index cdf8798..9acbdd3 100644 --- a/seat.c +++ b/seat.c @@ -380,6 +380,16 @@ cleanup: free(cg_group); } +static void +keyboard_group_destroy(struct cg_keyboard_group *keyboard_group) +{ + wl_list_remove(&keyboard_group->key.link); + wl_list_remove(&keyboard_group->modifiers.link); + wlr_keyboard_group_destroy(keyboard_group->wlr_group); + wl_list_remove(&keyboard_group->link); + free(keyboard_group); +} + static void handle_new_keyboard(struct cg_seat *seat, struct wlr_keyboard *keyboard, bool virtual) { @@ -893,6 +903,11 @@ seat_destroy(struct cg_seat *seat) wl_list_remove(&seat->request_start_drag.link); wl_list_remove(&seat->start_drag.link); + struct cg_keyboard_group *keyboard_group, *keyboard_group_tmp; + wl_list_for_each_safe (keyboard_group, keyboard_group_tmp, &seat->keyboard_groups, link) { + keyboard_group_destroy(keyboard_group); + } + // Destroying the wlr seat will trigger the destroy handler on our seat, // which will in turn free it. wlr_seat_destroy(seat->seat); From 6efb3b50421d9adc8d1220ccae63af45d423f5cf Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 10 Apr 2025 18:09:01 +0200 Subject: [PATCH 3/3] cage: remove global server listeners on shutdown --- cage.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cage.c b/cage.c index 8f14746..40a675d 100644 --- a/cage.c +++ b/cage.c @@ -596,11 +596,25 @@ main(int argc, char *argv[]) wl_display_run(server.wl_display); #if CAGE_HAS_XWAYLAND + if (xwayland) { + wl_list_remove(&server.new_xwayland_surface.link); + } wlr_xwayland_destroy(xwayland); wlr_xcursor_manager_destroy(xcursor_manager); #endif wl_display_destroy_clients(server.wl_display); + wl_list_remove(&server.new_virtual_pointer.link); + wl_list_remove(&server.new_virtual_keyboard.link); + wl_list_remove(&server.output_manager_apply.link); + wl_list_remove(&server.output_manager_test.link); + wl_list_remove(&server.xdg_toplevel_decoration.link); + wl_list_remove(&server.new_xdg_toplevel.link); + wl_list_remove(&server.new_xdg_popup.link); + wl_list_remove(&server.new_idle_inhibitor_v1.link); + wl_list_remove(&server.new_output.link); + wl_list_remove(&server.output_layout_change.link); + end: if (pid != 0) app_ret = cleanup_primary_client(pid);