diff --git a/docs/changelog.rst b/docs/changelog.rst index e761d37a8..9be9fe3ba 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -187,6 +187,8 @@ Detailed list of changes - Change :opt:`focus_follows_mouse` to switch the active window only when the mouse crosses into a different window, instead of on every mouse motion event. Prevents accidental mouse bumps from undoing a keyboard-driven window switch. +- Wayland: Use hold gestures to cancel momentum scrolling when fingers are placed on the trackpad, for a more natural kinetic scrolling experience (:iss:`9863`) + - Fix thickness of diagonal lines in box drawing characters not the same as horizontal/vertical lines (:iss:`9719`) - Graphics protocol: Fix crash when handling invalid PNG image with direct transmission diff --git a/glfw/source-info.json b/glfw/source-info.json index be181c201..dacad1d8a 100644 --- a/glfw/source-info.json +++ b/glfw/source-info.json @@ -90,6 +90,7 @@ "staging/xdg-toplevel-tag/xdg-toplevel-tag-v1.xml", "staging/ext-background-effect/ext-background-effect-v1.xml", "staging/xdg-toplevel-drag/xdg-toplevel-drag-v1.xml", + "unstable/pointer-gestures/pointer-gestures-unstable-v1.xml", "kwin-blur-v1.xml", "wlr-layer-shell-unstable-v1.xml" diff --git a/glfw/wl_init.c b/glfw/wl_init.c index be840b40f..839fe2b78 100644 --- a/glfw/wl_init.c +++ b/glfw/wl_init.c @@ -34,6 +34,7 @@ #include "../kitty/monotonic.h" #include "wl_text_input.h" #include "wayland-text-input-unstable-v3-client-protocol.h" +#include "wayland-pointer-gestures-unstable-v1-client-protocol.h" #include #include @@ -463,6 +464,22 @@ static const struct wl_keyboard_listener keyboardListener = { keyboardHandleRepeatInfo, }; +static void +holdGestureHandleBegin(void *data UNUSED, struct zwp_pointer_gesture_hold_v1 *gesture UNUSED, + uint32_t serial UNUSED, uint32_t time UNUSED, + struct wl_surface *surface UNUSED, uint32_t fingers UNUSED) { + glfw_cancel_momentum_scroll(); +} + +static void +holdGestureHandleEnd(void *data UNUSED, struct zwp_pointer_gesture_hold_v1 *gesture UNUSED, + uint32_t serial UNUSED, uint32_t time UNUSED, int32_t cancelled UNUSED) {} + +static const struct zwp_pointer_gesture_hold_v1_listener holdGestureListener = { + .begin = holdGestureHandleBegin, + .end = holdGestureHandleEnd, +}; + static void seatHandleCapabilities(void* data UNUSED, struct wl_seat* seat, enum wl_seat_capability caps) @@ -476,11 +493,19 @@ static void seatHandleCapabilities(void* data UNUSED, _glfw.wl.wp_cursor_shape_device_v1 = NULL; _glfw.wl.wp_cursor_shape_device_v1 = wp_cursor_shape_manager_v1_get_pointer(_glfw.wl.wp_cursor_shape_manager_v1, _glfw.wl.pointer); } + if (_glfw.wl.pointer_gestures) { + _glfw.wl.pointer_gesture_hold = zwp_pointer_gestures_v1_get_hold_gesture(_glfw.wl.pointer_gestures, _glfw.wl.pointer); + zwp_pointer_gesture_hold_v1_add_listener(_glfw.wl.pointer_gesture_hold, &holdGestureListener, NULL); + } } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer) { if (_glfw.wl.wp_cursor_shape_device_v1) wp_cursor_shape_device_v1_destroy(_glfw.wl.wp_cursor_shape_device_v1); _glfw.wl.wp_cursor_shape_device_v1 = NULL; + if (_glfw.wl.pointer_gesture_hold) { + zwp_pointer_gesture_hold_v1_destroy(_glfw.wl.pointer_gesture_hold); + _glfw.wl.pointer_gesture_hold = NULL; + } wl_pointer_destroy(_glfw.wl.pointer); _glfw.wl.pointer = NULL; if (_glfw.wl.cursorAnimationTimer) toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.cursorAnimationTimer, 0); @@ -676,6 +701,10 @@ static void registryHandleGlobal(void* data UNUSED, else if (is(zwp_keyboard_shortcuts_inhibit_manager_v1)) { _glfw.wl.keyboard_shortcuts_inhibit_manager = wl_registry_bind(registry, name, &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1); } + else if (is(zwp_pointer_gestures_v1)) { + if (version >= 3) + _glfw.wl.pointer_gestures = wl_registry_bind(registry, name, &zwp_pointer_gestures_v1_interface, 3); + } else if (is(xdg_toplevel_icon_manager_v1)) { _glfw.wl.xdg_toplevel_icon_manager_v1 = wl_registry_bind(registry, name, &xdg_toplevel_icon_manager_v1_interface, 1); } @@ -1005,6 +1034,10 @@ void _glfwPlatformTerminate(void) zwp_idle_inhibit_manager_v1_destroy(_glfw.wl.idle_inhibit_manager); if (_glfw.wl.keyboard_shortcuts_inhibit_manager) zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(_glfw.wl.keyboard_shortcuts_inhibit_manager); + if (_glfw.wl.pointer_gesture_hold) + zwp_pointer_gesture_hold_v1_destroy(_glfw.wl.pointer_gesture_hold); + if (_glfw.wl.pointer_gestures) + zwp_pointer_gestures_v1_release(_glfw.wl.pointer_gestures); if (_glfw.wl.registry) wl_registry_destroy(_glfw.wl.registry); diff --git a/glfw/wl_platform.h b/glfw/wl_platform.h index 7af11bda3..e294a06ad 100644 --- a/glfw/wl_platform.h +++ b/glfw/wl_platform.h @@ -364,6 +364,8 @@ typedef struct _GLFWlibraryWayland struct wp_single_pixel_buffer_manager_v1 *wp_single_pixel_buffer_manager_v1; struct zwp_idle_inhibit_manager_v1* idle_inhibit_manager; struct zwp_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit_manager; + struct zwp_pointer_gestures_v1* pointer_gestures; + struct zwp_pointer_gesture_hold_v1* pointer_gesture_hold; int compositorVersion; int seatVersion;