[gtk+/gestures] textview: Use GtkGestureDrag for text selection/DnD



commit a4ab72134c85c542a175f1f076c5538f67e8ae7d
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu May 8 16:28:49 2014 +0200

    textview: Use GtkGestureDrag for text selection/DnD
    
    remaining code in button press/release, motion notify, and grab
    notify handlers has been shuffled to be managed by this gesture.

 gtk/gtktextview.c |  421 +++++++++++++++++++++++++---------------------------
 1 files changed, 202 insertions(+), 219 deletions(-)
---
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index 08d8fa4..b657bee 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -134,10 +134,8 @@ struct _GtkTextViewPrivate
   guint blink_time;  /* time in msec the cursor has blinked since last user event */
   guint im_spot_idle;
   gchar *im_module;
-  GdkDevice *grab_device;
   GdkDevice *dnd_device;
 
-  gulong selection_drag_handler;
   GtkTextHandle *text_handle;
   GtkWidget *selection_bubble;
   guint selection_bubble_timeout_id;
@@ -192,16 +190,11 @@ struct _GtkTextViewPrivate
   guint first_validate_idle;        /* Idle to revalidate onscreen portion, runs before resize */
   guint incremental_validate_idle;  /* Idle to revalidate offscreen portions, runs after redraw */
 
-  gint pending_place_cursor_button;
-
   GtkTextMark *dnd_mark;
 
   GtkIMContext *im_context;
   GtkWidget *popup_menu;
 
-  gint drag_start_x;
-  gint drag_start_y;
-
   GSList *children;
 
   GtkTextPendingScroll *pending_scroll;
@@ -209,6 +202,7 @@ struct _GtkTextViewPrivate
   GtkPixelCache *pixel_cache;
 
   GtkGesture *multipress_gesture;
+  GtkGesture *drag_gesture;
 
   /* Default style settings */
   gint pixels_above_lines;
@@ -315,6 +309,8 @@ enum
   PROP_POPULATE_ALL
 };
 
+static GQuark quark_text_selection_data = 0;
+
 static void gtk_text_view_finalize             (GObject          *object);
 static void gtk_text_view_set_property         (GObject         *object,
                                                guint            prop_id,
@@ -342,8 +338,6 @@ static void gtk_text_view_unrealize            (GtkWidget        *widget);
 static void gtk_text_view_style_updated        (GtkWidget        *widget);
 static void gtk_text_view_direction_changed    (GtkWidget        *widget,
                                                 GtkTextDirection  previous_direction);
-static void gtk_text_view_grab_notify          (GtkWidget        *widget,
-                                               gboolean         was_grabbed);
 static void gtk_text_view_state_flags_changed  (GtkWidget        *widget,
                                                GtkStateFlags     previous_state);
 
@@ -352,6 +346,14 @@ static void gtk_text_view_multipress_gesture_pressed (GtkGestureMultiPress *gest
                                                       gdouble               x,
                                                       gdouble               y,
                                                       GtkTextView          *text_view);
+static void gtk_text_view_drag_gesture_update        (GtkGestureDrag *gesture,
+                                                      gdouble         offset_x,
+                                                      gdouble         offset_y,
+                                                      GtkTextView    *text_view);
+static void gtk_text_view_drag_gesture_end           (GtkGestureDrag *gesture,
+                                                      gdouble         offset_x,
+                                                      gdouble         offset_y,
+                                                      GtkTextView    *text_view);
 
 static gint gtk_text_view_event                (GtkWidget        *widget,
                                                 GdkEvent         *event);
@@ -359,14 +361,10 @@ static gint gtk_text_view_key_press_event      (GtkWidget        *widget,
                                                 GdkEventKey      *event);
 static gint gtk_text_view_key_release_event    (GtkWidget        *widget,
                                                 GdkEventKey      *event);
-static gint gtk_text_view_button_release_event (GtkWidget        *widget,
-                                                GdkEventButton   *event);
 static gint gtk_text_view_focus_in_event       (GtkWidget        *widget,
                                                 GdkEventFocus    *event);
 static gint gtk_text_view_focus_out_event      (GtkWidget        *widget,
                                                 GdkEventFocus    *event);
-static gint gtk_text_view_motion_event         (GtkWidget        *widget,
-                                                GdkEventMotion   *event);
 static gint gtk_text_view_draw                 (GtkWidget        *widget,
                                                 cairo_t          *cr);
 static void gtk_text_view_draw_focus           (GtkWidget        *widget,
@@ -460,7 +458,9 @@ static void     gtk_text_view_start_selection_drag   (GtkTextView          *text
 static gboolean gtk_text_view_end_selection_drag     (GtkTextView        *text_view);
 static void     gtk_text_view_start_selection_dnd    (GtkTextView        *text_view,
                                                       const GtkTextIter  *iter,
-                                                      GdkEventMotion     *event);
+                                                      const GdkEvent     *event,
+                                                      gint                x,
+                                                      gint                y);
 static void     gtk_text_view_check_cursor_blink     (GtkTextView        *text_view);
 static void     gtk_text_view_pend_cursor_blink      (GtkTextView        *text_view);
 static void     gtk_text_view_stop_cursor_blink      (GtkTextView        *text_view);
@@ -671,7 +671,6 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
   widget_class->unrealize = gtk_text_view_unrealize;
   widget_class->style_updated = gtk_text_view_style_updated;
   widget_class->direction_changed = gtk_text_view_direction_changed;
-  widget_class->grab_notify = gtk_text_view_grab_notify;
   widget_class->state_flags_changed = gtk_text_view_state_flags_changed;
   widget_class->get_preferred_width = gtk_text_view_get_preferred_width;
   widget_class->get_preferred_height = gtk_text_view_get_preferred_height;
@@ -679,10 +678,8 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
   widget_class->event = gtk_text_view_event;
   widget_class->key_press_event = gtk_text_view_key_press_event;
   widget_class->key_release_event = gtk_text_view_key_release_event;
-  widget_class->button_release_event = gtk_text_view_button_release_event;
   widget_class->focus_in_event = gtk_text_view_focus_in_event;
   widget_class->focus_out_event = gtk_text_view_focus_out_event;
-  widget_class->motion_notify_event = gtk_text_view_motion_event;
   widget_class->draw = gtk_text_view_draw;
   widget_class->focus = gtk_text_view_focus;
   widget_class->drag_begin = gtk_text_view_drag_begin;
@@ -1481,6 +1478,9 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
 
   gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_TEXT_VIEW_ACCESSIBLE);
   test_touchscreen = g_getenv ("GTK_TEST_TOUCHSCREEN") != NULL;
+
+  quark_text_selection_data =
+    g_quark_from_static_string ("gtk-text-view-text-selection-data");
 }
 
 static void
@@ -1549,11 +1549,6 @@ gtk_text_view_init (GtkTextView *text_view)
   priv->text_window = text_window_new (GTK_TEXT_WINDOW_TEXT,
                                        widget, 200, 200);
 
-  priv->drag_start_x = -1;
-  priv->drag_start_y = -1;
-
-  priv->pending_place_cursor_button = 0;
-
   /* We handle all our own redrawing */
   gtk_widget_set_redraw_on_allocate (widget, FALSE);
 
@@ -1564,6 +1559,17 @@ gtk_text_view_init (GtkTextView *text_view)
   g_signal_connect (priv->multipress_gesture, "pressed",
                     G_CALLBACK (gtk_text_view_multipress_gesture_pressed),
                     widget);
+
+  priv->drag_gesture = gtk_gesture_drag_new (widget);
+  gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->drag_gesture),
+                                     FALSE);
+  gtk_gesture_attach (priv->drag_gesture, GTK_PHASE_BUBBLE);
+  g_signal_connect (priv->drag_gesture, "drag-update",
+                    G_CALLBACK (gtk_text_view_drag_gesture_update),
+                    widget);
+  g_signal_connect (priv->drag_gesture, "drag-end",
+                    G_CALLBACK (gtk_text_view_drag_gesture_end),
+                    widget);
 }
 
 static void
@@ -3255,6 +3261,9 @@ gtk_text_view_finalize (GObject *object)
   gtk_gesture_detach (priv->multipress_gesture);
   g_object_unref (priv->multipress_gesture);
 
+  gtk_gesture_detach (priv->drag_gesture);
+  g_object_unref (priv->drag_gesture);
+
   if (priv->tabs)
     pango_tab_array_free (priv->tabs);
   
@@ -4545,30 +4554,6 @@ gtk_text_view_unobscure_mouse_cursor (GtkTextView *text_view)
     }
 }
 
-static void
-gtk_text_view_grab_notify (GtkWidget *widget,
-                          gboolean   was_grabbed)
-{
-  GtkTextViewPrivate *priv;
-
-  priv = GTK_TEXT_VIEW (widget)->priv;
-
-  if (priv->grab_device &&
-      gtk_widget_device_is_shadowed (widget, priv->grab_device))
-    {
-      if (priv->drag_start_x >= 0)
-        {
-          priv->drag_start_x = -1;
-          priv->drag_start_y = -1;
-        }
-
-      gtk_text_view_end_selection_drag (GTK_TEXT_VIEW (widget));
-      gtk_text_view_unobscure_mouse_cursor (GTK_TEXT_VIEW (widget));
-      priv->grab_device = NULL;
-    }
-}
-
-
 /*
  * Events
  */
@@ -5150,16 +5135,14 @@ gtk_text_view_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
                   gtk_widget_get_modifier_mask (GTK_WIDGET (text_view),
                                                 GDK_MODIFIER_INTENT_EXTEND_SELECTION)))
               {
-                priv->grab_device = gdk_event_get_device (event);
-                priv->drag_start_x = x;
-                priv->drag_start_y = y;
-                priv->pending_place_cursor_button = button;
-              }
-            else
-              {
-                gtk_text_view_start_selection_drag (text_view, &iter,
-                                                    SELECT_CHARACTERS, event);
+                /* Claim the sequence on the drag gesture, but attach no selection data */
+                gtk_gesture_set_state (priv->drag_gesture,
+                                       GTK_EVENT_SEQUENCE_CLAIMED);
+                break;
               }
+
+            gtk_text_view_start_selection_drag (text_view, &iter,
+                                                SELECT_CHARACTERS, event);
             break;
           }
         case 2:
@@ -5191,71 +5174,6 @@ gtk_text_view_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
     gtk_event_controller_reset (GTK_EVENT_CONTROLLER (gesture));
 }
 
-static gint
-gtk_text_view_button_release_event (GtkWidget *widget, GdkEventButton *event)
-{
-  GtkTextView *text_view;
-  GtkTextViewPrivate *priv;
-  GdkDevice *device;
-
-  text_view = GTK_TEXT_VIEW (widget);
-  priv = text_view->priv;
-  device = gdk_event_get_source_device ((GdkEvent *) event);
-
-  if (event->window != priv->text_window->bin_window)
-    return FALSE;
-
-  if (event->button == GDK_BUTTON_PRIMARY)
-    {
-      if (priv->drag_start_x >= 0)
-        {
-          priv->drag_start_x = -1;
-          priv->drag_start_y = -1;
-        }
-
-      if (gtk_text_view_end_selection_drag (GTK_TEXT_VIEW (widget)))
-       {
-          if (test_touchscreen ||
-              gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN)
-           gtk_text_view_selection_bubble_popup_set (text_view);
-         return TRUE;
-       }
-      else if (priv->pending_place_cursor_button == event->button)
-        {
-          GtkTextHandleMode mode;
-         GtkTextIter iter;
-
-          /* Unselect everything; we clicked inside selection, but
-           * didn't move by the drag threshold, so just clear selection
-           * and place cursor.
-           */
-         gtk_text_layout_get_iter_at_pixel (priv->layout,
-                                            &iter,
-                                            event->x + priv->xoffset,
-                                            event->y + priv->yoffset);
-
-         gtk_text_buffer_place_cursor (get_buffer (text_view), &iter);
-         gtk_text_view_check_cursor_blink (text_view);
-
-          if (priv->text_handle)
-            {
-              if (test_touchscreen || gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN)
-                mode = GTK_TEXT_HANDLE_MODE_CURSOR;
-              else
-                mode = GTK_TEXT_HANDLE_MODE_NONE;
-
-              gtk_text_view_update_handles (text_view, mode);
-            }
-
-          priv->pending_place_cursor_button = 0;
-
-          return FALSE;
-        }
-    }
-
-  return FALSE;
-}
-
 static void
 keymap_direction_changed (GdkKeymap   *keymap,
                          GtkTextView *text_view)
@@ -5337,52 +5255,6 @@ gtk_text_view_focus_out_event (GtkWidget *widget, GdkEventFocus *event)
   return FALSE;
 }
 
-static gint
-gtk_text_view_motion_event (GtkWidget *widget, GdkEventMotion *event)
-{
-  GtkTextView *text_view;
-  GtkTextViewPrivate *priv;
-
-  text_view = GTK_TEXT_VIEW (widget);
-  priv = text_view->priv;
-
-  gtk_text_view_unobscure_mouse_cursor (text_view);
-
-  if (event->window == priv->text_window->bin_window &&
-      priv->drag_start_x >= 0)
-    {
-      gint x = event->x;
-      gint y = event->y;
-
-      gdk_event_request_motions (event);
-
-      if (gtk_drag_check_threshold (widget,
-                                   priv->drag_start_x, 
-                                   priv->drag_start_y,
-                                   x, y))
-        {
-          GtkTextIter iter;
-          gint buffer_x, buffer_y;
-
-          gtk_text_view_window_to_buffer_coords (text_view,
-                                                 GTK_TEXT_WINDOW_TEXT,
-                                                 priv->drag_start_x,
-                                                 priv->drag_start_y,
-                                                 &buffer_x,
-                                                 &buffer_y);
-
-          gtk_text_layout_get_iter_at_pixel (priv->layout,
-                                             &iter,
-                                             buffer_x, buffer_y);
-
-          gtk_text_view_start_selection_dnd (text_view, &iter, event);
-          return TRUE;
-        }
-    }
-
-  return FALSE;
-}
-
 static void
 gtk_text_view_paint (GtkWidget      *widget,
                      cairo_t        *cr)
@@ -6817,6 +6689,37 @@ gtk_text_view_unselect (GtkTextView *text_view)
                              &insert);
 }
 
+static gboolean
+get_iter_from_gesture (GtkTextView *text_view,
+                       GtkTextIter *iter,
+                       gint        *x,
+                       gint        *y)
+{
+  gdouble start_x, start_y, offset_x, offset_y;
+  GtkTextViewPrivate *priv;
+  gint xcoord, ycoord;
+
+  priv = text_view->priv;
+
+  if (!gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (priv->drag_gesture),
+                                         &start_x, &start_y) ||
+      !gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (priv->drag_gesture),
+                                    &offset_x, &offset_y))
+    return FALSE;
+
+  xcoord = start_x + offset_x + priv->xoffset;
+  ycoord = start_y + offset_y + priv->yoffset;
+  gtk_text_layout_get_iter_at_pixel (priv->layout, iter, xcoord, ycoord);
+
+  if (x)
+    *x = xcoord;
+
+  if (y)
+    *y = ycoord;
+
+  return TRUE;
+}
+
 static void
 get_iter_at_pointer (GtkTextView *text_view,
                      GdkDevice   *device,
@@ -6846,16 +6749,14 @@ get_iter_at_pointer (GtkTextView *text_view,
 
 static void
 move_mark_to_pointer_and_scroll (GtkTextView    *text_view,
-                                 const gchar    *mark_name,
-                                 GdkDevice      *device,
-                                 GdkInputSource  source)
+                                 const gchar    *mark_name)
 {
   GtkTextIter newplace;
   GtkTextBuffer *buffer;
   GtkTextMark *mark;
 
   buffer = get_buffer (text_view);
-  get_iter_at_pointer (text_view, device, &newplace, NULL, NULL);
+  get_iter_from_gesture (text_view, &newplace, NULL, NULL);
 
   mark = gtk_text_buffer_get_mark (buffer, mark_name);
 
@@ -7035,42 +6936,73 @@ selection_data_free (SelectionData *data)
   g_free (data);
 }
 
-static gint
-selection_motion_event_handler (GtkTextView    *text_view, 
-                               GdkEventMotion *event, 
-                               SelectionData  *data)
+static void
+gtk_text_view_drag_gesture_update (GtkGestureDrag *gesture,
+                                   gdouble         offset_x,
+                                   gdouble         offset_y,
+                                   GtkTextView    *text_view)
 {
-  GtkTextViewPrivate *priv;
-  GdkInputSource input_source;
+  GdkEventSequence *sequence;
+  gdouble start_x, start_y;
+  gboolean is_touchscreen;
+  const GdkEvent *event;
+  SelectionData *data;
   GdkDevice *device;
 
-  priv = text_view->priv;
-  gdk_event_request_motions (event);
+  data = g_object_get_qdata (G_OBJECT (gesture), quark_text_selection_data);
+  sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
+  event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
+  gtk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
 
-  device = gdk_event_get_source_device ((GdkEvent *) event);
-  input_source = gdk_device_get_source (device);
+  if (!data)
+    {
+      /* If no data is attached, the initial press happened within the current
+       * text selection, check for drag and drop to be initiated.
+       */
+      if (gtk_drag_check_threshold (GTK_WIDGET (text_view), start_x, start_y,
+                                    start_x + offset_x, start_y + offset_y))
+        {
+          GtkTextIter iter;
+          gint buffer_x, buffer_y;
 
-  if (priv->grab_device != event->device)
-    return FALSE;
+          gtk_text_view_window_to_buffer_coords (text_view,
+                                                 GTK_TEXT_WINDOW_TEXT,
+                                                 start_x, start_y,
+                                                 &buffer_x,
+                                                 &buffer_y);
+
+          gtk_text_layout_get_iter_at_pixel (text_view->priv->layout,
+                                             &iter, buffer_x, buffer_y);
+
+          gtk_text_view_start_selection_dnd (text_view, &iter, event,
+                                             start_x, start_y);
+        }
 
-  if (data->granularity == SELECT_CHARACTERS) 
+      return;
+    }
+
+  device = gdk_event_get_source_device (event);
+
+  is_touchscreen = test_touchscreen ||
+                   gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN;
+
+  if (data->granularity == SELECT_CHARACTERS)
     {
-      move_mark_to_pointer_and_scroll (text_view, "insert",
-                                       event->device, input_source);
+      move_mark_to_pointer_and_scroll (text_view, "insert");
     }
-  else 
+  else
     {
       GtkTextIter cursor, start, end;
       GtkTextIter orig_start, orig_end;
       GtkTextBuffer *buffer;
-      
+
       buffer = get_buffer (text_view);
 
       gtk_text_buffer_get_iter_at_mark (buffer, &orig_start, data->orig_start);
       gtk_text_buffer_get_iter_at_mark (buffer, &orig_end, data->orig_end);
 
-      get_iter_at_pointer (text_view, event->device, &cursor, NULL, NULL);
-      
+      get_iter_from_gesture (text_view, &cursor, NULL, NULL);
+
       start = cursor;
       extend_selection (text_view, data->granularity, &start, &end);
 
@@ -7091,19 +7023,86 @@ selection_motion_event_handler (GtkTextView    *text_view,
    */
   if (text_view->priv->scroll_timeout != 0) /* reset on every motion event */
     g_source_remove (text_view->priv->scroll_timeout);
-  
+
   text_view->priv->scroll_timeout =
     gdk_threads_add_timeout (50, selection_scan_timeout, text_view);
   g_source_set_name_by_id (text_view->priv->scroll_timeout, "[gtk+] selection_scan_timeout");
 
-  if (test_touchscreen || input_source == GDK_SOURCE_TOUCHSCREEN)
+  if (is_touchscreen)
     {
       _gtk_text_view_ensure_text_handles (text_view);
       gtk_text_view_update_handles (text_view, GTK_TEXT_HANDLE_MODE_SELECTION);
-      gtk_text_view_show_magnifier (text_view, event->x, event->y);
+      gtk_text_view_show_magnifier (text_view, start_x + offset_x,
+                                    start_y + offset_y);
     }
+}
 
-  return TRUE;
+static void
+gtk_text_view_drag_gesture_end (GtkGestureDrag *gesture,
+                                gdouble         offset_x,
+                                gdouble         offset_y,
+                                GtkTextView    *text_view)
+{
+  GdkEventSequence *sequence;
+  gdouble start_x, start_y;
+  GtkTextViewPrivate *priv;
+  gboolean is_touchscreen;
+  const GdkEvent *event;
+  GdkDevice *device;
+
+  priv = text_view->priv;
+  sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
+  gtk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
+
+  g_object_set_qdata (G_OBJECT (gesture), quark_text_selection_data, NULL);
+  gtk_text_view_unobscure_mouse_cursor (text_view);
+
+  if (priv->scroll_timeout != 0)
+    {
+      g_source_remove (priv->scroll_timeout);
+      priv->scroll_timeout = 0;
+    }
+
+  if (priv->magnifier_popover)
+    gtk_widget_hide (priv->magnifier_popover);
+
+  /* Check whether the drag was cancelled rather than finished */
+  if (!gtk_gesture_handles_sequence (GTK_GESTURE (gesture), sequence))
+    return;
+
+  event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
+  device = gdk_event_get_source_device (event);
+  is_touchscreen = test_touchscreen ||
+    gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN;
+
+  if (is_touchscreen)
+    gtk_text_view_selection_bubble_popup_set (text_view);
+
+  if (!gtk_drag_check_threshold (GTK_WIDGET (text_view), start_x, start_y,
+                                 start_x + offset_x, start_y + offset_y))
+    {
+      GtkTextHandleMode mode = GTK_TEXT_HANDLE_MODE_NONE;
+      GtkTextIter iter;
+
+      /* Unselect everything; we clicked inside selection, but
+       * didn't move by the drag threshold, so just clear selection
+       * and place cursor.
+       */
+      gtk_text_layout_get_iter_at_pixel (priv->layout, &iter,
+                                         start_x + offset_x + priv->xoffset,
+                                         start_y + offset_y + priv->yoffset);
+
+      gtk_text_buffer_place_cursor (get_buffer (text_view), &iter);
+      gtk_text_view_check_cursor_blink (text_view);
+
+      if (priv->text_handle)
+        {
+          if (is_touchscreen)
+            mode = GTK_TEXT_HANDLE_MODE_CURSOR;
+
+          gtk_text_view_update_handles (text_view, mode);
+        }
+    }
 }
 
 static void
@@ -7119,14 +7118,10 @@ gtk_text_view_start_selection_drag (GtkTextView          *text_view,
   SelectionData *data;
   GdkModifierType state;
 
-  if (text_view->priv->selection_drag_handler != 0)
-    return;
-
   priv = text_view->priv;
   data = g_new0 (SelectionData, 1);
   data->granularity = granularity;
 
-  priv->grab_device = gdk_event_get_device (event);
   buffer = get_buffer (text_view);
   
   cursor = *iter;
@@ -7180,11 +7175,11 @@ gtk_text_view_start_selection_drag (GtkTextView          *text_view,
                                                 &orig_end, TRUE);
   gtk_text_view_check_cursor_blink (text_view);
 
-  text_view->priv->selection_drag_handler = g_signal_connect_data (text_view,
-                                                                   "motion-notify-event",
-                                                                   G_CALLBACK 
(selection_motion_event_handler),
-                                                                   data,
-                                                                   (GClosureNotify) selection_data_free, 0);
+  g_object_set_qdata_full (G_OBJECT (priv->drag_gesture),
+                           quark_text_selection_data,
+                           data, (GDestroyNotify) selection_data_free);
+  gtk_gesture_set_state (priv->drag_gesture,
+                         GTK_EVENT_SEQUENCE_CLAIMED);
 }
 
 /* returns whether we were really dragging */
@@ -7195,23 +7190,15 @@ gtk_text_view_end_selection_drag (GtkTextView *text_view)
 
   priv = text_view->priv;
 
-  if (!priv->grab_device)
-    return FALSE;
-
-  if (priv->selection_drag_handler == 0)
+  if (!gtk_gesture_is_active (priv->drag_gesture))
     return FALSE;
 
-  g_signal_handler_disconnect (text_view, priv->selection_drag_handler);
-  priv->selection_drag_handler = 0;
-
   if (priv->scroll_timeout != 0)
     {
       g_source_remove (priv->scroll_timeout);
       priv->scroll_timeout = 0;
     }
 
-  priv->grab_device = NULL;
-
   if (priv->magnifier_popover)
     gtk_widget_hide (priv->magnifier_popover);
 
@@ -7551,7 +7538,9 @@ drag_begin_cb (GtkWidget      *widget,
 static void
 gtk_text_view_start_selection_dnd (GtkTextView       *text_view,
                                    const GtkTextIter *iter,
-                                   GdkEventMotion    *event)
+                                   const GdkEvent    *event,
+                                   gint               x,
+                                   gint               y)
 {
   GtkTargetList *target_list;
 
@@ -7561,13 +7550,7 @@ gtk_text_view_start_selection_dnd (GtkTextView       *text_view,
                     G_CALLBACK (drag_begin_cb), NULL);
   gtk_drag_begin_with_coordinates (GTK_WIDGET (text_view), target_list,
                                    GDK_ACTION_COPY | GDK_ACTION_MOVE,
-                                   1, (GdkEvent*)event,
-                                   text_view->priv->drag_start_x,
-                                   text_view->priv->drag_start_y);
-
-  text_view->priv->drag_start_x = -1;
-  text_view->priv->drag_start_y = -1;
-  text_view->priv->pending_place_cursor_button = 0;
+                                   1, (GdkEvent*) event, x, y);
 }
 
 static void


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