|
|
07d9f9 |
From 9b575d2eefbbbc5a308648f99fcc0be5e1f03d87 Mon Sep 17 00:00:00 2001
|
|
|
07d9f9 |
From: Christophe Fergeau <cfergeau@redhat.com>
|
|
|
07d9f9 |
Date: Wed, 10 Aug 2016 12:04:30 +0200
|
|
|
07d9f9 |
Subject: [PATCH 21/23] clipboard: Use gtk_clipboard_request_text for text data
|
|
|
07d9f9 |
|
|
|
07d9f9 |
Currently, when the agent asks us for VD_AGENT_CLIPBOARD_UTF8_TEXT data,
|
|
|
07d9f9 |
spice-gtk looks up for the first X11 target which would provide it with
|
|
|
07d9f9 |
UTF8_TEXT data, and uses that for the clipboard request. This means we
|
|
|
07d9f9 |
will use UTF8_STRING as the target for gtk_clipboard_request_contents().
|
|
|
07d9f9 |
|
|
|
07d9f9 |
However, some applications who can copy and paste text do not
|
|
|
07d9f9 |
necessarily support the UTF8_STRING target. This is the case for Motif
|
|
|
07d9f9 |
applications which support the STRING target however. It turns out gtk+
|
|
|
07d9f9 |
also provides a gtk_clipboard_request_text() method which will try
|
|
|
07d9f9 |
several targets (UTF8_TEXT, COMPOUND_TEXT, TEXT), and will ensure the
|
|
|
07d9f9 |
returned string is UTF-8, so we can use that when the agent asks us for
|
|
|
07d9f9 |
some text data.
|
|
|
07d9f9 |
|
|
|
07d9f9 |
This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1348624
|
|
|
07d9f9 |
|
|
|
07d9f9 |
(cherry picked from commit 7b0de6217670e0f668aff2949fba174ed3cc0b50)
|
|
|
07d9f9 |
---
|
|
|
07d9f9 |
src/spice-gtk-session.c | 67 ++++++++++++++++++++++++++++++++++++++-----------
|
|
|
07d9f9 |
1 file changed, 52 insertions(+), 15 deletions(-)
|
|
|
07d9f9 |
|
|
|
07d9f9 |
diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c
|
|
|
07d9f9 |
index 6b1bcf6..3ab1465 100644
|
|
|
07d9f9 |
--- a/src/spice-gtk-session.c
|
|
|
07d9f9 |
+++ b/src/spice-gtk-session.c
|
|
|
07d9f9 |
@@ -926,6 +926,40 @@ static char *fixup_clipboard_text(SpiceGtkSession *self, const char *text, int *
|
|
|
07d9f9 |
return conv;
|
|
|
07d9f9 |
}
|
|
|
07d9f9 |
|
|
|
07d9f9 |
+static void clipboard_received_text_cb(GtkClipboard *clipboard,
|
|
|
07d9f9 |
+ const gchar *text,
|
|
|
07d9f9 |
+ gpointer user_data)
|
|
|
07d9f9 |
+{
|
|
|
07d9f9 |
+ WeakRef *weakref = user_data;
|
|
|
07d9f9 |
+ SpiceGtkSession *self = (SpiceGtkSession*)weakref->object;
|
|
|
07d9f9 |
+ char *conv = NULL;
|
|
|
07d9f9 |
+ int len = 0;
|
|
|
07d9f9 |
+ int selection;
|
|
|
07d9f9 |
+
|
|
|
07d9f9 |
+ weak_unref(weakref);
|
|
|
07d9f9 |
+
|
|
|
07d9f9 |
+ if (self == NULL)
|
|
|
07d9f9 |
+ return;
|
|
|
07d9f9 |
+
|
|
|
07d9f9 |
+ g_return_if_fail(SPICE_IS_GTK_SESSION(self));
|
|
|
07d9f9 |
+
|
|
|
07d9f9 |
+ selection = get_selection_from_clipboard(self->priv, clipboard);
|
|
|
07d9f9 |
+ g_return_if_fail(selection != -1);
|
|
|
07d9f9 |
+
|
|
|
07d9f9 |
+ len = strlen(text);
|
|
|
07d9f9 |
+ if (!check_clipboard_size_limits(self, len)) {
|
|
|
07d9f9 |
+ return;
|
|
|
07d9f9 |
+ }
|
|
|
07d9f9 |
+
|
|
|
07d9f9 |
+ /* gtk+ internal utf8 newline is always LF, even on windows */
|
|
|
07d9f9 |
+ conv = fixup_clipboard_text(self, text, &len;;
|
|
|
07d9f9 |
+
|
|
|
07d9f9 |
+ spice_main_clipboard_selection_notify(self->priv->main, selection,
|
|
|
07d9f9 |
+ VD_AGENT_CLIPBOARD_UTF8_TEXT,
|
|
|
07d9f9 |
+ (guchar *)(conv ?: text), len);
|
|
|
07d9f9 |
+ g_free(conv);
|
|
|
07d9f9 |
+}
|
|
|
07d9f9 |
+
|
|
|
07d9f9 |
static void clipboard_received_cb(GtkClipboard *clipboard,
|
|
|
07d9f9 |
GtkSelectionData *selection_data,
|
|
|
07d9f9 |
gpointer user_data)
|
|
|
07d9f9 |
@@ -971,16 +1005,14 @@ static void clipboard_received_cb(GtkClipboard *clipboard,
|
|
|
07d9f9 |
}
|
|
|
07d9f9 |
|
|
|
07d9f9 |
const guchar *data = gtk_selection_data_get_data(selection_data);
|
|
|
07d9f9 |
- gpointer conv = NULL;
|
|
|
07d9f9 |
|
|
|
07d9f9 |
- /* gtk+ internal utf8 newline is always LF, even on windows */
|
|
|
07d9f9 |
- if (type == VD_AGENT_CLIPBOARD_UTF8_TEXT) {
|
|
|
07d9f9 |
- conv = fixup_clipboard_text(self, (gchar *)data, &len;;
|
|
|
07d9f9 |
- }
|
|
|
07d9f9 |
+ /* text should be handled through clipboard_received_text_cb(), not
|
|
|
07d9f9 |
+ * clipboard_received_cb().
|
|
|
07d9f9 |
+ */
|
|
|
07d9f9 |
+ g_warn_if_fail(type != VD_AGENT_CLIPBOARD_UTF8_TEXT);
|
|
|
07d9f9 |
|
|
|
07d9f9 |
spice_main_clipboard_selection_notify(s->main, selection, type,
|
|
|
07d9f9 |
- conv ?: data, len);
|
|
|
07d9f9 |
- g_free(conv);
|
|
|
07d9f9 |
+ data, len);
|
|
|
07d9f9 |
}
|
|
|
07d9f9 |
|
|
|
07d9f9 |
static gboolean clipboard_request(SpiceMainChannel *main, guint selection,
|
|
|
07d9f9 |
@@ -1003,16 +1035,21 @@ static gboolean clipboard_request(SpiceMainChannel *main, guint selection,
|
|
|
07d9f9 |
cb = get_clipboard_from_selection(s, selection);
|
|
|
07d9f9 |
g_return_val_if_fail(cb != NULL, FALSE);
|
|
|
07d9f9 |
|
|
|
07d9f9 |
- for (m = 0; m < SPICE_N_ELEMENTS(atom2agent); m++) {
|
|
|
07d9f9 |
- if (atom2agent[m].vdagent == type)
|
|
|
07d9f9 |
- break;
|
|
|
07d9f9 |
- }
|
|
|
07d9f9 |
+ if (type == VD_AGENT_CLIPBOARD_UTF8_TEXT) {
|
|
|
07d9f9 |
+ gtk_clipboard_request_text(cb, clipboard_received_text_cb,
|
|
|
07d9f9 |
+ weak_ref(G_OBJECT(self)));
|
|
|
07d9f9 |
+ } else {
|
|
|
07d9f9 |
+ for (m = 0; m < SPICE_N_ELEMENTS(atom2agent); m++) {
|
|
|
07d9f9 |
+ if (atom2agent[m].vdagent == type)
|
|
|
07d9f9 |
+ break;
|
|
|
07d9f9 |
+ }
|
|
|
07d9f9 |
|
|
|
07d9f9 |
- g_return_val_if_fail(m < SPICE_N_ELEMENTS(atom2agent), FALSE);
|
|
|
07d9f9 |
+ g_return_val_if_fail(m < SPICE_N_ELEMENTS(atom2agent), FALSE);
|
|
|
07d9f9 |
|
|
|
07d9f9 |
- atom = gdk_atom_intern_static_string(atom2agent[m].xatom);
|
|
|
07d9f9 |
- gtk_clipboard_request_contents(cb, atom, clipboard_received_cb,
|
|
|
07d9f9 |
- weak_ref(G_OBJECT(self)));
|
|
|
07d9f9 |
+ atom = gdk_atom_intern_static_string(atom2agent[m].xatom);
|
|
|
07d9f9 |
+ gtk_clipboard_request_contents(cb, atom, clipboard_received_cb,
|
|
|
07d9f9 |
+ weak_ref(G_OBJECT(self)));
|
|
|
07d9f9 |
+ }
|
|
|
07d9f9 |
|
|
|
07d9f9 |
return TRUE;
|
|
|
07d9f9 |
}
|
|
|
07d9f9 |
--
|
|
|
07d9f9 |
2.10.0
|
|
|
07d9f9 |
|