diff --git a/client/displayservers/Wayland/input.c b/client/displayservers/Wayland/input.c index 312a7a5f..d3bbd916 100644 --- a/client/displayservers/Wayland/input.c +++ b/client/displayservers/Wayland/input.c @@ -684,12 +684,16 @@ void waylandWarpPointer(int x, int y, bool exiting) return; } - LG_LOCK(wlWm.surfaceLock); - if (wlWm.lockedPointer) + if (!wlWm.pointerWarpper) { - LG_UNLOCK(wlWm.surfaceLock); - MTRACE("warp drop=lock-race 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; @@ -700,21 +704,32 @@ void waylandWarpPointer(int x, int y, bool exiting) 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); + uint32_t tempId = 0; + uint64_t warpSeq; - 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); + if (wlWm.pointerWarpper) + { + wp_pointer_warp_v1_warp_pointer(wlWm.pointerWarpper, wlWm.surface, + wlWm.pointer, wl_fixed_from_int(x), wl_fixed_from_int(y), + wlWm.pointerEnterSerial); + warpSeq = app_mouseSeq(); + } else { + struct wl_region * region = wl_compositor_create_region(wlWm.compositor); + wl_region_add(region, x, y, 1, 1); - wl_surface_commit(wlWm.surface); - wl_region_destroy(region); + 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); + tempId = proxyId(confine); + wl_surface_commit(wlWm.surface); + zwp_confined_pointer_v1_destroy(confine); - uint64_t warpSeq = app_mouseSeq(); - LG_UNLOCK(wlWm.surfaceLock); + wl_surface_commit(wlWm.surface); + wl_region_destroy(region); + + 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); diff --git a/client/displayservers/Wayland/protocol/CMakeLists.txt b/client/displayservers/Wayland/protocol/CMakeLists.txt index ada8b7d1..5e70d7d2 100644 --- a/client/displayservers/Wayland/protocol/CMakeLists.txt +++ b/client/displayservers/Wayland/protocol/CMakeLists.txt @@ -72,6 +72,9 @@ wayland_generate( wayland_generate( "${WAYLAND_PROTOCOLS_BASE}/staging/xdg-toplevel-icon/xdg-toplevel-icon-v1.xml" "${CMAKE_BINARY_DIR}/wayland/wayland-xdg-toplevel-icon-v1-client-protocol") +wayland_generate( + "${WAYLAND_PROTOCOLS_BASE}/staging/pointer-warp/pointer-warp-v1.xml" + "${CMAKE_BINARY_DIR}/wayland/wayland-pointer-warp-v1-client-protocol") target_link_libraries(wayland_protocol PkgConfig::WAYLAND diff --git a/client/displayservers/Wayland/registry.c b/client/displayservers/Wayland/registry.c index 1aa56f0c..dbb6d082 100644 --- a/client/displayservers/Wayland/registry.c +++ b/client/displayservers/Wayland/registry.c @@ -80,6 +80,9 @@ static void registryGlobalHandler(void * data, struct wl_registry * registry, else if (!strcmp(interface, xdg_toplevel_icon_manager_v1_interface.name)) wlWm.iconManager = wl_registry_bind(wlWm.registry, name, &xdg_toplevel_icon_manager_v1_interface, 1); + else if (!strcmp(interface, wp_pointer_warp_v1_interface.name)) + wlWm.pointerWarpper = wl_registry_bind(wlWm.registry, name, + &wp_pointer_warp_v1_interface, 1); else if (wlWm.desktop->registryGlobalHandler( data, registry, name, interface, version)) return; diff --git a/client/displayservers/Wayland/wayland.h b/client/displayservers/Wayland/wayland.h index 29682b6f..de7d6df8 100644 --- a/client/displayservers/Wayland/wayland.h +++ b/client/displayservers/Wayland/wayland.h @@ -53,6 +53,7 @@ #include "wayland-content-type-v1-client-protocol.h" #include "wayland-color-management-v1-client-protocol.h" #include "wayland-xdg-toplevel-icon-v1-client-protocol.h" +#include "wayland-pointer-warp-v1-client-protocol.h" #include "scale.h" #include "motion.h" @@ -196,6 +197,7 @@ struct WaylandDSState struct zwp_pointer_constraints_v1 * pointerConstraints; struct zwp_relative_pointer_v1 * relativePointer; struct zwp_locked_pointer_v1 * lockedPointer; + struct wp_pointer_warp_v1 * pointerWarpper; bool captureRequested; bool showPointer; uint32_t pointerEnterSerial;