[gtk+/gestures: 51/173] dnd: Use GtkGestureDrag to initiate DnD



commit aaea3822c8ed0131040e36bbf2c76257520c7ac5
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Mar 28 23:23:38 2014 +0100

    dnd: Use GtkGestureDrag to initiate DnD
    
    This gesture is used by gtk_drag_source_set() to determine
    whether dragging moved past the threshold. The gesture events
    are handled via the usual ::event callbacks, so we don't mess
    up with callers expecting that to happen in a signal handler.
    
    If the sequence gets claimed somewhere else in the event widget
    stack, the DnD gesture will be cancelled.

 gtk/gtkdnd.c |  102 +++++++++++++++++++++++++---------------------------------
 1 files changed, 44 insertions(+), 58 deletions(-)
---
diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c
index 277b6aa..db211f9 100644
--- a/gtk/gtkdnd.c
+++ b/gtk/gtkdnd.c
@@ -90,6 +90,7 @@ struct _GtkDragSourceSite
   GdkDragAction      actions;            /* Possible actions */
 
   GtkIconHelper     *icon_helper;
+  GtkGesture        *drag_gesture;
 
   /* Stored button press information to detect drag beginning */
   gint               state;
@@ -180,7 +181,7 @@ enum {
 };
 
 /* Forward declarations */
-static void          gtk_drag_get_event_actions (GdkEvent        *event, 
+static void          gtk_drag_get_event_actions (const GdkEvent  *event,
                                                 gint             button,
                                                 GdkDragAction    actions,
                                                 GdkDragAction   *suggested_action,
@@ -265,7 +266,7 @@ static void gtk_drag_update                    (GtkDragSourceInfo *info,
                                                GdkScreen         *screen,
                                                gint               x_root,
                                                gint               y_root,
-                                               GdkEvent          *event);
+                                               const GdkEvent    *event);
 static gboolean gtk_drag_motion_cb             (GtkWidget         *widget, 
                                                GdkEventMotion    *event, 
                                                gpointer           data);
@@ -696,8 +697,8 @@ gtk_drag_get_event_time (GdkEvent *event)
 }
 
 static void
-gtk_drag_get_event_actions (GdkEvent *event, 
-                           gint button, 
+gtk_drag_get_event_actions (const GdkEvent *event,
+                           gint button,
                            GdkDragAction  actions,
                            GdkDragAction *suggested_action,
                            GdkDragAction *possible_actions)
@@ -2472,7 +2473,7 @@ gtk_drag_begin_internal (GtkWidget         *widget,
                         GtkTargetList     *target_list,
                         GdkDragAction      actions,
                         gint               button,
-                        GdkEvent          *event,
+                        const GdkEvent    *event,
                          int                x,
                          int                y)
 {
@@ -2797,7 +2798,11 @@ gtk_drag_source_set (GtkWidget            *widget,
     {
       site = g_slice_new0 (GtkDragSourceSite);
       site->icon_helper = _gtk_icon_helper_new ();
-      
+      site->drag_gesture = gtk_gesture_drag_new (widget);
+      gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (site->drag_gesture),
+                                         FALSE);
+      gtk_widget_add_gesture (widget, site->drag_gesture, GTK_PHASE_NONE);
+
       g_signal_connect (widget, "button-press-event",
                        G_CALLBACK (gtk_drag_source_event_cb),
                        site);
@@ -2807,7 +2812,6 @@ gtk_drag_source_set (GtkWidget            *widget,
       g_signal_connect (widget, "motion-notify-event",
                        G_CALLBACK (gtk_drag_source_event_cb),
                        site);
-      
       g_object_set_data_full (G_OBJECT (widget),
                              I_("gtk-site-data"), 
                              site, gtk_drag_source_site_destroy);
@@ -2838,8 +2842,9 @@ gtk_drag_source_unset (GtkWidget *widget)
   if (site)
     {
       g_signal_handlers_disconnect_by_func (widget,
-                                           gtk_drag_source_event_cb,
-                                           site);
+                                            gtk_drag_source_event_cb,
+                                            site);
+      gtk_widget_remove_gesture (widget, site->drag_gesture);
       g_object_set_data (G_OBJECT (widget), I_("gtk-site-data"), NULL);
     }
 }
@@ -3899,58 +3904,38 @@ gtk_drag_source_event_cb (GtkWidget      *widget,
                          GdkEvent       *event,
                          gpointer        data)
 {
-  GtkDragSourceSite *site;
-  gboolean retval = FALSE;
-  site = (GtkDragSourceSite *)data;
+  gdouble start_x, start_y, offset_x, offset_y;
+  GtkDragSourceSite *site = data;
 
-  switch (event->type)
-    {
-    case GDK_BUTTON_PRESS:
-      if ((GDK_BUTTON1_MASK << (event->button.button - 1)) & site->start_button_mask)
-       {
-         site->state |= (GDK_BUTTON1_MASK << (event->button.button - 1));
-         site->x = event->button.x;
-         site->y = event->button.y;
-       }
-      break;
-      
-    case GDK_BUTTON_RELEASE:
-      if ((GDK_BUTTON1_MASK << (event->button.button - 1)) & site->start_button_mask)
-       site->state &= ~(GDK_BUTTON1_MASK << (event->button.button - 1));
-      break;
-      
-    case GDK_MOTION_NOTIFY:
-      if (site->state & event->motion.state & site->start_button_mask)
-       {
-         /* FIXME: This is really broken and can leave us
-          * with a stuck grab
-          */
-         int i;
-         for (i=1; i<6; i++)
-           {
-             if (site->state & event->motion.state & 
-                 GDK_BUTTON1_MASK << (i - 1))
-               break;
-           }
+  gtk_event_controller_handle_event (GTK_EVENT_CONTROLLER (site->drag_gesture), event);
 
-         if (gtk_drag_check_threshold (widget, site->x, site->y,
-                                       event->motion.x, event->motion.y))
-           {
-             site->state = 0;
-             gtk_drag_begin_internal (widget, site, site->target_list,
-                                      site->actions, i, event,
-                                       site->x, site->y);
+  if (gtk_gesture_is_recognized (site->drag_gesture))
+    {
+      gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (site->drag_gesture),
+                                        &start_x, &start_y);
+      gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (site->drag_gesture),
+                                   &offset_x, &offset_y);
 
-             retval = TRUE;
-           }
-       }
-      break;
-      
-    default:                   /* hit for 2/3BUTTON_PRESS */
-      break;
+      if (gtk_drag_check_threshold (widget, start_x, start_y,
+                                    start_x + offset_x, start_y + offset_y))
+        {
+          GdkEventSequence *sequence;
+          const GdkEvent *event;
+          guint button;
+
+          sequence = gtk_gesture_get_last_updated_sequence (site->drag_gesture);
+          event = gtk_gesture_get_last_event (GTK_GESTURE (site->drag_gesture), sequence);
+          button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (site->drag_gesture));
+
+          gtk_event_controller_reset (GTK_EVENT_CONTROLLER (site->drag_gesture));
+          gtk_drag_begin_internal (widget, site, site->target_list,
+                                   site->actions, button, event,
+                                   start_x, start_y);
+          return TRUE;
+        }
     }
-  
-  return retval;
+
+  return FALSE;
 }
 
 static void 
@@ -3962,6 +3947,7 @@ gtk_drag_source_site_destroy (gpointer data)
     gtk_target_list_unref (site->target_list);
 
   g_clear_object (&site->icon_helper);
+  g_clear_object (&site->drag_gesture);
   g_slice_free (GtkDragSourceSite, site);
 }
 
@@ -4223,7 +4209,7 @@ gtk_drag_update (GtkDragSourceInfo *info,
                 GdkScreen         *screen,
                 gint               x_root,
                 gint               y_root,
-                GdkEvent          *event)
+                const GdkEvent    *event)
 {
   info->cur_screen = screen;
   info->cur_x = x_root;


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