Create a single wlr_xcursor_manager
Some checks failed
Continuous integration build / compile (clang, alpine:edge, disabled) (push) Has been cancelled
Continuous integration build / compile (clang, alpine:edge, enabled) (push) Has been cancelled
Continuous integration build / compile (clang, archlinux:base-devel, disabled) (push) Has been cancelled
Continuous integration build / compile (clang, archlinux:base-devel, enabled) (push) Has been cancelled
Continuous integration build / compile (gcc, alpine:edge, disabled) (push) Has been cancelled
Continuous integration build / compile (gcc, archlinux:base-devel, enabled) (push) Has been cancelled
Continuous integration build / scan-build (push) Has been cancelled
Continuous integration build / compile (gcc, alpine:edge, enabled) (push) Has been cancelled
Continuous integration build / compile (gcc, archlinux:base-devel, disabled) (push) Has been cancelled
Continuous integration build / format (push) Has been cancelled

No need to create multiple of these: all use the same parameters.
This commit is contained in:
Simon Ser 2026-05-13 23:08:42 +02:00
parent 6d6ecd44d7
commit 1f9f0d2581
4 changed files with 33 additions and 43 deletions

43
cage.c
View file

@ -42,9 +42,7 @@
#include <wlr/types/wlr_viewporter.h> #include <wlr/types/wlr_viewporter.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h> #include <wlr/types/wlr_virtual_keyboard_v1.h>
#include <wlr/types/wlr_virtual_pointer_v1.h> #include <wlr/types/wlr_virtual_pointer_v1.h>
#if CAGE_HAS_XWAYLAND
#include <wlr/types/wlr_xcursor_manager.h> #include <wlr/types/wlr_xcursor_manager.h>
#endif
#include <wlr/types/wlr_xdg_decoration_v1.h> #include <wlr/types/wlr_xdg_decoration_v1.h>
#include <wlr/types/wlr_xdg_output_v1.h> #include <wlr/types/wlr_xdg_output_v1.h>
#include <wlr/types/wlr_xdg_shell.h> #include <wlr/types/wlr_xdg_shell.h>
@ -132,6 +130,26 @@ set_cloexec(int fd)
return true; 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 static bool
spawn_primary_client(struct cg_server *server, char *argv[], pid_t *pid_out, struct wl_event_source **sigchld_source) 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; server.new_output.notify = handle_new_output;
wl_signal_add(&server.backend->events.new_output, &server.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); server.seat = seat_create(&server, server.backend);
if (!server.seat) { if (!server.seat) {
wlr_log(WLR_ERROR, "Unable to create the seat"); wlr_log(WLR_ERROR, "Unable to create the seat");
@ -567,7 +592,6 @@ main(int argc, char *argv[])
} }
#if CAGE_HAS_XWAYLAND #if CAGE_HAS_XWAYLAND
struct wlr_xcursor_manager *xcursor_manager = NULL;
struct wlr_xwayland *xwayland = NULL; struct wlr_xwayland *xwayland = NULL;
if (server.enable_xwayland) { if (server.enable_xwayland) {
xwayland = wlr_xwayland_create(server.wl_display, compositor, true); 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; server.new_xwayland_surface.notify = handle_xwayland_surface_new;
wl_signal_add(&xwayland->events.new_surface, &server.new_xwayland_surface); 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) { if (setenv("DISPLAY", xwayland->display_name, true) < 0) {
wlr_log_errno(WLR_ERROR, wlr_log_errno(WLR_ERROR,
"Unable to set DISPLAY for XWayland. Clients may not be able to connect"); "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); 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"); wlr_log(WLR_ERROR, "Cannot load XWayland XCursor theme");
} }
struct wlr_xcursor *xcursor = 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) { if (xcursor) {
struct wlr_xcursor_image *image = xcursor->images[0]; struct wlr_xcursor_image *image = xcursor->images[0];
wlr_xwayland_set_cursor(xwayland, wlr_xcursor_image_get_buffer(image), image->hotspot_x, 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); wl_list_remove(&server.new_xwayland_surface.link);
} }
wlr_xwayland_destroy(xwayland); wlr_xwayland_destroy(xwayland);
wlr_xcursor_manager_destroy(xcursor_manager);
#endif #endif
wl_display_destroy_clients(server.wl_display); wl_display_destroy_clients(server.wl_display);
@ -678,6 +694,7 @@ end:
/* This function is not null-safe, but we only ever get here /* This function is not null-safe, but we only ever get here
with a proper wl_display. */ with a proper wl_display. */
wl_display_destroy(server.wl_display); wl_display_destroy(server.wl_display);
wlr_xcursor_manager_destroy(server.xcursor_manager);
if (server.scene != NULL) { if (server.scene != NULL) {
wlr_scene_node_destroy(&server.scene->tree.node); wlr_scene_node_destroy(&server.scene->tree.node);
} }

29
seat.c
View file

@ -29,7 +29,6 @@
#include <wlr/types/wlr_touch.h> #include <wlr/types/wlr_touch.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h> #include <wlr/types/wlr_virtual_keyboard_v1.h>
#include <wlr/types/wlr_virtual_pointer_v1.h> #include <wlr/types/wlr_virtual_pointer_v1.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#if CAGE_HAS_XWAYLAND #if CAGE_HAS_XWAYLAND
#include <wlr/xwayland.h> #include <wlr/xwayland.h>
@ -130,7 +129,7 @@ update_capabilities(struct cg_seat *seat)
if ((caps & WL_SEAT_CAPABILITY_POINTER) == 0) { if ((caps & WL_SEAT_CAPABILITY_POINTER) == 0) {
wlr_cursor_unset_image(seat->cursor); wlr_cursor_unset_image(seat->cursor);
} else { } 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); wl_list_remove(&seat->new_input.link);
wlr_xcursor_manager_destroy(seat->xcursor_manager);
if (seat->cursor) { if (seat->cursor) {
wlr_cursor_destroy(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); 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; seat->cursor_motion_relative.notify = handle_cursor_motion_relative;
wl_signal_add(&seat->cursor->events.motion, &seat->cursor_motion_relative); wl_signal_add(&seat->cursor->events.motion, &seat->cursor_motion_relative);
seat->cursor_motion_absolute.notify = handle_cursor_motion_absolute; seat->cursor_motion_absolute.notify = handle_cursor_motion_absolute;

2
seat.h
View file

@ -6,7 +6,6 @@
#include <wlr/types/wlr_data_device.h> #include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_input_device.h> #include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_seat.h> #include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include "server.h" #include "server.h"
#include "view.h" #include "view.h"
@ -26,7 +25,6 @@ struct cg_seat {
struct wl_listener new_input; struct wl_listener new_input;
struct wlr_cursor *cursor; struct wlr_cursor *cursor;
struct wlr_xcursor_manager *xcursor_manager;
struct wl_listener cursor_motion_relative; struct wl_listener cursor_motion_relative;
struct wl_listener cursor_motion_absolute; struct wl_listener cursor_motion_absolute;
struct wl_listener cursor_button; struct wl_listener cursor_button;

View file

@ -70,6 +70,8 @@ struct cg_server {
struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager; struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
struct wlr_xcursor_manager *xcursor_manager;
bool xdg_decoration; bool xdg_decoration;
bool allow_vt_switch; bool allow_vt_switch;
bool enable_xwayland; bool enable_xwayland;