[mutter] backends/native: Migrate discrete scroll



commit 5171e5b7950bd1b315e087c2bfa13d1cd18cbb7c
Author: José Expósito <jose exposito89 gmail com>
Date:   Mon Sep 20 19:53:20 2021 +0200

    backends/native: Migrate discrete scroll
    
    Change meta_seat_impl_notify_discrete_scroll_in_impl to receive 120
    based values and report high-resolution scroll values as smooth scroll.
    
    Notify discrete scroll only when the accumulated value reach 120.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1962>

 src/backends/native/meta-input-device-native.h     | 13 ++++
 src/backends/native/meta-seat-impl.c               | 79 ++++++++++++++++++----
 src/backends/native/meta-seat-impl.h               |  4 +-
 .../native/meta-virtual-input-device-native.c      |  3 +-
 4 files changed, 84 insertions(+), 15 deletions(-)
---
diff --git a/src/backends/native/meta-input-device-native.h b/src/backends/native/meta-input-device-native.h
index 88af07c435..0fd17b86c0 100644
--- a/src/backends/native/meta-input-device-native.h
+++ b/src/backends/native/meta-input-device-native.h
@@ -88,6 +88,19 @@ struct _MetaInputDeviceNative
   float pointer_x;
   float pointer_y;
 
+  /* When the client doesn't support high-resolution scroll, accumulate deltas
+   * until we can notify a discrete event.
+   * Some mice have a free spinning wheel, making possible to lock the wheel
+   * when the accumulator value is not 0. To avoid synchronization issues
+   * between the mouse wheel and the accumulators, store the last delta and when
+   * the scroll direction changes, reset the accumulator. */
+  struct {
+    int32_t acc_dx;
+    int32_t acc_dy;
+    int32_t last_dx;
+    int32_t last_dy;
+  } value120;
+
   /* Keyboard a11y */
   MetaKeyboardA11yFlags a11y_flags;
   GList *slow_keys_list;
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
index 6f3380691c..def778eb5a 100644
--- a/src/backends/native/meta-seat-impl.c
+++ b/src/backends/native/meta-seat-impl.c
@@ -895,23 +895,78 @@ discrete_to_direction (double discrete_dx,
   return 0;
 }
 
+static gboolean
+should_reset_discrete_acc (double current_delta,
+                           double last_delta)
+{
+  if (last_delta == 0)
+    return TRUE;
+
+  return (current_delta < 0 && last_delta > 0) ||
+         (current_delta > 0 && last_delta < 0);
+}
+
 void
 meta_seat_impl_notify_discrete_scroll_in_impl (MetaSeatImpl        *seat_impl,
                                                ClutterInputDevice  *input_device,
                                                uint64_t             time_us,
-                                               double               discrete_dx,
-                                               double               discrete_dy,
+                                               double               dx_value120,
+                                               double               dy_value120,
                                                ClutterScrollSource  scroll_source)
 {
+  MetaInputDeviceNative *evdev_device;
+  double dx = 0, dy = 0;
+  int discrete_dx = 0, discrete_dy = 0;
+
+  /* Convert into DISCRETE_SCROLL_STEP range. 120/DISCRETE_SCROLL_STEP = 12.0 */
+  dx = dx_value120 / 12.0;
+  dy = dy_value120 / 12.0;
+
   notify_scroll (input_device, time_us,
-                 discrete_dx * DISCRETE_SCROLL_STEP,
-                 discrete_dy * DISCRETE_SCROLL_STEP,
+                 dx,
+                 dy,
                  scroll_source, CLUTTER_SCROLL_FINISHED_NONE,
-                 TRUE);
-  notify_discrete_scroll (input_device, time_us,
-                          discrete_to_direction (discrete_dx, discrete_dy),
-                          scroll_source, FALSE);
+                 FALSE);
+
+  /* Notify discrete scroll only when the accumulated value reach 120 */
+  evdev_device = META_INPUT_DEVICE_NATIVE (input_device);
+
+  if (dx_value120 != 0)
+    {
+      if (should_reset_discrete_acc (dx_value120, evdev_device->value120.last_dx))
+        evdev_device->value120.acc_dx = 0;
 
+      evdev_device->value120.last_dx = dx_value120;
+    }
+
+  if (dy_value120 != 0)
+    {
+      if (should_reset_discrete_acc (dy_value120, evdev_device->value120.last_dy))
+        evdev_device->value120.acc_dy = 0;
+
+      evdev_device->value120.last_dy = dy_value120;
+    }
+
+  evdev_device->value120.acc_dx += dx_value120;
+  evdev_device->value120.acc_dy += dy_value120;
+  discrete_dx = (evdev_device->value120.acc_dx / 120);
+  discrete_dy = (evdev_device->value120.acc_dy / 120);
+
+  if (discrete_dx != 0)
+    {
+      evdev_device->value120.acc_dx -= (discrete_dx * 120);
+      notify_discrete_scroll (input_device, time_us,
+                              discrete_to_direction (discrete_dx, 0),
+                              scroll_source, FALSE);
+    }
+
+  if (discrete_dy != 0)
+    {
+      evdev_device->value120.acc_dy -= (discrete_dy * 120);
+      notify_discrete_scroll (input_device, time_us,
+                              discrete_to_direction (0, discrete_dy),
+                              scroll_source, FALSE);
+    }
 }
 
 void
@@ -1923,24 +1978,24 @@ notify_discrete_axis (MetaSeatImpl                  *seat_impl,
                       ClutterScrollSource            scroll_source,
                       struct libinput_event_pointer *axis_event)
 {
-  double discrete_dx = 0.0, discrete_dy = 0.0;
+  double dx_value120 = 0.0, dy_value120 = 0.0;
 
   if (libinput_event_pointer_has_axis (axis_event,
                                        LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
     {
-      discrete_dx = libinput_event_pointer_get_axis_value_discrete (
+      dx_value120 = libinput_event_pointer_get_scroll_value_v120 ( 
           axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
     }
   if (libinput_event_pointer_has_axis (axis_event,
                                        LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
     {
-      discrete_dy = libinput_event_pointer_get_axis_value_discrete (
+      dy_value120 = libinput_event_pointer_get_scroll_value_v120 (
           axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
     }
 
   meta_seat_impl_notify_discrete_scroll_in_impl (seat_impl, device,
                                                  time_us,
-                                                 discrete_dx, discrete_dy,
+                                                 dx_value120, dy_value120,
                                                  scroll_source);
 }
 
diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h
index d3e2ab8607..995582bcd7 100644
--- a/src/backends/native/meta-seat-impl.h
+++ b/src/backends/native/meta-seat-impl.h
@@ -176,8 +176,8 @@ void meta_seat_impl_notify_scroll_continuous_in_impl (MetaSeatImpl             *
 void meta_seat_impl_notify_discrete_scroll_in_impl (MetaSeatImpl        *seat_impl,
                                                     ClutterInputDevice  *input_device,
                                                     uint64_t             time_us,
-                                                    double               discrete_dx,
-                                                    double               discrete_dy,
+                                                    double               dx_value120,
+                                                    double               dy_value120,
                                                     ClutterScrollSource  source);
 
 void meta_seat_impl_notify_touch_event_in_impl (MetaSeatImpl       *seat_impl,
diff --git a/src/backends/native/meta-virtual-input-device-native.c 
b/src/backends/native/meta-virtual-input-device-native.c
index d2d13748ab..9fe77dfdcb 100644
--- a/src/backends/native/meta-virtual-input-device-native.c
+++ b/src/backends/native/meta-virtual-input-device-native.c
@@ -699,7 +699,8 @@ notify_discrete_scroll_in_impl (GTask *task)
   meta_seat_impl_notify_discrete_scroll_in_impl (seat,
                                                  virtual_evdev->impl_state->device,
                                                  event->time_us,
-                                                 discrete_dx, discrete_dy,
+                                                 discrete_dx * 120.0,
+                                                 discrete_dy * 120.0,
                                                  event->scroll_source);
 
   g_task_return_boolean (task, TRUE);


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