From: Ray Strode rstrode@redhat.com
Wayland has 3 types of scrolling events:
- axis. Used for e.g., touchpad 2 finger smooth scrolling - axis_discrete. Used for mouse scroll wheels (i.e., notches) - axis_value120. Used for high resolution input devices
Wine currently only supports axis_discrete, meaning that 2 finger scroll events get ignored.
This commit tries to add basic support for axis scrolling events, by translating the smooth motion in scroll increments using some primitive assumptions about line height and number of lines to scroll. --- dlls/winewayland.drv/wayland_pointer.c | 51 ++++++++++++++++++++++++++ dlls/winewayland.drv/waylanddrv.h | 2 + 2 files changed, 53 insertions(+)
diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index fad75c8506c..06fbc9882c5 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -191,10 +191,57 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) { + struct wayland_pointer *pointer = &process_wayland.pointer; + HWND hwnd; + double pixels_scrolled; + double lines_scrolled; + double increments; + int32_t mouse_data; + + if (!(hwnd = wayland_pointer_get_focused_hwnd())) return; + + if (pointer->scroll_frame_number == pointer->next_frame_number) return; + + input.type = INPUT_MOUSE; + + pixels_scrolled = wl_fixed_to_double(value); + /* FIXME: Assuming 18 pixels per line and 3 lines per scroll increment. + * I'm not sure how to do better. Maybe we should call + * SystemParametersInfoW( SPI_GETWHEELSCROLLLINES, 0, &scroll_lines, 0 ); + * instead of assuming 3 lines per scroll increment? + * Maybe there's a way to send smooth scrolling information in pixel units, + * instead of the fixed point scroll units? + * We could also ignore value, and just make every swipe operation scroll one + * increment. I suspect that users might find that unreasonable sluggish. + */ + lines_scrolled = pixels_scrolled / 18.0; + increments = lines_scrolled / 3; + mouse_data = (int32_t) round(WHEEL_DELTA * increments): + + switch (axis) + { + case WL_POINTER_AXIS_VERTICAL_SCROLL: + input.mi.dwFlags = MOUSEEVENTF_WHEEL; + input.mi.mouseData = -mouse_data; + break; + case WL_POINTER_AXIS_HORIZONTAL_SCROLL: + input.mi.dwFlags = MOUSEEVENTF_HWHEEL; + input.mi.mouseData = mouse_data; + break; + default: break; + } + + TRACE("hwnd=%p axis=%u value=%lf\n", hwnd, axis, pixels_scrolled); + + __wine_send_input(hwnd, &input, NULL); + pointer->scroll_frame_number = pointer->next_frame_number; }
static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) { + struct wayland_pointer *pointer = &process_wayland.pointer; + + pointer->next_frame_number++; }
static void pointer_handle_axis_source(void *data, struct wl_pointer *wl_pointer, @@ -210,6 +257,7 @@ static void pointer_handle_axis_stop(void *data, struct wl_pointer *wl_pointer, static void pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete) { + struct wayland_pointer *pointer = &process_wayland.pointer; INPUT input = {0}; HWND hwnd;
@@ -233,6 +281,7 @@ static void pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_point TRACE("hwnd=%p axis=%u discrete=%d\n", hwnd, axis, discrete);
__wine_send_input(hwnd, &input, NULL); + pointer->scroll_frame_number = pointer->next_frame_number; }
static const struct wl_pointer_listener pointer_listener = @@ -333,6 +382,7 @@ void wayland_pointer_init(struct wl_pointer *wl_pointer) pointer->wl_pointer = wl_pointer; pointer->focused_hwnd = NULL; pointer->enter_serial = 0; + pointer->next_frame_number = 0; pthread_mutex_unlock(&pointer->mutex); wl_pointer_add_listener(pointer->wl_pointer, &pointer_listener, NULL); } @@ -361,6 +411,7 @@ void wayland_pointer_deinit(void) pointer->wl_pointer = NULL; pointer->focused_hwnd = NULL; pointer->enter_serial = 0; + pointer->next_frame_number = 0; pthread_mutex_unlock(&pointer->mutex); }
diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 0883c43f1ff..fc7fd6ee3fc 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -99,6 +99,8 @@ struct wayland_pointer HWND constraint_hwnd; uint32_t enter_serial; uint32_t button_serial; + uint32_t scroll_frame_number; + uint32_t next_frame_number; struct wayland_cursor cursor; pthread_mutex_t mutex; };