commit bc58c52
uint
·
2026-08-04 01:34:25 +0000 UTC
parent 4206e56
Wayland: zwp_pointer_constraints_v1: locking, unlocking pointer
4 files changed,
+66,
-5
M
Makefile
+10,
-1
1@@ -41,7 +41,7 @@ build/maus_x11.o: source/maus_x11.c include/maus.h include/maus_x11.h config.mk
2 ${CC} ${CFLAGS} ${CPPFLAGS} -c source/maus_x11.c -o $@
3
4 # Wayland
5-build/maus_wayland.o: source/maus_wayland.c include/maus.h include/maus_wayland.h build/xdg-shell-client-protocol.h config.mk
6+build/maus_wayland.o: source/maus_wayland.c include/maus.h include/maus_wayland.h build/xdg-shell-client-protocol.h build/pointer-constraints-unstable-v1-client-protocol.h config.mk
7 mkdir -p build
8 ${CC} ${WL_CFLAGS} ${CPPFLAGS} -c source/maus_wayland.c -o $@
9 build/xdg-shell-client-protocol.h:
10@@ -53,6 +53,15 @@ build/xdg-shell-protocol.c:
11 build/xdg-shell-protocol.o: build/xdg-shell-protocol.c build/xdg-shell-client-protocol.h
12 mkdir -p build
13 ${CC} ${WL_CFLAGS} ${CPPFLAGS} -c build/xdg-shell-protocol.c -o $@
14+build/pointer-constraints-unstable-v1-client-protocol.h:
15+ mkdir -p build
16+ wayland-scanner client-header ${PROTOS}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml $@
17+build/pointer-constraints-unstable-v1-protocol.c:
18+ mkdir -p build
19+ wayland-scanner private-code ${PROTOS}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml $@
20+build/pointer-constraints-unstable-v1-protocol.o: build/pointer-constraints-unstable-v1-protocol.c build/pointer-constraints-unstable-v1-client-protocol.h
21+ mkdir -p build
22+ ${CC} ${WL_CFLAGS} ${CPPFLAGS} -c build/pointer-constraints-unstable-v1-protocol.c -o $@
23
24 clean:
25 rm -rf build ${LIB_NAME} config.mk compile_flags.txt
+2,
-2
1@@ -32,8 +32,8 @@ case "$backend" in
2 wayland)
3 echo "CONF_CPPFLAGS = -DBACKEND_WAY $(pkg-config --cflags wayland-client wayland-cursor xkbcommon)" >> config.mk
4 echo "CONF_LDFLAGS = $(pkg-config --libs wayland-client wayland-cursor xkbcommon)" >> config.mk
5- echo "CONF_SRC = source/maus_wayland.c build/xdg-shell-protocol.c" >> config.mk
6- echo "CONF_OBJS = build/maus_wayland.o build/xdg-shell-protocol.o" >> config.mk
7+ echo "CONF_SRC = source/maus_wayland.c build/xdg-shell-protocol.c build/pointer-constraints-unstable-v1-protocol.c" >> config.mk
8+ echo "CONF_OBJS = build/maus_wayland.o build/xdg-shell-protocol.o build/pointer-constraints-unstable-v1-protocol.o" >> config.mk
9 echo "CONF_LIB_NAME = libmaus_wayland.a" >> config.mk
10 echo "PROTOS = $(pkg-config --variable=pkgdatadir wayland-protocols)" >> config.mk
11 ;;
+7,
-0
1@@ -22,6 +22,9 @@ struct xdg_wm_base;
2 struct xdg_surface;
3 struct xdg_toplevel;
4
5+struct zwp_pointer_constraints_v1;
6+struct zwp_confined_pointer_v1;
7+
8 struct xkb_context;
9 struct xkb_keymap;
10 struct xkb_state;
11@@ -64,6 +67,9 @@ typedef struct {
12 uint32_t pointer_enter_serial;
13 int8_t cursor_state;
14
15+ struct zwp_pointer_constraints_v1* pointer_constraints;
16+ struct zwp_confined_pointer_v1* locked_pointer;
17+
18 struct xkb_context* xkb_context;
19 struct xkb_keymap* xkb_keymap;
20 struct xkb_state* xkb_state;
21@@ -80,3 +86,4 @@ typedef struct {
22 } MausBackend;
23
24 #endif /* MAUS_WAYLAND_H */
25+
+47,
-2
1@@ -10,6 +10,7 @@
2 #include <wayland-client.h>
3 #include <wayland-cursor.h>
4 #include <xdg-shell-client-protocol.h>
5+#include <pointer-constraints-unstable-v1-client-protocol.h>
6 #include <xkbcommon/xkbcommon.h>
7
8 #include "maus.h"
9@@ -46,6 +47,8 @@ static void registry_global(void* data, struct wl_registry* registry, uint32_t n
10 static void cursor_destroy(Maus* mw);
11 static void cursor_hide(Maus* mw);
12 static int8_t cursor_init(Maus* mw);
13+static void cursor_lock(Maus* mw);
14+static void cursor_unlock(Maus* mw);
15 static void cursor_show(Maus* mw);
16 static MausKey keysym_to_mauskey(xkb_keysym_t sym);
17 static MausMouseButton wl_button_to_maus(uint32_t button);
18@@ -157,6 +160,10 @@ static void registry_global(void* data, struct wl_registry* registry,
19 be->seat = wl_registry_bind(registry, name, &wl_seat_interface, 5);
20 wl_seat_add_listener(be->seat, &seat_listener, mw);
21 }
22+ else if (strcmp(interface, zwp_pointer_constraints_v1_interface.name) == 0)
23+ be->pointer_constraints = wl_registry_bind(
24+ registry, name, &zwp_pointer_constraints_v1_interface, 1
25+ );
26 }
27
28 static void seat_capabilities(void* data, struct wl_seat* seat, uint32_t capabilities)
29@@ -489,6 +496,34 @@ static void cursor_hide(Maus* mw)
30 wl_pointer_set_cursor(be->pointer, be->pointer_enter_serial, NULL, 0, 0);
31 }
32
33+static void cursor_lock(Maus* mw)
34+{
35+ MausBackend* be = &mw->backend;
36+
37+ if (be->locked_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->pointer_constraints, be->surface, be->pointer, NULL,
44+ ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT
45+ );
46+}
47+
48+static void cursor_unlock(Maus* mw)
49+{
50+ MausBackend* be = &mw->backend;
51+
52+ if (be->locked_pointer) {
53+ zwp_pointer_constraints_v1_lock_pointer(be->locked_pointer);
54+ be->locked_pointer = NULL;
55+ }
56+
57+ if (be->cursor_state == MAUS_CURSOR_STATE_VISIBLE)
58+ cursor_show(mw);
59+}
60+
61 static void cursor_show(Maus* mw)
62 {
63 MausBackend* be = &mw->backend;
64@@ -745,6 +780,8 @@ void maus_close(Maus* mw)
65 if (be->surface)
66 wl_surface_destroy(be->surface);
67
68+ cursor_unlock(mw);
69+
70 if (be->keyboard)
71 wl_keyboard_destroy(be->keyboard);
72
73@@ -754,6 +791,9 @@ void maus_close(Maus* mw)
74 if (be->seat)
75 wl_seat_destroy(be->seat);
76
77+ if (be->pointer_constraints)
78+ zwp_pointer_constraints_v1_destroy(be->pointer_constraints);
79+
80 if (be->xkb_state)
81 xkb_state_unref(be->xkb_state);
82
83@@ -790,6 +830,7 @@ int8_t maus_close_window(Maus* mw)
84 {
85 MausBackend* be = &mw->backend;
86
87+ cursor_unlock(mw);
88 fb_destroy(mw);
89
90 if (be->xdg_toplevel)
91@@ -1011,9 +1052,13 @@ void maus_cur_set_mode(Maus* mw, MausCursorState state)
92 mw->backend.cursor_state = state;
93 break;
94 case MAUS_CURSOR_STATE_LOCKED:
95- /* TODO */
96+ mw->backend.cursor_state = state;
97+ cursor_lock(mw);
98+ break;
99 case MAUS_CURSOR_STATE_FREE:
100- /* TODO */
101+ cursor_unlock(mw);
102+ mw->backend.cursor_state = MAUS_CURSOR_STATE_VISIBLE;
103+ break;
104 default:
105 break;
106 }