[gtk: 5/9] gdk/wayland: Handle high-resolution scroll events




commit ed0a2a203c5b80c6c7d062f6181c065c18a298df
Author: José Expósito <jose exposito89 gmail com>
Date:   Mon Sep 20 19:59:58 2021 +0200

    gdk/wayland: Handle high-resolution scroll events
    
    Starting with the Wayland protocol wl_pointer >= 8, discrete axis
    events have been deprecated in favour of high-resolution scroll event.
    
    Add a listener for high-resolution scroll events and, for backwards
    compatibility, handle discrete events as discrete*120.

 gdk/wayland/gdkdevice-wayland.c  | 99 ++++++++++++++++++++++++++++++----------
 gdk/wayland/gdkdisplay-wayland.c |  2 +-
 2 files changed, 77 insertions(+), 24 deletions(-)
---
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index c6ab24dad2..1cea5ab1ea 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -112,7 +112,7 @@ struct _GdkWaylandPointerFrameData
 
   /* Specific to the scroll event */
   double delta_x, delta_y;
-  int32_t discrete_x, discrete_y;
+  int32_t value120_x, value120_y;
   gint8 is_scroll_stop;
   enum wl_pointer_axis_source source;
 };
@@ -1383,31 +1383,54 @@ static GdkDevice * get_scroll_device (GdkWaylandSeat              *seat,
 
 static void
 flush_discrete_scroll_event (GdkWaylandSeat     *seat,
-                             gint                discrete_x,
-                             gint                discrete_y)
+                             gint                value120_x,
+                             gint                value120_y)
 {
-  GdkEvent *event;
+  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
+  GdkEvent *event = NULL;
   GdkDevice *source;
   GdkScrollDirection direction;
 
-  if (discrete_x > 0)
+  if (value120_x > 0)
     direction = GDK_SCROLL_LEFT;
-  else if (discrete_x < 0)
+  else if (value120_x < 0)
     direction = GDK_SCROLL_RIGHT;
-  else if (discrete_y > 0)
+  else if (value120_y > 0)
     direction = GDK_SCROLL_DOWN;
   else
     direction = GDK_SCROLL_UP;
 
   source = get_scroll_device (seat, seat->pointer_info.frame.source);
-  event = gdk_scroll_event_new_discrete (seat->pointer_info.focus,
-                                         source,
-                                         NULL,
-                                         seat->pointer_info.time,
-                                         device_get_modifiers (seat->logical_pointer),
-                                         direction);
 
-  _gdk_wayland_display_deliver_event (seat->display, event);
+  if (display_wayland->seat_version >= WL_POINTER_AXIS_VALUE120_SINCE_VERSION)
+    {
+      event = gdk_scroll_event_new_value120 (seat->pointer_info.focus,
+                                             source,
+                                             NULL,
+                                             seat->pointer_info.time,
+                                             device_get_modifiers (seat->logical_pointer),
+                                             direction,
+                                             value120_x,
+                                             value120_y);
+    }
+  else
+    {
+      gint discrete_x = value120_x / 120;
+      gint discrete_y = value120_y / 120;
+
+      if (discrete_x != 0 || discrete_y != 0)
+        {
+          event = gdk_scroll_event_new_discrete (seat->pointer_info.focus,
+                                                 source,
+                                                 NULL,
+                                                 seat->pointer_info.time,
+                                                 device_get_modifiers (seat->logical_pointer),
+                                                 direction);
+        }
+    }
+
+  if (event)
+    _gdk_wayland_display_deliver_event (seat->display, event);
 }
 
 static void
@@ -1438,13 +1461,13 @@ flush_scroll_event (GdkWaylandSeat             *seat,
 {
   gboolean is_stop = FALSE;
 
-  if (pointer_frame->discrete_x || pointer_frame->discrete_y)
+  if (pointer_frame->value120_x || pointer_frame->value120_y)
     {
       flush_discrete_scroll_event (seat,
-                                   pointer_frame->discrete_x,
-                                   pointer_frame->discrete_y);
-      pointer_frame->discrete_x = 0;
-      pointer_frame->discrete_y = 0;
+                                   pointer_frame->value120_x,
+                                   pointer_frame->value120_y);
+      pointer_frame->value120_x = 0;
+      pointer_frame->value120_y = 0;
     }
   else if (pointer_frame->is_scroll_stop ||
            pointer_frame->delta_x != 0 ||
@@ -1464,8 +1487,8 @@ flush_scroll_event (GdkWaylandSeat             *seat,
                                  is_stop);
     }
 
-  pointer_frame->discrete_x = 0;
-  pointer_frame->discrete_y = 0;
+  pointer_frame->value120_x = 0;
+  pointer_frame->value120_y = 0;
   pointer_frame->delta_x = 0;
   pointer_frame->delta_y = 0;
   pointer_frame->is_scroll_stop = FALSE;
@@ -1864,10 +1887,10 @@ pointer_handle_axis_discrete (void              *data,
   switch (axis)
     {
     case WL_POINTER_AXIS_VERTICAL_SCROLL:
-      pointer_frame->discrete_y = value;
+      pointer_frame->value120_y = value * 120;
       break;
     case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
-      pointer_frame->discrete_x = value;
+      pointer_frame->value120_x = value * 120;
       break;
     default:
       g_return_if_reached ();
@@ -1878,6 +1901,35 @@ pointer_handle_axis_discrete (void              *data,
                        get_axis_name (axis), value, seat));
 }
 
+static void
+pointer_handle_axis_value120 (void              *data,
+                              struct wl_pointer *pointer,
+                              uint32_t           axis,
+                              int32_t            value)
+{
+  GdkWaylandSeat *seat = data;
+  GdkWaylandPointerFrameData *pointer_frame = &seat->pointer_info.frame;
+
+  if (!seat->pointer_info.focus)
+    return;
+
+  switch (axis)
+    {
+    case WL_POINTER_AXIS_VERTICAL_SCROLL:
+      pointer_frame->value120_y = value;
+      break;
+    case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
+      pointer_frame->value120_x = value;
+      break;
+    default:
+      g_return_if_reached ();
+    }
+
+  GDK_SEAT_NOTE (seat, EVENTS,
+            g_message ("value120 scroll, axis %s, value %d, seat %p",
+                       get_axis_name (axis), value, seat));
+}
+
 static int
 get_active_layout (GdkKeymap *keymap)
 {
@@ -3072,6 +3124,7 @@ static const struct wl_pointer_listener pointer_listener = {
   pointer_handle_axis_source,
   pointer_handle_axis_stop,
   pointer_handle_axis_discrete,
+  pointer_handle_axis_value120,
 };
 
 static const struct wl_keyboard_listener keyboard_listener = {
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index fd2aeee12d..142c971730 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -232,7 +232,7 @@ _gdk_wayland_display_add_seat (GdkWaylandDisplay *display_wayland,
 {
   struct wl_seat *seat;
 
-  display_wayland->seat_version = MIN (version, 7);
+  display_wayland->seat_version = MIN (version, 8);
   seat = wl_registry_bind (display_wayland->wl_registry,
                            id, &wl_seat_interface,
                            display_wayland->seat_version);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]