[gtk+] wayland: add gdk_event_is_scroll_stop_event()



commit 48aa1bb08f89a1f3f8f290da771f183cdd5061d8
Author: Peter Hutterer <peter hutterer who-t net>
Date:   Wed Oct 21 10:14:40 2015 +1000

    wayland: add gdk_event_is_scroll_stop_event()
    
    And use it to handle kinetic scrolling in the GtkScrolledWindow.
    
    However, dropping the delta check causes the X11-based kinetic
    scroll to break since we don't have the stop event here. Correct handling of
    xf86-input-libinput-based scroll events is still being discussed.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=756729

 docs/reference/gdk/gdk3-sections.txt |    1 +
 gdk/gdkevents.c                      |   23 +++++++++++++++++++++++
 gdk/gdkevents.h                      |    4 ++++
 gdk/gdkwindow.c                      |    1 +
 gdk/wayland/gdkdevice-wayland.c      |   21 +++++++++++++++++++--
 gtk/gtkscrolledwindow.c              |    2 +-
 6 files changed, 49 insertions(+), 3 deletions(-)
---
diff --git a/docs/reference/gdk/gdk3-sections.txt b/docs/reference/gdk/gdk3-sections.txt
index 7b1b9f7..cfcce26 100644
--- a/docs/reference/gdk/gdk3-sections.txt
+++ b/docs/reference/gdk/gdk3-sections.txt
@@ -859,6 +859,7 @@ gdk_event_get_keyval
 gdk_event_get_root_coords
 gdk_event_get_scroll_direction
 gdk_event_get_scroll_deltas
+gdk_event_is_scroll_stop_event
 gdk_event_get_state
 gdk_event_get_time
 gdk_event_get_window
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index 9ed4317..83f8ab1 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -562,6 +562,7 @@ gdk_event_new (GdkEventType type)
       new_event->scroll.y_root = 0.;
       new_event->scroll.delta_x = 0.;
       new_event->scroll.delta_y = 0.;
+      new_event->scroll.is_stop = FALSE;
       break;
     case GDK_ENTER_NOTIFY:
     case GDK_LEAVE_NOTIFY:
@@ -1419,6 +1420,28 @@ gdk_event_get_scroll_deltas (const GdkEvent *event,
 }
 
 /**
+ * gdk_event_is_scroll_stop_event
+ * @event: a #GdkEvent
+ *
+ * Check whether a scroll event is a stop scroll event. Scroll sequences
+ * with smooth scroll information may provide a stop scroll event once the
+ * interaction with the device finishes, e.g. by lifting a finger. This
+ * stop scroll event is the signal that a widget may trigger kinetic
+ * scrolling based on the current velocity.
+ *
+ * Stop scroll events always have a a delta of 0/0.
+ *
+ * Returns: %TRUE if the event is a scroll stop event
+ *
+ * Since: 3.20
+ */
+gboolean
+gdk_event_is_scroll_stop_event (const GdkEvent *event)
+{
+  return event->scroll.is_stop;
+}
+
+/**
  * gdk_event_get_axis:
  * @event: a #GdkEvent
  * @axis_use: the axis use to look for
diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h
index ca019b7..a502b27 100644
--- a/gdk/gdkevents.h
+++ b/gdk/gdkevents.h
@@ -824,6 +824,7 @@ struct _GdkEventScroll
   gdouble x_root, y_root;
   gdouble delta_x;
   gdouble delta_y;
+  guint is_stop : 1;
 };
 
 /**
@@ -1377,6 +1378,9 @@ gboolean  gdk_event_get_scroll_deltas   (const GdkEvent *event,
                                          gdouble         *delta_x,
                                          gdouble         *delta_y);
 
+GDK_AVAILABLE_IN_3_20
+gboolean  gdk_event_is_scroll_stop_event (const GdkEvent *event);
+
 GDK_AVAILABLE_IN_ALL
 gboolean  gdk_event_get_axis            (const GdkEvent  *event,
                                          GdkAxisUse       axis_use,
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 57ffa64..6995db9 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -9328,6 +9328,7 @@ proxy_button_event (GdkEvent *source_event,
       event->scroll.device = source_event->scroll.device;
       event->scroll.delta_x = source_event->scroll.delta_x;
       event->scroll.delta_y = source_event->scroll.delta_y;
+      event->scroll.is_stop = source_event->scroll.is_stop;
       gdk_event_set_source_device (event, source_device);
       return TRUE;
 
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index 50d07bd..1afb9b0 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -62,6 +62,7 @@ struct _GdkWaylandPointerFrameData
   /* Specific to the scroll event */
   gdouble delta_x, delta_y;
   int32_t discrete_x, discrete_y;
+  gint8 is_scroll_stop;
 };
 
 struct _GdkWaylandSeat
@@ -972,7 +973,8 @@ flush_discrete_scroll_event (GdkWaylandSeat     *seat,
 static void
 flush_smooth_scroll_event (GdkWaylandSeat *seat,
                            gdouble         delta_x,
-                           gdouble         delta_y)
+                           gdouble         delta_y,
+                           gboolean        is_stop)
 {
   GdkEvent *event;
 
@@ -980,6 +982,7 @@ flush_smooth_scroll_event (GdkWaylandSeat *seat,
   event->scroll.direction = GDK_SCROLL_SMOOTH;
   event->scroll.delta_x = delta_x;
   event->scroll.delta_y = delta_y;
+  event->scroll.is_stop = is_stop;
 
   _gdk_wayland_display_deliver_event (seat->display, event);
 }
@@ -988,6 +991,8 @@ static void
 flush_scroll_event (GdkWaylandSeat             *seat,
                     GdkWaylandPointerFrameData *pointer_frame)
 {
+  gboolean is_stop = FALSE;
+
   if (pointer_frame->discrete_x || pointer_frame->discrete_y)
     {
       GdkScrollDirection direction;
@@ -1004,14 +1009,24 @@ flush_scroll_event (GdkWaylandSeat             *seat,
       flush_discrete_scroll_event (seat, direction);
     }
 
+  /* Axes can stop independently, if we stop on one axis but have a
+   * delta on the other, we don't count it as a stop event.
+   */
+  if (pointer_frame->is_scroll_stop &&
+      pointer_frame->delta_x == 0 &&
+      pointer_frame->delta_y == 0)
+    is_stop = TRUE;
+
   flush_smooth_scroll_event (seat,
                              pointer_frame->delta_x,
-                             pointer_frame->delta_y);
+                             pointer_frame->delta_y,
+                             is_stop);
 
   pointer_frame->delta_x = 0;
   pointer_frame->delta_y = 0;
   pointer_frame->discrete_x = 0;
   pointer_frame->discrete_y = 0;
+  pointer_frame->is_scroll_stop = FALSE;
 }
 
 static void
@@ -1369,6 +1384,8 @@ pointer_handle_axis_stop (void              *data,
       g_return_if_reached ();
     }
 
+  pointer_frame->is_scroll_stop = TRUE;
+
   GDK_NOTE (EVENTS,
             g_message ("axis stop, seat %p", seat));
 }
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index b27028c..0df1a62 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -3321,7 +3321,7 @@ gtk_scrolled_window_scroll_event (GtkWidget      *widget,
        * after scrolling finished, start kinetic scrolling when this
        * happens.
        */
-      if (delta_y == 0 && delta_x == 0)
+      if (gdk_event_is_scroll_stop_event ((GdkEvent *) event))
         {
           handled = TRUE;
           start_deceleration = TRUE;


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