From 9b8c175f234ce4eb071199ab29137adb6ef6c9b0 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 6 Sep 2020 11:48:10 -0400 Subject: [PATCH 1/2] textview: Fix dnd When we start a dnd of the selection in the drag-update handler, set the gesture state to denied. Otherwise, we get more drag-update signals, and things get really confused, leading to no dnd and sadness. --- gtk/gtktextview.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index 5b0715befd..dc8d3c9682 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -7188,11 +7188,11 @@ selection_data_free (SelectionData *data) static gboolean drag_gesture_get_text_surface_coords (GtkGestureDrag *gesture, - GtkTextView *text_view, - int *start_x, - int *start_y, - int *x, - int *y) + GtkTextView *text_view, + int *start_x, + int *start_y, + int *x, + int *y) { double sx, sy, ox, oy; @@ -7262,6 +7262,10 @@ gtk_text_view_drag_gesture_update (GtkGestureDrag *gesture, gtk_text_view_start_selection_dnd (text_view, &iter, event, start_x, start_y); + + /* Deny the gesture so we don't get further updates */ + gtk_gesture_set_state (text_view->priv->drag_gesture, + GTK_EVENT_SEQUENCE_DENIED); return; } else @@ -7275,6 +7279,8 @@ gtk_text_view_drag_gesture_update (GtkGestureDrag *gesture, return; } + g_assert (data != NULL); + /* Text selection */ if (data->granularity == SELECT_CHARACTERS) { @@ -7782,6 +7788,14 @@ dnd_finished_cb (GdkDrag *drag, self->priv->drag = NULL; } +static void +dnd_cancel_cb (GdkDrag *drag, + GdkDragCancelReason reason, + GtkTextView *self) +{ + self->priv->drag = NULL; +} + static void gtk_text_view_start_selection_dnd (GtkTextView *text_view, const GtkTextIter *iter, @@ -7808,9 +7822,11 @@ gtk_text_view_start_selection_dnd (GtkTextView *text_view, surface = gdk_event_get_surface (event); device = gdk_event_get_device (event); drag = gdk_drag_begin (surface, device, content, actions, x, y); + g_object_unref (content); g_signal_connect (drag, "dnd-finished", G_CALLBACK (dnd_finished_cb), text_view); + g_signal_connect (drag, "cancel", G_CALLBACK (dnd_cancel_cb), text_view); if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) { From adc9d91e0e4493d7cc955ff5c8a2b79e3e831007 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 6 Sep 2020 12:19:44 -0400 Subject: [PATCH 2/2] text: Stop drag updates when a dnd starts This prevents the selection from changing underneath us, messing up move dnd operations. --- gtk/gtktext.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gtk/gtktext.c b/gtk/gtktext.c index 6af06f39fe..7e2f2308eb 100644 --- a/gtk/gtktext.c +++ b/gtk/gtktext.c @@ -2910,6 +2910,16 @@ dnd_finished_cb (GdkDrag *drag, priv->drag = NULL; } +static void +dnd_cancel_cb (GdkDrag *drag, + GdkDragCancelReason reason, + GtkText *self) +{ + GtkTextPrivate *priv = gtk_text_get_instance_private (self); + + priv->drag = NULL; +} + static void gtk_text_drag_gesture_update (GtkGestureDrag *gesture, double offset_x, @@ -2973,6 +2983,7 @@ gtk_text_drag_gesture_update (GtkGestureDrag *gesture, g_object_unref (content); g_signal_connect (drag, "dnd-finished", G_CALLBACK (dnd_finished_cb), self); + g_signal_connect (drag, "cancel", G_CALLBACK (dnd_cancel_cb), self); paintable = gtk_text_util_create_drag_icon (widget, text, -1); gtk_drag_icon_set_from_paintable (drag, paintable, ranges[0], 0); @@ -2986,6 +2997,9 @@ gtk_text_drag_gesture_update (GtkGestureDrag *gesture, g_free (text); priv->in_drag = FALSE; + + /* Deny the gesture so we don't get further updates */ + gtk_gesture_set_state (priv->drag_gesture, GTK_EVENT_SEQUENCE_DENIED); } } else