[gtk+/multitouch-for-3.4: 16/89] scrolledwindow: Don't use p-a-h for the "let event go through" timeout



commit be74ffe6f04ce0e2c9f752475f069ab72264cfc7
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sun Nov 6 16:22:09 2011 +0100

    scrolledwindow: Don't use p-a-h for the "let event go through" timeout
    
    Just use a timeout there, the press-and-hold feedback is undesirable
    here.

 gtk/gtkscrolledwindow.c |   90 +++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 75 insertions(+), 15 deletions(-)
---
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 4b6941e..2f6b162 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -131,6 +131,7 @@
 #define FRAME_INTERVAL(fps) (1000. / fps)
 #define INTERPOLATION_DURATION 250
 #define INTERPOLATION_DURATION_OVERSHOOT(overshoot) (overshoot > 0.0 ? INTERPOLATION_DURATION : 10)
+#define RELEASE_EVENT_TIMEOUT 1000
 
 typedef struct
 {
@@ -174,7 +175,7 @@ struct _GtkScrolledWindowPrivate
   guint                  button_press_id;
   guint                  motion_notify_id;
   guint                  button_release_id;
-  guint                  press_and_hold_id;
+  guint                  release_timeout_id;
   MotionEventList        motion_events;
   GtkTimeline           *deceleration_timeline;
   gdouble                dx;
@@ -1151,10 +1152,10 @@ gtk_scrolled_window_set_kinetic_scrolling (GtkScrolledWindow *scrolled_window,
           g_signal_handler_disconnect (scrolled_window, priv->button_release_id);
           priv->button_release_id = 0;
         }
-      if (priv->press_and_hold_id > 0)
+      if (priv->release_timeout_id)
         {
-          g_signal_handler_disconnect (scrolled_window, priv->press_and_hold_id);
-          priv->press_and_hold_id = 0;
+          g_source_remove (priv->release_timeout_id);
+          priv->release_timeout_id = 0;
         }
       motion_event_list_clear (&priv->motion_events);
       if (priv->event_window)
@@ -1227,10 +1228,10 @@ gtk_scrolled_window_destroy (GtkWidget *widget)
       g_signal_handler_disconnect (widget, priv->button_release_id);
       priv->button_release_id = 0;
     }
-  if (priv->press_and_hold_id > 0)
+  if (priv->release_timeout_id)
     {
-      g_signal_handler_disconnect (widget, priv->press_and_hold_id);
-      priv->press_and_hold_id = 0;
+      g_source_remove (priv->release_timeout_id);
+      priv->release_timeout_id = 0;
     }
 
   if (priv->button_press_event)
@@ -2739,6 +2740,49 @@ gtk_scrolled_window_start_deceleration (GtkScrolledWindow *scrolled_window,
 }
 
 static gboolean
+gtk_scrolled_window_release_captured_events (GtkScrolledWindow *scrolled_window)
+{
+  GtkScrolledWindowPrivate *priv = scrolled_window->priv;
+  GdkDevice *device;
+
+  /* Cancel the scrolling and send the button press
+   * event to the child widget
+   */
+  if (!priv->button_press_event)
+    return FALSE;
+
+  device = gdk_event_get_device (priv->button_press_event);
+  gdk_device_ungrab (device, GDK_CURRENT_TIME);
+  gtk_device_grab_remove (GTK_WIDGET (scrolled_window), device);
+
+  if (priv->motion_notify_id > 0)
+    {
+      g_signal_handler_disconnect (scrolled_window, priv->motion_notify_id);
+      priv->motion_notify_id = 0;
+    }
+  if (priv->button_release_id > 0)
+    {
+      g_signal_handler_disconnect (scrolled_window, priv->button_release_id);
+      priv->button_release_id = 0;
+    }
+
+  /* We are going to synthesize the button press event so that
+   * it can be handled by child widget, but we don't want to
+   * handle it, so block both button-press and and press-and-hold
+   * during this button press
+   */
+  g_signal_handler_block (scrolled_window, priv->button_press_id);
+
+  gtk_main_do_event (priv->button_press_event);
+
+  g_signal_handler_unblock (scrolled_window, priv->button_press_id);
+  gdk_event_free (priv->button_press_event);
+  priv->button_press_event = NULL;
+
+  return FALSE;
+}
+
+static gboolean
 gtk_scrolled_window_button_release_event (GtkWidget *widget,
                                           GdkEvent  *_event)
 {
@@ -2772,6 +2816,11 @@ gtk_scrolled_window_button_release_event (GtkWidget *widget,
       g_signal_handler_disconnect (widget, priv->button_release_id);
       priv->button_release_id = 0;
     }
+  if (priv->release_timeout_id)
+    {
+      g_source_remove (priv->release_timeout_id);
+      priv->release_timeout_id = 0;
+    }
 
   if (!priv->in_drag)
     {
@@ -2845,7 +2894,14 @@ gtk_scrolled_window_motion_notify_event (GtkWidget *widget,
     {
       motion = motion_event_list_first (&priv->motion_events);
       if (gtk_drag_check_threshold (widget, motion->x, motion->y, event->x_root, event->y_root))
-        priv->in_drag = TRUE;
+        {
+          if (priv->release_timeout_id)
+            {
+              g_source_remove (priv->release_timeout_id);
+              priv->release_timeout_id = 0;
+            }
+          priv->in_drag = TRUE;
+        }
       else
         return FALSE;
     }
@@ -2883,7 +2939,7 @@ gtk_scrolled_window_motion_notify_event (GtkWidget *widget,
   motion->y = event->y_root;
   g_get_current_time (&motion->time);
 
-  return TRUE;
+  return FALSE;
 }
 
 static gboolean
@@ -2958,13 +3014,17 @@ gtk_scrolled_window_button_press_event (GtkWidget *widget,
     }
 
   priv->motion_notify_id =
-          g_signal_connect (widget, "captured-event",
-                            G_CALLBACK (gtk_scrolled_window_motion_notify_event),
-                            NULL);
+    g_signal_connect (widget, "captured-event",
+                      G_CALLBACK (gtk_scrolled_window_motion_notify_event),
+                      NULL);
   priv->button_release_id =
-          g_signal_connect (widget, "captured-event",
-                            G_CALLBACK (gtk_scrolled_window_button_release_event),
-                            NULL);
+    g_signal_connect (widget, "captured-event",
+                      G_CALLBACK (gtk_scrolled_window_button_release_event),
+                      NULL);
+  priv->release_timeout_id =
+    gdk_threads_add_timeout (RELEASE_EVENT_TIMEOUT,
+                             (GSourceFunc) gtk_scrolled_window_release_captured_events,
+                             scrolled_window);
 
   /* If there's a zero drag threshold, start the drag immediately */
   g_object_get (gtk_widget_get_settings (widget),



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