parent
63bb706314
commit
1872b01cf1
@ -0,0 +1,50 @@
|
||||
From 51594105bc59f6197e2b176b6c132a3ac8a156c0 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ant=C3=B3nio=20Fernandes?= <antoniof@gnome.org>
|
||||
Date: Fri, 16 Jul 2021 22:47:40 +0100
|
||||
Subject: [PATCH] window-slot-dnd: Fix data retrieval failure path
|
||||
|
||||
When data retrieval fails, ::drag-data-received is emitted with a
|
||||
selection of negative length.
|
||||
|
||||
We have been treating this case as invalid data, but we never actually
|
||||
call gdk_drag_finish() which is mandatory after a drop.
|
||||
|
||||
Instead, reset drag_info->have_data to FALSE in this case, and let
|
||||
slot_proxy_handle_drop() handle the rest.
|
||||
---
|
||||
src/nautilus-window-slot-dnd.c | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/nautilus-window-slot-dnd.c b/src/nautilus-window-slot-dnd.c
|
||||
index 9509d2c97..ec0134e46 100644
|
||||
--- a/src/nautilus-window-slot-dnd.c
|
||||
+++ b/src/nautilus-window-slot-dnd.c
|
||||
@@ -472,17 +472,21 @@ slot_proxy_drag_data_received (GtkWidget *widget,
|
||||
drag_info = user_data;
|
||||
|
||||
g_assert (!drag_info->have_data);
|
||||
-
|
||||
- drag_info->have_data = TRUE;
|
||||
- drag_info->info = info;
|
||||
drag_info->waiting_for_data = FALSE;
|
||||
|
||||
if (gtk_selection_data_get_length (data) < 0)
|
||||
{
|
||||
- drag_info->have_valid_data = FALSE;
|
||||
+ /* Data retrieval failed. */
|
||||
+ if (drag_info->drop_occurred)
|
||||
+ {
|
||||
+ gtk_drag_finish (context, FALSE, FALSE, time);
|
||||
+ }
|
||||
return;
|
||||
}
|
||||
|
||||
+ drag_info->have_data = TRUE;
|
||||
+ drag_info->info = info;
|
||||
+
|
||||
if (info == NAUTILUS_ICON_DND_GNOME_ICON_LIST)
|
||||
{
|
||||
drag_info->data.selection_list = nautilus_drag_build_selection_list (data);
|
||||
--
|
||||
2.41.0
|
||||
|
@ -0,0 +1,65 @@
|
||||
From 9f36eaa6f4e7757b7cdf41a54cfc9f03eaa0ce89 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ant=C3=B3nio=20Fernandes?= <antoniof@gnome.org>
|
||||
Date: Fri, 16 Jul 2021 23:25:22 +0100
|
||||
Subject: [PATCH] window-slot-dnd: Ignore data not received on hover
|
||||
|
||||
Sometimes, after having called gtk_drag_get_data() on ::drag-motion, we
|
||||
only get the data after ::drag-leave.
|
||||
|
||||
This is fine if the ::drag-leave is followed by ::drag-drop. Otherwise,
|
||||
as ::drag-leave is responsible for cleanup, data arriving afterwards is
|
||||
leaking into the next time content is dragged hover the widget, even if
|
||||
the dragged content is no longer the same.
|
||||
|
||||
Instead, keep track of the hover status and don't save data that's no
|
||||
longer relevant.
|
||||
---
|
||||
src/nautilus-window-slot-dnd.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/src/nautilus-window-slot-dnd.c b/src/nautilus-window-slot-dnd.c
|
||||
index ec0134e46..772a8bb88 100644
|
||||
--- a/src/nautilus-window-slot-dnd.c
|
||||
+++ b/src/nautilus-window-slot-dnd.c
|
||||
@@ -36,6 +36,7 @@ typedef struct
|
||||
gboolean have_data;
|
||||
gboolean have_valid_data;
|
||||
|
||||
+ gboolean is_hover;
|
||||
gboolean drop_occurred;
|
||||
|
||||
unsigned int info;
|
||||
@@ -170,6 +171,8 @@ slot_proxy_drag_motion (GtkWidget *widget,
|
||||
|
||||
drag_info = user_data;
|
||||
|
||||
+ drag_info->is_hover = TRUE;
|
||||
+
|
||||
action = 0;
|
||||
valid_text_drag = FALSE;
|
||||
valid_xds_drag = FALSE;
|
||||
@@ -335,6 +338,7 @@ slot_proxy_drag_leave (GtkWidget *widget,
|
||||
|
||||
drag_info = user_data;
|
||||
|
||||
+ drag_info->is_hover = FALSE;
|
||||
gtk_drag_unhighlight (widget);
|
||||
drag_info_clear (drag_info);
|
||||
}
|
||||
@@ -474,6 +478,13 @@ slot_proxy_drag_data_received (GtkWidget *widget,
|
||||
g_assert (!drag_info->have_data);
|
||||
drag_info->waiting_for_data = FALSE;
|
||||
|
||||
+ if (!drag_info->is_hover && !drag_info->drop_occurred)
|
||||
+ {
|
||||
+ /* Ignore data arriving after ::drag-leave, except if followed by
|
||||
+ * ::drag-drop. */
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (gtk_selection_data_get_length (data) < 0)
|
||||
{
|
||||
/* Data retrieval failed. */
|
||||
--
|
||||
2.41.0
|
||||
|
@ -0,0 +1,76 @@
|
||||
From 095d88295e6a7a5fefdcb58e1483ae3926b8cb1c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ant=C3=B3nio=20Fernandes?= <antoniof@gnome.org>
|
||||
Date: Fri, 16 Jul 2021 22:32:41 +0100
|
||||
Subject: [PATCH] window-slot-dnd: Stop queueing data requests
|
||||
|
||||
Each time ::drag-motion is emitted, we call gtk_drag_get_data() if we
|
||||
don't have data yet.
|
||||
|
||||
If the drag source doesn't provide the data right away, we can end up
|
||||
calling gtk_drag_get_data() multiple times. Later, when the data is
|
||||
retrieved, we get multiple ::drag-data-received emissions.
|
||||
|
||||
Not only is this wasteful, it also breaks an assertion, causing crashes.
|
||||
|
||||
Instead, make sure gtk_drag_get_data() is called only once.
|
||||
|
||||
Fixes https://gitlab.gnome.org/GNOME/nautilus/-/issues/1535
|
||||
---
|
||||
src/nautilus-window-slot-dnd.c | 13 ++++++++++---
|
||||
1 file changed, 10 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/nautilus-window-slot-dnd.c b/src/nautilus-window-slot-dnd.c
|
||||
index 96c5d9cc8..9509d2c97 100644
|
||||
--- a/src/nautilus-window-slot-dnd.c
|
||||
+++ b/src/nautilus-window-slot-dnd.c
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
+ gboolean waiting_for_data;
|
||||
gboolean have_data;
|
||||
gboolean have_valid_data;
|
||||
|
||||
@@ -181,7 +182,7 @@ slot_proxy_drag_motion (GtkWidget *widget,
|
||||
window = gtk_widget_get_toplevel (widget);
|
||||
g_assert (NAUTILUS_IS_WINDOW (window));
|
||||
|
||||
- if (!drag_info->have_data)
|
||||
+ if (!drag_info->have_data && !drag_info->waiting_for_data)
|
||||
{
|
||||
target = gtk_drag_dest_find_target (widget, context, NULL);
|
||||
|
||||
@@ -190,6 +191,7 @@ slot_proxy_drag_motion (GtkWidget *widget,
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ drag_info->waiting_for_data = TRUE;
|
||||
gtk_drag_get_data (widget, context, target, time);
|
||||
}
|
||||
|
||||
@@ -353,8 +355,12 @@ slot_proxy_drag_drop (GtkWidget *widget,
|
||||
|
||||
drag_info->drop_occurred = TRUE;
|
||||
|
||||
- target = gtk_drag_dest_find_target (widget, context, NULL);
|
||||
- gtk_drag_get_data (widget, context, target, time);
|
||||
+ if (!drag_info->waiting_for_data)
|
||||
+ {
|
||||
+ target = gtk_drag_dest_find_target (widget, context, NULL);
|
||||
+ drag_info->waiting_for_data = TRUE;
|
||||
+ gtk_drag_get_data (widget, context, target, time);
|
||||
+ }
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -469,6 +475,7 @@ slot_proxy_drag_data_received (GtkWidget *widget,
|
||||
|
||||
drag_info->have_data = TRUE;
|
||||
drag_info->info = info;
|
||||
+ drag_info->waiting_for_data = FALSE;
|
||||
|
||||
if (gtk_selection_data_get_length (data) < 0)
|
||||
{
|
||||
--
|
||||
2.41.0
|
||||
|
Loading…
Reference in new issue