Signed-off-by: Jindrich Makovicka <makovick@gmail.com>
---
ui/gtk-clipboard.c | 52 +++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 39 insertions(+), 13 deletions(-)
diff --git a/ui/gtk-clipboard.c b/ui/gtk-clipboard.c
index 65d89ec601..691784697d 100644
--- a/ui/gtk-clipboard.c
+++ b/ui/gtk-clipboard.c
@@ -136,26 +136,54 @@ static void gd_clipboard_notify(Notifier *notifier, void *data)
}
}
+static void
+gd_clipboard_request_text_received_callback(GtkClipboard *clipboard,
+ const gchar *text,
+ gpointer data)
+{
+ QemuClipboardInfo *info = (QemuClipboardInfo *)data;
+
+ if (text) {
+ qemu_clipboard_set_data(info->owner, info, QEMU_CLIPBOARD_TYPE_TEXT,
+ strlen(text), text, true);
+ }
+ qemu_clipboard_info_unref(info);
+}
+
static void gd_clipboard_request(QemuClipboardInfo *info,
QemuClipboardType type)
{
GtkDisplayState *gd = container_of(info->owner, GtkDisplayState, cbpeer);
- char *text;
switch (type) {
case QEMU_CLIPBOARD_TYPE_TEXT:
- text = gtk_clipboard_wait_for_text(gd->gtkcb[info->selection]);
- if (text) {
- qemu_clipboard_set_data(&gd->cbpeer, info, type,
- strlen(text), text, true);
- g_free(text);
- }
+ qemu_clipboard_info_ref(info);
+ gtk_clipboard_request_text(gd->gtkcb[info->selection],
+ gd_clipboard_request_text_received_callback,
+ info);
break;
default:
break;
}
}
+static void gd_clipboard_owner_change_contents_received_callback(
+ GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ gpointer data)
+{
+ QemuClipboardInfo *info = (QemuClipboardInfo *)data;
+
+ if (selection_data) {
+ if (gtk_selection_data_targets_include_text(selection_data)) {
+ info->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
+ }
+ }
+
+ qemu_clipboard_update(info);
+ qemu_clipboard_info_unref(info);
+}
+
static void gd_owner_change(GtkClipboard *clipboard,
GdkEvent *event,
gpointer data)
@@ -173,12 +201,10 @@ static void gd_owner_change(GtkClipboard *clipboard,
switch (event->owner_change.reason) {
case GDK_OWNER_CHANGE_NEW_OWNER:
info = qemu_clipboard_info_new(&gd->cbpeer, s);
- if (gtk_clipboard_wait_is_text_available(clipboard)) {
- info->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
- }
-
- qemu_clipboard_update(info);
- qemu_clipboard_info_unref(info);
+ gtk_clipboard_request_contents(
+ clipboard, gdk_atom_intern_static_string("TARGETS"),
+ gd_clipboard_owner_change_contents_received_callback,
+ info);
break;
default:
qemu_clipboard_peer_release(&gd->cbpeer, s);
--
2.53.0
Hi Jindřich
On Sun, Apr 26, 2026 at 11:53 AM Jindřich Makovička <makovick@gmail.com> wrote:
>
Could you review & compare with the previous lost patch ("[PATCH v4]
ui/gtk-clipboard: async owner_change clipboard_request")
https://patchew.org/QEMU/20231206142243.510068-1-edmund.raile@proton.me/
thanks
> Signed-off-by: Jindrich Makovicka <makovick@gmail.com>
> ---
> ui/gtk-clipboard.c | 52 +++++++++++++++++++++++++++++++++++++++-------------
> 1 file changed, 39 insertions(+), 13 deletions(-)
>
> diff --git a/ui/gtk-clipboard.c b/ui/gtk-clipboard.c
> index 65d89ec601..691784697d 100644
> --- a/ui/gtk-clipboard.c
> +++ b/ui/gtk-clipboard.c
> @@ -136,26 +136,54 @@ static void gd_clipboard_notify(Notifier *notifier, void *data)
> }
> }
>
> +static void
> +gd_clipboard_request_text_received_callback(GtkClipboard *clipboard,
> + const gchar *text,
> + gpointer data)
> +{
> + QemuClipboardInfo *info = (QemuClipboardInfo *)data;
> +
> + if (text) {
> + qemu_clipboard_set_data(info->owner, info, QEMU_CLIPBOARD_TYPE_TEXT,
> + strlen(text), text, true);
> + }
> + qemu_clipboard_info_unref(info);
> +}
> +
> static void gd_clipboard_request(QemuClipboardInfo *info,
> QemuClipboardType type)
> {
> GtkDisplayState *gd = container_of(info->owner, GtkDisplayState, cbpeer);
> - char *text;
>
> switch (type) {
> case QEMU_CLIPBOARD_TYPE_TEXT:
> - text = gtk_clipboard_wait_for_text(gd->gtkcb[info->selection]);
> - if (text) {
> - qemu_clipboard_set_data(&gd->cbpeer, info, type,
> - strlen(text), text, true);
> - g_free(text);
> - }
> + qemu_clipboard_info_ref(info);
> + gtk_clipboard_request_text(gd->gtkcb[info->selection],
> + gd_clipboard_request_text_received_callback,
> + info);
> break;
> default:
> break;
> }
> }
>
> +static void gd_clipboard_owner_change_contents_received_callback(
> + GtkClipboard *clipboard,
> + GtkSelectionData *selection_data,
> + gpointer data)
> +{
> + QemuClipboardInfo *info = (QemuClipboardInfo *)data;
> +
> + if (selection_data) {
> + if (gtk_selection_data_targets_include_text(selection_data)) {
> + info->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
> + }
> + }
> +
> + qemu_clipboard_update(info);
> + qemu_clipboard_info_unref(info);
> +}
> +
> static void gd_owner_change(GtkClipboard *clipboard,
> GdkEvent *event,
> gpointer data)
> @@ -173,12 +201,10 @@ static void gd_owner_change(GtkClipboard *clipboard,
> switch (event->owner_change.reason) {
> case GDK_OWNER_CHANGE_NEW_OWNER:
> info = qemu_clipboard_info_new(&gd->cbpeer, s);
> - if (gtk_clipboard_wait_is_text_available(clipboard)) {
> - info->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
> - }
> -
> - qemu_clipboard_update(info);
> - qemu_clipboard_info_unref(info);
> + gtk_clipboard_request_contents(
> + clipboard, gdk_atom_intern_static_string("TARGETS"),
> + gd_clipboard_owner_change_contents_received_callback,
> + info);
> break;
> default:
> qemu_clipboard_peer_release(&gd->cbpeer, s);
>
> --
> 2.53.0
>
>
Hi
On Sun, Apr 26, 2026 at 11:52 AM Jindřich Makovička <makovick@gmail.com> wrote:
>
> Signed-off-by: Jindrich Makovicka <makovick@gmail.com>
> ---
> ui/gtk-clipboard.c | 52 +++++++++++++++++++++++++++++++++++++++-------------
> 1 file changed, 39 insertions(+), 13 deletions(-)
>
> diff --git a/ui/gtk-clipboard.c b/ui/gtk-clipboard.c
> index 65d89ec601..691784697d 100644
> --- a/ui/gtk-clipboard.c
> +++ b/ui/gtk-clipboard.c
> @@ -136,26 +136,54 @@ static void gd_clipboard_notify(Notifier *notifier, void *data)
> }
> }
>
> +static void
> +gd_clipboard_request_text_received_callback(GtkClipboard *clipboard,
> + const gchar *text,
> + gpointer data)
> +{
> + QemuClipboardInfo *info = (QemuClipboardInfo *)data;
> +
> + if (text) {
> + qemu_clipboard_set_data(info->owner, info, QEMU_CLIPBOARD_TYPE_TEXT,
> + strlen(text), text, true);
> + }
> + qemu_clipboard_info_unref(info);
> +}
> +
> static void gd_clipboard_request(QemuClipboardInfo *info,
> QemuClipboardType type)
> {
> GtkDisplayState *gd = container_of(info->owner, GtkDisplayState, cbpeer);
> - char *text;
>
> switch (type) {
> case QEMU_CLIPBOARD_TYPE_TEXT:
> - text = gtk_clipboard_wait_for_text(gd->gtkcb[info->selection]);
> - if (text) {
> - qemu_clipboard_set_data(&gd->cbpeer, info, type,
> - strlen(text), text, true);
> - g_free(text);
> - }
> + qemu_clipboard_info_ref(info);
> + gtk_clipboard_request_text(gd->gtkcb[info->selection],
> + gd_clipboard_request_text_received_callback,
> + info);
> break;
> default:
> break;
> }
> }
>
> +static void gd_clipboard_owner_change_contents_received_callback(
> + GtkClipboard *clipboard,
> + GtkSelectionData *selection_data,
> + gpointer data)
> +{
> + QemuClipboardInfo *info = (QemuClipboardInfo *)data;
> +
> + if (selection_data) {
> + if (gtk_selection_data_targets_include_text(selection_data)) {
> + info->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
> + }
> + }
> +
> + qemu_clipboard_update(info);
> + qemu_clipboard_info_unref(info);
> +}
> +
> static void gd_owner_change(GtkClipboard *clipboard,
> GdkEvent *event,
> gpointer data)
> @@ -173,12 +201,10 @@ static void gd_owner_change(GtkClipboard *clipboard,
> switch (event->owner_change.reason) {
> case GDK_OWNER_CHANGE_NEW_OWNER:
> info = qemu_clipboard_info_new(&gd->cbpeer, s);
> - if (gtk_clipboard_wait_is_text_available(clipboard)) {
> - info->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
> - }
> -
> - qemu_clipboard_update(info);
> - qemu_clipboard_info_unref(info);
> + gtk_clipboard_request_contents(
> + clipboard, gdk_atom_intern_static_string("TARGETS"),
> + gd_clipboard_owner_change_contents_received_callback,
> + info);
could you use gtk_clipboard_request_targets instead?
lgtm otherwise
> break;
> default:
> qemu_clipboard_peer_release(&gd->cbpeer, s);
>
> --
> 2.53.0
>
© 2016 - 2026 Red Hat, Inc.