From e2be90e264502d5629849a703b7059107f368f87 Mon Sep 17 00:00:00 2001 From: Quantum Date: Sat, 8 Aug 2026 14:49:45 -0400 Subject: [PATCH] [client] wayland: restore cursor warp support via pointer confining This notably does not restore any of the cursed pointer confining logic. --- client/displayservers/Wayland/input.c | 51 +++++++++++++++++++++++-- client/displayservers/Wayland/wayland.c | 10 ++++- client/displayservers/Wayland/wayland.h | 1 + 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/client/displayservers/Wayland/input.c b/client/displayservers/Wayland/input.c index 1e63bb9c..312a7a5f 100644 --- a/client/displayservers/Wayland/input.c +++ b/client/displayservers/Wayland/input.c @@ -670,9 +670,54 @@ void waylandUngrabKeyboard(void) void waylandWarpPointer(int x, int y, bool exiting) { - (void)x; - (void)y; - (void)exiting; + const int reqX = x; + const int reqY = y; + if (!wlWm.pointerInSurface) + { + MTRACE("warp drop=surface target=%d,%d exit=%d", x, y, exiting); + return; + } + + if (wlWm.lockedPointer) + { + MTRACE("warp drop=lock target=%d,%d exit=%d", x, y, exiting); + return; + } + + LG_LOCK(wlWm.surfaceLock); + if (wlWm.lockedPointer) + { + LG_UNLOCK(wlWm.surfaceLock); + MTRACE("warp drop=lock-race target=%d,%d exit=%d", x, y, exiting); + return; + } + + int width, height; + wlWm.desktop->getSize(&width, &height); + + if (x < 0) x = 0; + else if (x >= width) x = width - 1; + if (y < 0) y = 0; + else if (y >= height) y = height - 1; + + struct wl_region * region = wl_compositor_create_region(wlWm.compositor); + wl_region_add(region, x, y, 1, 1); + + struct zwp_confined_pointer_v1 * confine = zwp_pointer_constraints_v1_confine_pointer( + wlWm.pointerConstraints, wlWm.surface, wlWm.pointer, region, + ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); + uint32_t tempId = proxyId(confine); + wl_surface_commit(wlWm.surface); + zwp_confined_pointer_v1_destroy(confine); + + wl_surface_commit(wlWm.surface); + wl_region_destroy(region); + + uint64_t warpSeq = app_mouseSeq(); + LG_UNLOCK(wlWm.surfaceLock); + + MLOG(warpSeq, "warp req=%d,%d target=%d,%d exit=%d temp=%u", + reqX, reqY, x, y, exiting, tempId); } void waylandRealignPointer(void) diff --git a/client/displayservers/Wayland/wayland.c b/client/displayservers/Wayland/wayland.c index 0c53a741..642d9dbf 100644 --- a/client/displayservers/Wayland/wayland.c +++ b/client/displayservers/Wayland/wayland.c @@ -34,6 +34,13 @@ static struct Option waylandOptions[] = { + { + .module = "wayland", + .name = "warpSupport", + .description = "Enable cursor warping", + .type = OPTION_TYPE_BOOL, + .value.x_bool = true, + }, { .module = "wayland", .name = "fractionScale", @@ -133,6 +140,7 @@ static bool waylandInit(const LG_DSInitParams params) wl_list_init(&wlWm.surfaceOutputs); + wlWm.warpSupport = option_get_bool("wayland", "warpSupport"); wlWm.useFractionalScale = option_get_bool("wayland", "fractionScale"); if (!waylandPollInit()) @@ -215,7 +223,7 @@ static bool waylandGetProp(LG_DSProperty prop, void * ret) { if (prop == LG_DS_WARP_SUPPORT) { - *(enum LG_DSWarpSupport*)ret = LG_DS_WARP_NONE; + *(enum LG_DSWarpSupport*)ret = wlWm.warpSupport ? LG_DS_WARP_SURFACE : LG_DS_WARP_NONE; return true; } diff --git a/client/displayservers/Wayland/wayland.h b/client/displayservers/Wayland/wayland.h index 991fe990..29682b6f 100644 --- a/client/displayservers/Wayland/wayland.h +++ b/client/displayservers/Wayland/wayland.h @@ -142,6 +142,7 @@ struct WaylandDSState bool fractionalScale; bool needsResize; bool configured; + bool warpSupport; struct WlMotion motion; double scrollState;