From 935d76ba04fe50a0a4e255eec5af2e510a96cf9a Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 8 Sep 2015 14:32:50 +0200 Subject: [PATCH] wayland: Implement wl_pointer.axis_source/axis_stop/axis_frame emission As per the spec: - wl_pointer.axis_source determines the current source of scroll events. - wl_pointer.axis_stop determines when there's no further scroll events on the given axis. - wl_pointer.axis_discrete is emitted on "wheel" scroll sources, measured in ticks. - wl_pointer.frame is meant to coalesce events that logically belong together, e.g. axis events in this case. Co-Authored-By: Peter Hutterer https://bugzilla.gnome.org/show_bug.cgi?id=760637 --- src/wayland/meta-wayland-pointer.c | 76 +++++++++++++++++++++++++++++ src/wayland/meta-wayland-versions.h | 2 +- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index c746a138d..d9e66f059 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -242,6 +242,21 @@ pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data) meta_wayland_pointer_set_focus (pointer, NULL); } +static void +meta_wayland_pointer_send_frame (MetaWaylandPointer *pointer) +{ + struct wl_resource *resource; + + if (!pointer->focus_client) + return; + + wl_resource_for_each (resource, &pointer->focus_client->pointer_resources) + { + if (wl_resource_get_version (resource) >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION) + wl_pointer_send_frame (resource); + } +} + void meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer, const ClutterEvent *event) @@ -262,6 +277,8 @@ meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer, { wl_pointer_send_motion (resource, time, sx, sy); } + + meta_wayland_pointer_send_frame (pointer); } void @@ -321,6 +338,8 @@ meta_wayland_pointer_send_button (MetaWaylandPointer *pointer, time, button, event_type == CLUTTER_BUTTON_PRESS ? 1 : 0); } + + meta_wayland_pointer_send_frame (pointer); } if (pointer->button_count == 0 && event_type == CLUTTER_BUTTON_RELEASE) @@ -510,26 +529,48 @@ handle_scroll_event (MetaWaylandPointer *pointer, { struct wl_resource *resource; wl_fixed_t x_value = 0, y_value = 0; + int x_discrete = 0, y_discrete = 0; + enum wl_pointer_axis_source source = -1; if (clutter_event_is_pointer_emulated (event)) return; + switch (event->scroll.scroll_source) + { + case CLUTTER_SCROLL_SOURCE_WHEEL: + source = WL_POINTER_AXIS_SOURCE_WHEEL; + break; + case CLUTTER_SCROLL_SOURCE_FINGER: + source = WL_POINTER_AXIS_SOURCE_FINGER; + break; + case CLUTTER_SCROLL_SOURCE_CONTINUOUS: + source = WL_POINTER_AXIS_SOURCE_CONTINUOUS; + break; + default: + source = WL_POINTER_AXIS_SOURCE_WHEEL; + break; + } + switch (clutter_event_get_scroll_direction (event)) { case CLUTTER_SCROLL_UP: y_value = -DEFAULT_AXIS_STEP_DISTANCE; + y_discrete = -1; break; case CLUTTER_SCROLL_DOWN: y_value = DEFAULT_AXIS_STEP_DISTANCE; + y_discrete = 1; break; case CLUTTER_SCROLL_LEFT: x_value = -DEFAULT_AXIS_STEP_DISTANCE; + x_discrete = -1; break; case CLUTTER_SCROLL_RIGHT: x_value = DEFAULT_AXIS_STEP_DISTANCE; + x_discrete = 1; break; case CLUTTER_SCROLL_SMOOTH: @@ -553,13 +594,44 @@ handle_scroll_event (MetaWaylandPointer *pointer, { wl_resource_for_each (resource, &pointer->focus_client->pointer_resources) { + if (wl_resource_get_version (resource) >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION) + wl_pointer_send_axis_source (resource, source); + + /* X axis */ + if (x_discrete != 0 && + wl_resource_get_version (resource) >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION) + wl_pointer_send_axis_discrete (resource, + WL_POINTER_AXIS_HORIZONTAL_SCROLL, + x_discrete); + if (x_value) wl_pointer_send_axis (resource, clutter_event_get_time (event), WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value); + + if ((event->scroll.finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL) && + wl_resource_get_version (resource) >= WL_POINTER_AXIS_STOP_SINCE_VERSION) + wl_pointer_send_axis_stop (resource, + clutter_event_get_time (event), + WL_POINTER_AXIS_HORIZONTAL_SCROLL); + /* Y axis */ + if (y_discrete != 0 && + wl_resource_get_version (resource) >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION) + wl_pointer_send_axis_discrete (resource, + WL_POINTER_AXIS_VERTICAL_SCROLL, + y_discrete); + if (y_value) wl_pointer_send_axis (resource, clutter_event_get_time (event), WL_POINTER_AXIS_VERTICAL_SCROLL, y_value); + + if ((event->scroll.finish_flags & CLUTTER_SCROLL_FINISHED_VERTICAL) && + wl_resource_get_version (resource) >= WL_POINTER_AXIS_STOP_SINCE_VERSION) + wl_pointer_send_axis_stop (resource, + clutter_event_get_time (event), + WL_POINTER_AXIS_VERTICAL_SCROLL); } + + meta_wayland_pointer_send_frame (pointer); } } @@ -632,6 +704,8 @@ meta_wayland_pointer_broadcast_enter (MetaWaylandPointer *pointer, &pointer->focus_client->pointer_resources) meta_wayland_pointer_send_enter (pointer, pointer_resource, serial, surface); + + meta_wayland_pointer_send_frame (pointer); } static void @@ -645,6 +719,8 @@ meta_wayland_pointer_broadcast_leave (MetaWaylandPointer *pointer, &pointer->focus_client->pointer_resources) meta_wayland_pointer_send_leave (pointer, pointer_resource, serial, surface); + + meta_wayland_pointer_send_frame (pointer); } void diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h index a6de27b31..91a82af7c 100644 --- a/src/wayland/meta-wayland-versions.h +++ b/src/wayland/meta-wayland-versions.h @@ -39,7 +39,7 @@ #define META_WL_DATA_DEVICE_MANAGER_VERSION 2 #define META_XDG_SHELL_VERSION 1 #define META_WL_SHELL_VERSION 1 -#define META_WL_SEAT_VERSION 4 +#define META_WL_SEAT_VERSION 5 #define META_WL_OUTPUT_VERSION 2 #define META_XSERVER_VERSION 1 #define META_GTK_SHELL_VERSION 2