ui/gtk: Use non-blocking clipboard retrieval
Signed-off-by: Jindrich Makovicka <makovick@gmail.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-ID: <20260427-gtk-clipboard-v5-1-6968feb31a5d@gmail.com>
Jindřich Makovička committed
Apr 27, 2026 at 22:06 UTC
9a007326e83f50185a4d2f1461b380897de0836a
1 file changed
+40
-13
ui/gtk-clipboard.c
+40
-13
@@ -136,26 +136,55 @@ static void gd_clipboard_notify(Notifier *notifier, void *data)
136
}
137
}
138
139
+static void
140
+gd_clipboard_request_text_received_callback(GtkClipboard *clipboard,
141
+ const gchar *text,
142
+ gpointer data)
143
+{
144
+ QemuClipboardInfo *info = (QemuClipboardInfo *)data;
145
+
146
+ if (text) {
147
+ qemu_clipboard_set_data(info->owner, info, QEMU_CLIPBOARD_TYPE_TEXT,
148
+ strlen(text), text, true);
149
+ }
150
+ qemu_clipboard_info_unref(info);
151
+}
152
+
153
static void gd_clipboard_request(QemuClipboardInfo *info,
154
QemuClipboardType type)
155
{
156
GtkDisplayState *gd = container_of(info->owner, GtkDisplayState, cbpeer);
143
- char *text;
157
158
switch (type) {
159
case QEMU_CLIPBOARD_TYPE_TEXT:
147
- text = gtk_clipboard_wait_for_text(gd->gtkcb[info->selection]);
148
- if (text) {
149
- qemu_clipboard_set_data(&gd->cbpeer, info, type,
150
- strlen(text), text, true);
151
- g_free(text);
152
- }
160
+ qemu_clipboard_info_ref(info);
161
+ gtk_clipboard_request_text(gd->gtkcb[info->selection],
162
+ gd_clipboard_request_text_received_callback,
163
+ info);
164
break;
165
default:
166
break;
167
}
168
}
169
170
+static void gd_clipboard_owner_change_targets_received_callback(
171
+ GtkClipboard *clipboard,
172
+ GdkAtom *targets,
173
+ gint n_targets,
174
+ gpointer data)
175
+{
176
+ QemuClipboardInfo *info = (QemuClipboardInfo *)data;
177
+
178
+ if (n_targets) {
179
+ if (gtk_targets_include_text(targets, n_targets)) {
180
+ info->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
181
+ }
182
+ }
183
+
184
+ qemu_clipboard_update(info);
185
+ qemu_clipboard_info_unref(info);
186
+}
187
+
188
static void gd_owner_change(GtkClipboard *clipboard,
189
GdkEvent *event,
190
gpointer data)
@@ -173,12 +202,10 @@ static void gd_owner_change(GtkClipboard *clipboard,
202
switch (event->owner_change.reason) {
203
case GDK_OWNER_CHANGE_NEW_OWNER:
204
info = qemu_clipboard_info_new(&gd->cbpeer, s);
176
- if (gtk_clipboard_wait_is_text_available(clipboard)) {
177
- info->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
178
- }
179
-
180
- qemu_clipboard_update(info);
181
- qemu_clipboard_info_unref(info);
205
+ gtk_clipboard_request_targets(
206
+ clipboard,
207
+ gd_clipboard_owner_change_targets_received_callback,
208
+ info);
209
break;
210
default:
211
qemu_clipboard_peer_release(&gd->cbpeer, s);