Ticket #4060: 0001-scrolledwindow-Stop-scrolling-when-a-second-touch-po.patch

File 0001-scrolledwindow-Stop-scrolling-when-a-second-touch-po.patch, 4.9 KB (added by garnacho, 9 years ago)

updated patch

  • gtk/gtkscrolledwindow.c

    From 4a3c6e5d2cc755b4d94694d7b8c0e3790a0ea259 Mon Sep 17 00:00:00 2001
    From: Carlos Garnacho <carlos@lanedo.com>
    Date: Fri, 2 Nov 2012 17:45:24 +0100
    Subject: [PATCH] scrolledwindow: Stop scrolling when a second touch point is
     detected
    
    If the scrolled window is receiving touch events, it is likely
    that the contained child wants to handle multiple touches, so
    if a second touch arrives when scrolling didn't start yet, release
    the captured event and give up on the scroll attempt.
    ---
     gtk/gtkscrolledwindow.c | 63 +++++++++++++++++++++++++++++++++++++++++--------
     1 file changed, 53 insertions(+), 10 deletions(-)
    
    diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
    index 7929863..08a286c 100644
    a b struct _GtkScrolledWindowPrivate 
    153153
    154154  /* Kinetic scrolling */
    155155  GdkEvent              *button_press_event;
     156  GdkEventSequence      *sequence;
    156157  GdkWindow             *overshoot_window;
    157158  GdkDevice             *drag_device;
    158159  guint                  kinetic_scrolling         : 1;
    static void gtk_scrolled_window_size_allocate (GtkWidget *widge 
    228229                                                        GtkAllocation     *allocation);
    229230static gboolean gtk_scrolled_window_scroll_event       (GtkWidget         *widget,
    230231                                                        GdkEventScroll    *event);
     232static gboolean gtk_scrolled_window_check_stop_event_capture (GtkWidget         *widget,
     233                                                              GdkEvent          *event);
    231234static gboolean gtk_scrolled_window_captured_event     (GtkWidget         *widget,
    232235                                                        GdkEvent          *event);
    233236static gboolean gtk_scrolled_window_focus              (GtkWidget         *widget,
    gtk_scrolled_window_captured_motion_notify (GtkWidget *widget, 
    27462749
    27472750  priv->last_button_event_valid = FALSE;
    27482751
    2749   if (priv->button_press_event)
    2750     {
    2751       gdk_event_free (priv->button_press_event);
    2752       priv->button_press_event = NULL;
    2753     }
    2754 
    27552752  _gtk_scrolled_window_get_overshoot (scrolled_window,
    27562753                                      &old_overshoot_x, &old_overshoot_y);
    27572754
    gtk_scrolled_window_captured_button_press (GtkWidget *widget, 
    28792876    return FALSE;
    28802877}
    28812878
     2879
     2880static gboolean
     2881gtk_scrolled_window_check_stop_event_capture (GtkWidget *widget,
     2882                                              GdkEvent  *event)
     2883{
     2884  GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
     2885  GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW (widget)->priv;
     2886
     2887  if (priv->in_drag)
     2888    return FALSE;
     2889
     2890  if (priv->drag_device)
     2891    {
     2892      gtk_device_grab_remove (widget, priv->drag_device);
     2893      gdk_device_ungrab (priv->drag_device,
     2894                         gtk_get_current_event_time ());
     2895      priv->drag_device = NULL;
     2896
     2897      gtk_scrolled_window_release_captured_event (scrolled_window);
     2898    }
     2899
     2900  priv->in_drag = FALSE;
     2901  priv->sequence = NULL;
     2902
     2903  return TRUE;
     2904}
     2905
     2906
    28822907static gboolean
    28832908gtk_scrolled_window_captured_event (GtkWidget *widget,
    28842909                                    GdkEvent  *event)
    28852910{
    28862911  gboolean retval = FALSE;
    28872912  GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW (widget)->priv;
     2913  GdkEventSequence *sequence;
    28882914
    28892915  if (gdk_window_get_window_type (event->any.window) == GDK_WINDOW_TEMP)
    28902916    return FALSE;
    28912917
     2918  sequence = gdk_event_get_event_sequence (event);
     2919
    28922920  switch (event->type)
    28932921    {
    28942922    case GDK_TOUCH_BEGIN:
    28952923    case GDK_BUTTON_PRESS:
    2896       retval = gtk_scrolled_window_captured_button_press (widget, event);
     2924      /* Let children handle multiple touches. If scrolling didn't start yet,
     2925       * and a second touch arrives, give up on scrolling and release the event.
     2926       */
     2927      if (event->type == GDK_TOUCH_BEGIN && priv->sequence != sequence &&
     2928          gtk_scrolled_window_check_stop_event_capture (widget, event))
     2929        retval = FALSE;
     2930      else if (priv->sequence == sequence)
     2931        {
     2932          retval = gtk_scrolled_window_captured_button_press (widget, event);
     2933
     2934          if (!priv->sequence)
     2935            priv->sequence = sequence;
     2936        }
    28972937      break;
    28982938    case GDK_TOUCH_END:
    28992939    case GDK_BUTTON_RELEASE:
    2900       if (priv->drag_device)
    2901         retval = gtk_scrolled_window_captured_button_release (widget, event);
     2940      if (priv->drag_device && priv->sequence == sequence)
     2941        {
     2942          retval = gtk_scrolled_window_captured_button_release (widget, event);
     2943          priv->sequence = NULL;
     2944        }
    29022945      else
    29032946        priv->last_button_event_valid = FALSE;
    29042947      break;
    29052948    case GDK_TOUCH_UPDATE:
    29062949    case GDK_MOTION_NOTIFY:
    2907       if (priv->drag_device)
     2950      if (priv->drag_device && priv->sequence == sequence)
    29082951        retval = gtk_scrolled_window_captured_motion_notify (widget, event);
    29092952      break;
    29102953    case GDK_LEAVE_NOTIFY: