From f60adfd1b6a5e908e39944e056ebf23bf1f5ed3f Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 13 May 2026 23:08:42 +0200 Subject: [PATCH] Create a single wlr_xcursor_manager No need to create multiple of these: all use the same parameters. --- cage.c | 43 ++++++++++++++++++++++++++++++------------- seat.c | 29 +---------------------------- seat.h | 2 -- server.h | 2 ++ 4 files changed, 33 insertions(+), 43 deletions(-) diff --git a/cage.c b/cage.c index 252e9c2..60e78a0 100644 --- a/cage.c +++ b/cage.c @@ -42,9 +42,7 @@ #include #include #include -#if CAGE_HAS_XWAYLAND #include -#endif #include #include #include @@ -132,6 +130,26 @@ set_cloexec(int fd) return true; } +static struct wlr_xcursor_manager * +create_xcursor_manager(void) +{ + const char *theme = getenv("XCURSOR_THEME"); + const char *size_str = getenv("XCURSOR_SIZE"); + + int32_t size = XCURSOR_SIZE; + if (size_str) { + char *end_ptr = NULL; + unsigned long value = strtoul(size_str, &end_ptr, 10); + if (end_ptr != size_str && *end_ptr == '\0') { + size = (int32_t) value; + } else { + wlr_log(WLR_ERROR, "Invalid value for XCURSOR_SIZE: '%s'", size_str); + } + } + + return wlr_xcursor_manager_create(theme, size); +} + static bool spawn_primary_client(struct cg_server *server, char *argv[], pid_t *pid_out, struct wl_event_source **sigchld_source) { @@ -414,6 +432,13 @@ main(int argc, char *argv[]) server.new_output.notify = handle_new_output; wl_signal_add(&server.backend->events.new_output, &server.new_output); + server.xcursor_manager = create_xcursor_manager(); + if (!server.xcursor_manager) { + wlr_log(WLR_ERROR, "Unable to create XCursor manager"); + ret = 1; + goto end; + } + server.seat = seat_create(&server, server.backend); if (!server.seat) { wlr_log(WLR_ERROR, "Unable to create the seat"); @@ -567,7 +592,6 @@ main(int argc, char *argv[]) } #if CAGE_HAS_XWAYLAND - struct wlr_xcursor_manager *xcursor_manager = NULL; struct wlr_xwayland *xwayland = NULL; if (server.enable_xwayland) { xwayland = wlr_xwayland_create(server.wl_display, compositor, true); @@ -577,13 +601,6 @@ main(int argc, char *argv[]) server.new_xwayland_surface.notify = handle_xwayland_surface_new; wl_signal_add(&xwayland->events.new_surface, &server.new_xwayland_surface); - xcursor_manager = wlr_xcursor_manager_create(NULL, XCURSOR_SIZE); - if (!xcursor_manager) { - wlr_log(WLR_ERROR, "Cannot create XWayland XCursor manager"); - ret = 1; - goto end; - } - if (setenv("DISPLAY", xwayland->display_name, true) < 0) { wlr_log_errno(WLR_ERROR, "Unable to set DISPLAY for XWayland. Clients may not be able to connect"); @@ -591,11 +608,11 @@ main(int argc, char *argv[]) wlr_log(WLR_DEBUG, "XWayland is running on display %s", xwayland->display_name); } - if (!wlr_xcursor_manager_load(xcursor_manager, 1)) { + if (!wlr_xcursor_manager_load(server.xcursor_manager, 1)) { wlr_log(WLR_ERROR, "Cannot load XWayland XCursor theme"); } struct wlr_xcursor *xcursor = - wlr_xcursor_manager_get_xcursor(xcursor_manager, DEFAULT_XCURSOR, 1); + wlr_xcursor_manager_get_xcursor(server.xcursor_manager, DEFAULT_XCURSOR, 1); if (xcursor) { struct wlr_xcursor_image *image = xcursor->images[0]; wlr_xwayland_set_cursor(xwayland, wlr_xcursor_image_get_buffer(image), image->hotspot_x, @@ -643,7 +660,6 @@ main(int argc, char *argv[]) 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); @@ -678,6 +694,7 @@ end: /* This function is not null-safe, but we only ever get here with a proper wl_display. */ wl_display_destroy(server.wl_display); + wlr_xcursor_manager_destroy(server.xcursor_manager); if (server.scene != NULL) { wlr_scene_node_destroy(&server.scene->tree.node); } diff --git a/seat.c b/seat.c index 65f261d..e2cf441 100644 --- a/seat.c +++ b/seat.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #if CAGE_HAS_XWAYLAND #include @@ -130,7 +129,7 @@ update_capabilities(struct cg_seat *seat) if ((caps & WL_SEAT_CAPABILITY_POINTER) == 0) { wlr_cursor_unset_image(seat->cursor); } else { - wlr_cursor_set_xcursor(seat->cursor, seat->xcursor_manager, DEFAULT_XCURSOR); + wlr_cursor_set_xcursor(seat->cursor, seat->server->xcursor_manager, DEFAULT_XCURSOR); } } @@ -800,7 +799,6 @@ handle_destroy(struct wl_listener *listener, void *data) } wl_list_remove(&seat->new_input.link); - wlr_xcursor_manager_destroy(seat->xcursor_manager); if (seat->cursor) { wlr_cursor_destroy(seat->cursor); } @@ -835,31 +833,6 @@ seat_create(struct cg_server *server, struct wlr_backend *backend) } wlr_cursor_attach_output_layout(seat->cursor, server->output_layout); - if (!seat->xcursor_manager) { - const char *theme = getenv("XCURSOR_THEME"); - const char *size_str = getenv("XCURSOR_SIZE"); - - int32_t size = XCURSOR_SIZE; - if (size_str) { - char *end_ptr = NULL; - unsigned long value = strtoul(size_str, &end_ptr, 10); - if (end_ptr != size_str && *end_ptr == '\0') { - size = (int32_t) value; - } else { - wlr_log(WLR_ERROR, "Invalid value for XCURSOR_SIZE: '%s'", size_str); - } - } - - seat->xcursor_manager = wlr_xcursor_manager_create(theme, size); - if (!seat->xcursor_manager) { - wlr_log(WLR_ERROR, "Cannot create XCursor manager"); - wlr_cursor_destroy(seat->cursor); - wl_list_remove(&seat->destroy.link); - free(seat); - return NULL; - } - } - seat->cursor_motion_relative.notify = handle_cursor_motion_relative; wl_signal_add(&seat->cursor->events.motion, &seat->cursor_motion_relative); seat->cursor_motion_absolute.notify = handle_cursor_motion_absolute; diff --git a/seat.h b/seat.h index 4b7bfda..d86f272 100644 --- a/seat.h +++ b/seat.h @@ -6,7 +6,6 @@ #include #include #include -#include #include "server.h" #include "view.h" @@ -26,7 +25,6 @@ struct cg_seat { struct wl_listener new_input; struct wlr_cursor *cursor; - struct wlr_xcursor_manager *xcursor_manager; struct wl_listener cursor_motion_relative; struct wl_listener cursor_motion_absolute; struct wl_listener cursor_button; diff --git a/server.h b/server.h index a5b7138..6755c22 100644 --- a/server.h +++ b/server.h @@ -70,6 +70,8 @@ struct cg_server { struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager; + struct wlr_xcursor_manager *xcursor_manager; + bool xdg_decoration; bool allow_vt_switch; bool enable_xwayland;