[gtk/wip/exalm/scroll-gesture: 9/11] scrolledwindow: Port to the new controllers




commit 0a454f3bf562de53a8cf191d389ec07b637a8d2a
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Fri Sep 17 18:41:02 2021 +0500

    scrolledwindow: Port to the new controllers
    
    Make sure the drag code path can handle scrolling without behavior
    changes, replace GtkEventControllerScroll with Wheel.

 gtk/gtkscrolledwindow.c | 186 ++++++++++++++++++------------------------------
 1 file changed, 68 insertions(+), 118 deletions(-)
---
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 372afe4a95..50a996035e 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -31,8 +31,8 @@
 #include "gtkbuildable.h"
 #include "gtkdragsourceprivate.h"
 #include "gtkeventcontrollermotion.h"
-#include "gtkeventcontrollerscroll.h"
 #include "gtkeventcontrollerprivate.h"
+#include "gtkeventcontrollerwheel.h"
 #include "gtkgesturedrag.h"
 #include "gtkgesturelongpress.h"
 #include "gtkgesturepan.h"
@@ -265,7 +265,6 @@ typedef struct
   guint    auto_added_viewport      : 1;
   guint    propagate_natural_width  : 1;
   guint    propagate_natural_height : 1;
-  guint    smooth_scroll            : 1;
 
   int      min_content_width;
   int      min_content_height;
@@ -287,9 +286,12 @@ typedef struct
 
   double drag_start_x;
   double drag_start_y;
+  double last_drag_offset_x;
+  double last_drag_offset_y;
 
   guint                  kinetic_scrolling         : 1;
   guint                  in_drag                   : 1;
+  guint                  drag_active               : 1;
 
   guint                  deceleration_id;
 
@@ -401,10 +403,8 @@ static void     indicator_start_fade (Indicator *indicator,
 static void     indicator_set_over   (Indicator *indicator,
                                       gboolean   over);
 
-static void scrolled_window_scroll (GtkScrolledWindow        *scrolled_window,
-                                    double                    delta_x,
-                                    double                    delta_y,
-                                    GtkEventControllerScroll *scroll);
+static double   get_scroll_unit (GtkScrolledWindow *sw,
+                                 GtkOrientation     orientation);
 
 static guint signals[LAST_SIGNAL] = {0};
 static GParamSpec *properties[NUM_PROPERTIES];
@@ -953,7 +953,8 @@ scrolled_window_drag_begin_cb (GtkScrolledWindow *scrolled_window,
   priv->in_drag = FALSE;
   priv->drag_start_x = priv->unclamped_hadj_value;
   priv->drag_start_y = priv->unclamped_vadj_value;
-  gtk_scrolled_window_cancel_deceleration (scrolled_window);
+  priv->last_drag_offset_x = 0;
+  priv->last_drag_offset_y = 0;
   sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
   event_widget = gtk_gesture_get_last_target (gesture, sequence);
 
@@ -991,10 +992,21 @@ scrolled_window_drag_update_cb (GtkScrolledWindow *scrolled_window,
   GtkAdjustment *hadjustment;
   GtkAdjustment *vadjustment;
   double dx, dy;
+  GdkEventType event_type;
+  gboolean scroll;
 
   sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
+  event_type = gdk_event_get_event_type (gtk_event_controller_get_current_event (GTK_EVENT_CONTROLLER 
(gesture)));
+  scroll = event_type == GDK_SCROLL;
+
+  if (!priv->drag_active)
+    {
+      gtk_scrolled_window_cancel_deceleration (scrolled_window);
+      priv->drag_active = TRUE;
+    }
 
-  if (gtk_gesture_get_sequence_state (gesture, sequence) != GTK_EVENT_SEQUENCE_CLAIMED &&
+  if (!scroll &&
+      gtk_gesture_get_sequence_state (gesture, sequence) != GTK_EVENT_SEQUENCE_CLAIMED &&
       !gtk_drag_check_threshold_double (GTK_WIDGET (scrolled_window),
                                         0, 0, offset_x, offset_y))
     return;
@@ -1005,7 +1017,15 @@ scrolled_window_drag_update_cb (GtkScrolledWindow *scrolled_window,
   hadjustment = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->hscrollbar));
   if (hadjustment && may_hscroll (scrolled_window))
     {
-      dx = priv->drag_start_x - offset_x;
+      if (scroll)
+        {
+          double scroll_unit = get_scroll_unit (scrolled_window, GTK_ORIENTATION_HORIZONTAL);
+
+          dx = priv->unclamped_hadj_value - (offset_x - priv->last_drag_offset_x) * scroll_unit;
+        }
+      else
+        dx = priv->drag_start_x - offset_x;
+
       _gtk_scrolled_window_set_adjustment_value (scrolled_window,
                                                  hadjustment, dx);
     }
@@ -1013,12 +1033,23 @@ scrolled_window_drag_update_cb (GtkScrolledWindow *scrolled_window,
   vadjustment = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->vscrollbar));
   if (vadjustment && may_vscroll (scrolled_window))
     {
-      dy = priv->drag_start_y - offset_y;
+      if (scroll)
+        {
+          double scroll_unit = get_scroll_unit (scrolled_window, GTK_ORIENTATION_VERTICAL);
+
+          dy = priv->unclamped_vadj_value - (offset_y - priv->last_drag_offset_y) * scroll_unit;
+        }
+      else
+        dy = priv->drag_start_y - offset_y;
+
       _gtk_scrolled_window_set_adjustment_value (scrolled_window,
                                                  vadjustment, dy);
     }
 
   gtk_scrolled_window_invalidate_overshoot (scrolled_window);
+
+  priv->last_drag_offset_x = offset_x;
+  priv->last_drag_offset_y = offset_y;
 }
 
 static void
@@ -1030,6 +1061,8 @@ scrolled_window_drag_end_cb (GtkScrolledWindow *scrolled_window,
 
   if (!priv->in_drag || !gtk_gesture_handles_sequence (gesture, sequence))
     gtk_gesture_set_state (gesture, GTK_EVENT_SEQUENCE_DENIED);
+
+  priv->drag_active = FALSE;
 }
 
 static void
@@ -1060,9 +1093,23 @@ gtk_scrolled_window_decelerate (GtkScrolledWindow *scrolled_window,
 static void
 scrolled_window_swipe_cb (GtkScrolledWindow *scrolled_window,
                           double             x_velocity,
-                          double             y_velocity)
+                          double             y_velocity,
+                          GtkGesture        *gesture)
 {
-  gtk_scrolled_window_decelerate (scrolled_window, -x_velocity, -y_velocity);
+  double unit_x, unit_y;
+  GdkEventType event_type;
+
+  event_type = gdk_event_get_event_type (gtk_event_controller_get_current_event (GTK_EVENT_CONTROLLER 
(gesture)));
+
+  if (event_type == GDK_SCROLL)
+    {
+      unit_x = get_scroll_unit (scrolled_window, GTK_ORIENTATION_HORIZONTAL);
+      unit_y = get_scroll_unit (scrolled_window, GTK_ORIENTATION_VERTICAL);
+    }
+  else
+    unit_x = unit_y = 1.0;
+
+  gtk_scrolled_window_decelerate (scrolled_window, -x_velocity * unit_x, -y_velocity * unit_y);
 }
 
 static void
@@ -1254,26 +1301,6 @@ get_scroll_unit (GtkScrolledWindow *sw,
   return scroll_unit;
 }
 
-static gboolean
-captured_scroll_cb (GtkEventControllerScroll *scroll,
-                    double                    delta_x,
-                    double                    delta_y,
-                    GtkScrolledWindow        *scrolled_window)
-{
-  GtkScrolledWindowPrivate *priv =
-    gtk_scrolled_window_get_instance_private (scrolled_window);
-
-  gtk_scrolled_window_cancel_deceleration (scrolled_window);
-
-  if (priv->smooth_scroll)
-    {
-      scrolled_window_scroll (scrolled_window, delta_x, delta_y, scroll);
-      return GDK_EVENT_STOP;
-    }
-
-  return GDK_EVENT_PROPAGATE;
-}
-
 static void
 captured_motion (GtkEventController *controller,
                  double              x,
@@ -1341,29 +1368,21 @@ start_scroll_deceleration_cb (gpointer user_data)
   return FALSE;
 }
 
-static void
-scroll_controller_scroll_begin (GtkEventControllerScroll *scroll,
-                                GtkScrolledWindow        *scrolled_window)
-{
-  GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (scrolled_window);
-
-  priv->smooth_scroll = TRUE;
-}
-
-static void
-scrolled_window_scroll (GtkScrolledWindow        *scrolled_window,
-                        double                    delta_x,
-                        double                    delta_y,
-                        GtkEventControllerScroll *scroll)
+static gboolean
+scroll_controller_scroll (GtkEventControllerWheel *controller,
+                          double                   delta_x,
+                          double                   delta_y,
+                          GtkScrolledWindow       *scrolled_window)
 {
   GtkScrolledWindowPrivate *priv =
     gtk_scrolled_window_get_instance_private (scrolled_window);
   gboolean shifted;
   GdkModifierType state;
 
-  state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (scroll));
+  state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (controller));
   shifted = (state & GDK_SHIFT_MASK) != 0;
 
+  gtk_scrolled_window_cancel_deceleration (scrolled_window);
   gtk_scrolled_window_invalidate_overshoot (scrolled_window);
 
   if (shifted)
@@ -1407,72 +1426,17 @@ scrolled_window_scroll (GtkScrolledWindow        *scrolled_window,
 
   g_clear_handle_id (&priv->scroll_events_overshoot_id, g_source_remove);
 
-  if (!priv->smooth_scroll &&
-      _gtk_scrolled_window_get_overshoot (scrolled_window, NULL, NULL))
+  if (_gtk_scrolled_window_get_overshoot (scrolled_window, NULL, NULL))
     {
       priv->scroll_events_overshoot_id =
         g_timeout_add (50, start_scroll_deceleration_cb, scrolled_window);
       gdk_source_set_static_name_by_id (priv->scroll_events_overshoot_id,
                                       "[gtk] start_scroll_deceleration_cb");
     }
-}
-
-static gboolean
-scroll_controller_scroll (GtkEventControllerScroll *scroll,
-                          double                    delta_x,
-                          double                    delta_y,
-                          GtkScrolledWindow        *scrolled_window)
-{
-  GtkScrolledWindowPrivate *priv =
-    gtk_scrolled_window_get_instance_private (scrolled_window);
-
-  if (!priv->smooth_scroll)
-    scrolled_window_scroll (scrolled_window, delta_x, delta_y, scroll);
 
   return GDK_EVENT_STOP;
 }
 
-static void
-scroll_controller_scroll_end (GtkEventControllerScroll *scroll,
-                              GtkScrolledWindow        *scrolled_window)
-{
-  GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (scrolled_window);
-
-  priv->smooth_scroll = FALSE;
-}
-
-static void
-scroll_controller_decelerate (GtkEventControllerScroll *scroll,
-                              double                    initial_vel_x,
-                              double                    initial_vel_y,
-                              GtkScrolledWindow        *scrolled_window)
-{
-  double unit_x, unit_y;
-  gboolean shifted;
-  GdkModifierType state;
-
-
-  state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (scroll));
-
-  shifted = (state & GDK_SHIFT_MASK) != 0;
-
-  unit_x = get_scroll_unit (scrolled_window, GTK_ORIENTATION_HORIZONTAL);
-  unit_y = get_scroll_unit (scrolled_window, GTK_ORIENTATION_VERTICAL);
-
-  if (shifted)
-    {
-      gtk_scrolled_window_decelerate (scrolled_window,
-                                      initial_vel_y * unit_x,
-                                      initial_vel_x * unit_y);
-    }
-  else
-    {
-      gtk_scrolled_window_decelerate (scrolled_window,
-                                      initial_vel_x * unit_x,
-                                      initial_vel_y * unit_y);
-    }
-}
-
 static void
 gtk_scrolled_window_update_scrollbar_visibility_flags (GtkScrolledWindow *scrolled_window,
                                                        GtkWidget         *scrollbar)
@@ -2102,23 +2066,9 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
   gtk_css_node_set_state (priv->junction_node, gtk_css_node_get_state (widget_node));
   g_object_unref (priv->junction_node);
 
-  controller = gtk_event_controller_scroll_new (GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES |
-                                                GTK_EVENT_CONTROLLER_SCROLL_KINETIC);
-  g_signal_connect (controller, "scroll-begin",
-                    G_CALLBACK (scroll_controller_scroll_begin), scrolled_window);
+  controller = gtk_event_controller_wheel_new ();
   g_signal_connect (controller, "scroll",
                     G_CALLBACK (scroll_controller_scroll), scrolled_window);
-  g_signal_connect (controller, "scroll-end",
-                    G_CALLBACK (scroll_controller_scroll_end), scrolled_window);
-  gtk_widget_add_controller (widget, controller);
-
-  controller = gtk_event_controller_scroll_new (GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES |
-                                                GTK_EVENT_CONTROLLER_SCROLL_KINETIC);
-  gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
-  g_signal_connect (controller, "scroll",
-                    G_CALLBACK (captured_scroll_cb), scrolled_window);
-  g_signal_connect (controller, "decelerate",
-                    G_CALLBACK (scroll_controller_decelerate), scrolled_window);
   gtk_widget_add_controller (widget, controller);
 
   controller = gtk_event_controller_motion_new ();


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