[gtk/gtk-3-24: 1/2] wayland: Ensure clipboard handling doesn't lock up in certain corner cases
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gtk-3-24: 1/2] wayland: Ensure clipboard handling doesn't lock up in certain corner cases
- Date: Mon, 6 Dec 2021 11:16:55 +0000 (UTC)
commit e23b4dd21b41329a804fadf6a89c79be17dffcdf
Author: msizanoen1 <qtmlabs protonmail com>
Date: Fri Oct 8 07:08:24 2021 +0700
wayland: Ensure clipboard handling doesn't lock up in certain corner cases
When a selection request fails to be converted to the requested format in the
GTK layers, the wayland backend would miss bumping the machinery to handle
further pending selection requests. Fix this by reacting to
GdkDisplay::send_selection_notify with target=GDK_NONE (i.e. a failed
conversion as hinted from the upper layers) to do that.
This ensures the clipboard handling doesn't lock up in the following
scenarios:
- GTK returned with a mismatching type to the one requested
- GTK fails to convert to the requested type
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4340
gdk/wayland/gdkselection-wayland.c | 48 +++++++++++++++++++++++---------------
1 file changed, 29 insertions(+), 19 deletions(-)
---
diff --git a/gdk/wayland/gdkselection-wayland.c b/gdk/wayland/gdkselection-wayland.c
index f85f595616..d7f3332fa2 100644
--- a/gdk/wayland/gdkselection-wayland.c
+++ b/gdk/wayland/gdkselection-wayland.c
@@ -100,7 +100,7 @@ struct _GdkWaylandSelection
/* Source-side data */
GPtrArray *stored_selections; /* Array of StoredSelection */
- GdkAtom current_request_selection;
+ StoredSelection *current_request_selection;
GArray *source_targets;
GdkAtom requested_target;
@@ -858,7 +858,12 @@ gdk_wayland_selection_reset_selection (GdkWaylandSelection *wayland_selection,
stored_selection = g_ptr_array_index (wayland_selection->stored_selections, i);
if (stored_selection->selection_atom == selection)
- g_ptr_array_remove_index_fast (wayland_selection->stored_selections, i);
+ {
+ if (wayland_selection->current_request_selection == stored_selection)
+ wayland_selection->current_request_selection = NULL;
+
+ g_ptr_array_remove_index_fast (wayland_selection->stored_selections, i);
+ }
else
i++;
}
@@ -877,21 +882,10 @@ gdk_wayland_selection_store (GdkWindow *window,
if (type == gdk_atom_intern_static_string ("NULL"))
return;
- if (selection->current_request_selection == GDK_NONE)
+ if (!selection->current_request_selection)
return;
- stored_selection =
- gdk_wayland_selection_find_stored_selection (selection, window,
- selection->current_request_selection,
- type);
-
- if (!stored_selection)
- {
- stored_selection = stored_selection_new (selection, window,
- selection->current_request_selection,
- type);
- g_ptr_array_add (selection->stored_selections, stored_selection);
- }
+ stored_selection = selection->current_request_selection;
if ((mode == GDK_PROP_MODE_PREPEND ||
mode == GDK_PROP_MODE_REPLACE) &&
@@ -915,7 +909,7 @@ gdk_wayland_selection_store (GdkWindow *window,
}
/* Handle the next GDK_SELECTION_REQUEST / store, if any */
- selection->current_request_selection = GDK_NONE;
+ selection->current_request_selection = NULL;
gdk_wayland_selection_handle_next_request (selection);
}
@@ -979,7 +973,7 @@ gdk_wayland_selection_handle_next_request (GdkWaylandSelection *wayland_selectio
gdk_wayland_selection_emit_request (stored_selection->source,
stored_selection->selection_atom,
stored_selection->type);
- wayland_selection->current_request_selection = stored_selection->selection_atom;
+ wayland_selection->current_request_selection = stored_selection;
break;
}
}
@@ -1023,7 +1017,7 @@ gdk_wayland_selection_request_target (GdkWaylandSelection *wayland_selection,
write_data = async_write_data_new (stored_selection, fd);
- if (wayland_selection->current_request_selection == GDK_NONE)
+ if (!wayland_selection->current_request_selection)
gdk_wayland_selection_handle_next_request (wayland_selection);
return TRUE;
@@ -1435,13 +1429,29 @@ _gdk_wayland_display_set_selection_owner (GdkDisplay *display,
}
void
-_gdk_wayland_display_send_selection_notify (GdkDisplay *dispay,
+_gdk_wayland_display_send_selection_notify (GdkDisplay *display,
GdkWindow *requestor,
GdkAtom selection,
GdkAtom target,
GdkAtom property,
guint32 time)
{
+ GdkWaylandSelection *wayland_selection;
+
+ if (property != GDK_NONE)
+ return;
+
+ wayland_selection = gdk_wayland_display_get_selection (display);
+
+ if (!wayland_selection->current_request_selection)
+ return;
+
+ g_ptr_array_remove_fast (wayland_selection->stored_selections,
+ wayland_selection->current_request_selection);
+
+ /* Handle the next GDK_SELECTION_REQUEST / store, if any */
+ wayland_selection->current_request_selection = NULL;
+ gdk_wayland_selection_handle_next_request (wayland_selection);
}
gint
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]