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;