commit ef5a246
uint
·
2026-08-05 16:48:48 +0000 UTC
parent 37f6208
Wayland: fix independent cursor visibility, confinement and relative modes
2 files changed,
+46,
-30
+5,
-2
1@@ -26,6 +26,7 @@ struct xdg_toplevel;
2
3 struct zwp_pointer_constraints_v1;
4 struct zwp_confined_pointer_v1;
5+struct zwp_locked_pointer_v1;
6 struct zwp_relative_pointer_manager_v1;
7 struct zwp_relative_pointer_v1;
8
9@@ -79,10 +80,12 @@ typedef struct {
10 int32_t mouse_x;
11 int32_t mouse_y;
12 int8_t mouse_pos_set;
13- int8_t cursor_state;
14+ int8_t cursor_visible;
15+ int8_t cursor_confined;
16
17 struct zwp_pointer_constraints_v1* pointer_constraints;
18- struct zwp_confined_pointer_v1* locked_pointer;
19+ struct zwp_confined_pointer_v1* confined_pointer;
20+ struct zwp_locked_pointer_v1* locked_pointer;
21 struct zwp_relative_pointer_manager_v1* relative_pointer_manager;
22 struct zwp_relative_pointer_v1* relative_pointer;
23
+41,
-28
1@@ -48,8 +48,8 @@ static void registry_global(void* data, struct wl_registry* registry, uint32_t n
2
3 static int8_t cursor_init(Maus* mw);
4 static void cursor_destroy(Maus* mw);
5-static void cursor_lock(Maus* mw);
6-static void cursor_unlock(Maus* mw);
7+static void cursor_confine(Maus* mw);
8+static void cursor_unconfine(Maus* mw);
9 static void cursor_show(Maus* mw);
10 static void cursor_hide(Maus* mw);
11 static void cursor_relative(Maus* mw);
12@@ -280,10 +280,10 @@ static void pointer_enter(void* data, struct wl_pointer* pointer, uint32_t seria
13 (void)sy;
14
15 mw->backend.pointer_enter_serial = serial;
16- if (mw->backend.cursor_state == MAUS_CURSOR_STATE_HIDDEN)
17- cursor_hide(mw);
18- else
19+ if (mw->backend.cursor_visible)
20 cursor_show(mw);
21+ else
22+ cursor_hide(mw);
23 }
24
25 static void pointer_leave(void* data, struct wl_pointer* pointer, uint32_t serial,
26@@ -700,32 +700,31 @@ static void cursor_hide(Maus* mw)
27 wl_pointer_set_cursor(be->pointer, be->pointer_enter_serial, NULL, 0, 0);
28 }
29
30-static void cursor_lock(Maus* mw)
31+static void cursor_confine(Maus* mw)
32 {
33 MausBackend* be = &mw->backend;
34
35- if (be->locked_pointer)
36+ be->cursor_confined = 1;
37+ if (be->relative_pointer || be->confined_pointer)
38 return;
39 if (!be->pointer_constraints || !be->surface || !be->pointer)
40 return;
41
42- be->locked_pointer = zwp_pointer_constraints_v1_confine_pointer(
43+ be->confined_pointer = zwp_pointer_constraints_v1_confine_pointer(
44 be->pointer_constraints, be->surface, be->pointer, NULL,
45 ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT
46 );
47 }
48
49-static void cursor_unlock(Maus* mw)
50+static void cursor_unconfine(Maus* mw)
51 {
52 MausBackend* be = &mw->backend;
53
54- if (be->locked_pointer) {
55- zwp_confined_pointer_v1_destroy(be->locked_pointer);
56- be->locked_pointer = NULL;
57+ be->cursor_confined = 0;
58+ if (be->confined_pointer) {
59+ zwp_confined_pointer_v1_destroy(be->confined_pointer);
60+ be->confined_pointer = NULL;
61 }
62-
63- if (be->cursor_state == MAUS_CURSOR_STATE_VISIBLE)
64- cursor_show(mw);
65 }
66
67 static void cursor_show(Maus* mw)
68@@ -754,12 +753,22 @@ static void cursor_show(Maus* mw)
69 static void cursor_relative(Maus* mw)
70 {
71 MausBackend* be = &mw->backend;
72+
73 if (be->relative_pointer)
74 return;
75- if (!be->relative_pointer_manager || !be->pointer)
76+ if (!be->relative_pointer_manager || !be->pointer_constraints ||
77+ !be->surface || !be->pointer)
78 return;
79
80- cursor_lock(mw);
81+ if (be->confined_pointer) {
82+ zwp_confined_pointer_v1_destroy(be->confined_pointer);
83+ be->confined_pointer = NULL;
84+ }
85+
86+ be->locked_pointer = zwp_pointer_constraints_v1_lock_pointer(
87+ be->pointer_constraints, be->surface, be->pointer, NULL,
88+ ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT
89+ );
90 be->relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(
91 be->relative_pointer_manager, be->pointer
92 );
93@@ -776,8 +785,13 @@ static void cursor_absolute(Maus* mw)
94 zwp_relative_pointer_v1_destroy(be->relative_pointer);
95 be->relative_pointer = NULL;
96 }
97+ if (be->locked_pointer) {
98+ zwp_locked_pointer_v1_destroy(be->locked_pointer);
99+ be->locked_pointer = NULL;
100+ }
101
102- cursor_unlock(mw);
103+ if (be->cursor_confined)
104+ cursor_confine(mw);
105 }
106
107 static int8_t fb_create(Maus* mw);
108@@ -1034,6 +1048,7 @@ void maus_close(Maus* mw)
109
110 fb_destroy(mw);
111 cursor_absolute(mw);
112+ cursor_unconfine(mw);
113
114 if (be->xdg_toplevel)
115 xdg_toplevel_destroy(be->xdg_toplevel);
116@@ -1095,7 +1110,8 @@ int8_t maus_close_window(Maus* mw)
117 {
118 MausBackend* be = &mw->backend;
119
120- cursor_unlock(mw);
121+ cursor_absolute(mw);
122+ cursor_unconfine(mw);
123 fb_destroy(mw);
124
125 if (be->xdg_toplevel)
126@@ -1185,7 +1201,8 @@ Maus* maus_init(const char* title, int x, int y, int width, int height)
127 mw->width = width;
128 mw->height = height;
129 mw->stride = width;
130- be->cursor_state = MAUS_CURSOR_STATE_VISIBLE;
131+ be->cursor_visible = 1;
132+ be->cursor_confined = 0;
133
134 mw->bfb = calloc(mw->stride * mw->height, sizeof(uint32_t));
135 if (!mw->bfb)
136@@ -1321,28 +1338,24 @@ void maus_cur_set_mode(Maus* mw, MausCursorState state)
137 {
138 switch (state) {
139 case MAUS_CURSOR_STATE_VISIBLE:
140+ mw->backend.cursor_visible = 1;
141 cursor_show(mw);
142- mw->backend.cursor_state = state;
143 break;
144 case MAUS_CURSOR_STATE_HIDDEN:
145+ mw->backend.cursor_visible = 0;
146 cursor_hide(mw);
147- mw->backend.cursor_state = state;
148 break;
149 case MAUS_CURSOR_STATE_LOCKED:
150- mw->backend.cursor_state = state;
151- cursor_lock(mw);
152+ cursor_confine(mw);
153 break;
154 case MAUS_CURSOR_STATE_FREE:
155- cursor_unlock(mw);
156- mw->backend.cursor_state = state;
157+ cursor_unconfine(mw);
158 break;
159 case MAUS_CURSOR_STATE_RELATIVE:
160 cursor_relative(mw);
161- mw->backend.cursor_state = state;
162 break;
163 case MAUS_CURSOR_STATE_ABSOLUTE:
164 cursor_absolute(mw);
165- mw->backend.cursor_state = state;
166 break;
167 default:
168 break;