Backport clipboard-race patches for #1755038
This commit is contained in:
parent
9b912f4c8f
commit
56f7953ad2
77
0001-clipboard-do-not-release-between-client-grabs.patch
Normal file
77
0001-clipboard-do-not-release-between-client-grabs.patch
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
From 16b41429618985e4ab8c597fbd0c5cca5cf7b3e2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
||||||
|
Date: Thu, 21 Mar 2019 13:21:33 +0100
|
||||||
|
Subject: [PATCH 1/6] clipboard: do not release between client grabs
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
On the client side, whenever the grab owner changes (and the clipboard
|
||||||
|
was previously grabbed), spice-gtk sends a clipboard release followed
|
||||||
|
immediately by a new grab. But some clipboard managers on the remote
|
||||||
|
side react to clipboard release events by taking a clipboard grab,
|
||||||
|
presumably to avoid empty clipboards.
|
||||||
|
|
||||||
|
The two grabs, coming from the client and from the remote sides, will
|
||||||
|
race in both directions, which may confuse the client & remote side,
|
||||||
|
as both believe the other side is the current grab owner, and thus
|
||||||
|
further clipboard data requests are likely to fail.
|
||||||
|
|
||||||
|
Let's avoid sending a release event when re-grabing.
|
||||||
|
|
||||||
|
The race described above may still happen in other rare circunstances,
|
||||||
|
and will require a protocol change. To avoid the conflict, a discussed
|
||||||
|
solution could use a clipboard serial number.
|
||||||
|
|
||||||
|
Tested with current linux & windows vdagent. Looking at earlier
|
||||||
|
version of the code, it doesn't seem like subsequent grabs will be
|
||||||
|
treated as an error.
|
||||||
|
|
||||||
|
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||||
|
---
|
||||||
|
src/spice-gtk-session.c | 21 ++++++++-------------
|
||||||
|
1 file changed, 8 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c
|
||||||
|
index 60399d0..cb00fa5 100644
|
||||||
|
--- a/src/spice-gtk-session.c
|
||||||
|
+++ b/src/spice-gtk-session.c
|
||||||
|
@@ -577,8 +577,7 @@ static void clipboard_get_targets(GtkClipboard *clipboard,
|
||||||
|
g_return_if_fail(selection != -1);
|
||||||
|
|
||||||
|
if (s->clip_grabbed[selection]) {
|
||||||
|
- SPICE_DEBUG("Clipboard is already grabbed, ignoring %d atoms", n_atoms);
|
||||||
|
- return;
|
||||||
|
+ SPICE_DEBUG("Clipboard is already grabbed, re-grab: %d atoms", n_atoms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set all Atoms that matches our current protocol implementation */
|
||||||
|
@@ -660,18 +659,14 @@ static void clipboard_owner_change(GtkClipboard *clipboard,
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* In case we sent a grab to the agent, we need to release it now as
|
||||||
|
- * previous clipboard data should not be reachable anymore */
|
||||||
|
- if (s->clip_grabbed[selection]) {
|
||||||
|
- s->clip_grabbed[selection] = FALSE;
|
||||||
|
- if (spice_main_channel_agent_test_capability(s->main, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND)) {
|
||||||
|
- spice_main_channel_clipboard_selection_release(s->main, selection);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* We are mostly interested when owner has changed in which case
|
||||||
|
- * we would like to let agent know about new clipboard data. */
|
||||||
|
if (event->reason != GDK_OWNER_CHANGE_NEW_OWNER) {
|
||||||
|
+ if (s->clip_grabbed[selection]) {
|
||||||
|
+ /* grab was sent to the agent, so release it */
|
||||||
|
+ s->clip_grabbed[selection] = FALSE;
|
||||||
|
+ if (spice_main_channel_agent_test_capability(s->main, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND)) {
|
||||||
|
+ spice_main_channel_clipboard_selection_release(s->main, selection);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
s->clip_hasdata[selection] = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
167
0002-clipboard-do-not-release-between-remote-grabs.patch
Normal file
167
0002-clipboard-do-not-release-between-remote-grabs.patch
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
From 271656ae32e756eacfcc522d1aaab9d7102b0ce7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
||||||
|
Date: Thu, 21 Mar 2019 13:21:34 +0100
|
||||||
|
Subject: [PATCH 2/6] clipboard: do not release between remote grabs
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Delay the release events for 0.5 sec. If no further grab comes in,
|
||||||
|
then release the grab. Otherwise, let's skip the release. This avoids
|
||||||
|
some races with clipboard managers.
|
||||||
|
|
||||||
|
Related to:
|
||||||
|
https://gitlab.freedesktop.org/spice/spice-gtk/issues/82
|
||||||
|
|
||||||
|
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||||
|
---
|
||||||
|
src/spice-gtk-session.c | 80 ++++++++++++++++++++++++++++++++++++-----
|
||||||
|
1 file changed, 72 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c
|
||||||
|
index cb00fa5..79385a4 100644
|
||||||
|
--- a/src/spice-gtk-session.c
|
||||||
|
+++ b/src/spice-gtk-session.c
|
||||||
|
@@ -59,6 +59,7 @@ struct _SpiceGtkSessionPrivate {
|
||||||
|
gboolean clip_hasdata[CLIPBOARD_LAST];
|
||||||
|
gboolean clip_grabbed[CLIPBOARD_LAST];
|
||||||
|
gboolean clipboard_by_guest[CLIPBOARD_LAST];
|
||||||
|
+ guint clipboard_release_delay[CLIPBOARD_LAST];
|
||||||
|
/* auto-usbredir related */
|
||||||
|
gboolean auto_usbredir_enable;
|
||||||
|
int auto_usbredir_reqs;
|
||||||
|
@@ -95,6 +96,7 @@ struct _SpiceGtkSessionPrivate {
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Prototypes for private functions */
|
||||||
|
+static void clipboard_release(SpiceGtkSession *self, guint selection);
|
||||||
|
static void clipboard_owner_change(GtkClipboard *clipboard,
|
||||||
|
GdkEventOwnerChange *event,
|
||||||
|
gpointer user_data);
|
||||||
|
@@ -255,6 +257,23 @@ static void spice_gtk_session_dispose(GObject *gobject)
|
||||||
|
G_OBJECT_CLASS(spice_gtk_session_parent_class)->dispose(gobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void clipboard_release_delay_remove(SpiceGtkSession *self, guint selection,
|
||||||
|
+ gboolean release_if_delayed)
|
||||||
|
+{
|
||||||
|
+ SpiceGtkSessionPrivate *s = self->priv;
|
||||||
|
+
|
||||||
|
+ if (!s->clipboard_release_delay[selection])
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (release_if_delayed) {
|
||||||
|
+ SPICE_DEBUG("delayed clipboard release, sel:%u", selection);
|
||||||
|
+ clipboard_release(self, selection);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ g_source_remove(s->clipboard_release_delay[selection]);
|
||||||
|
+ s->clipboard_release_delay[selection] = 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void spice_gtk_session_finalize(GObject *gobject)
|
||||||
|
{
|
||||||
|
SpiceGtkSession *self = SPICE_GTK_SESSION(gobject);
|
||||||
|
@@ -264,6 +283,7 @@ static void spice_gtk_session_finalize(GObject *gobject)
|
||||||
|
/* release stuff */
|
||||||
|
for (i = 0; i < CLIPBOARD_LAST; ++i) {
|
||||||
|
g_clear_pointer(&s->clip_targets[i], g_free);
|
||||||
|
+ clipboard_release_delay_remove(self, i, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Chain up to the parent class */
|
||||||
|
@@ -823,6 +843,8 @@ static gboolean clipboard_grab(SpiceMainChannel *main, guint selection,
|
||||||
|
int m, n;
|
||||||
|
int num_targets = 0;
|
||||||
|
|
||||||
|
+ clipboard_release_delay_remove(self, selection, false);
|
||||||
|
+
|
||||||
|
cb = get_clipboard_from_selection(s, selection);
|
||||||
|
g_return_val_if_fail(cb != NULL, FALSE);
|
||||||
|
|
||||||
|
@@ -1052,17 +1074,12 @@ static gboolean clipboard_request(SpiceMainChannel *main, guint selection,
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void clipboard_release(SpiceMainChannel *main, guint selection,
|
||||||
|
- gpointer user_data)
|
||||||
|
+static void clipboard_release(SpiceGtkSession *self, guint selection)
|
||||||
|
{
|
||||||
|
- g_return_if_fail(SPICE_IS_GTK_SESSION(user_data));
|
||||||
|
-
|
||||||
|
- SpiceGtkSession *self = user_data;
|
||||||
|
SpiceGtkSessionPrivate *s = self->priv;
|
||||||
|
GtkClipboard* clipboard = get_clipboard_from_selection(s, selection);
|
||||||
|
|
||||||
|
- if (!clipboard)
|
||||||
|
- return;
|
||||||
|
+ g_return_if_fail(clipboard != NULL);
|
||||||
|
|
||||||
|
s->nclip_targets[selection] = 0;
|
||||||
|
|
||||||
|
@@ -1072,6 +1089,53 @@ static void clipboard_release(SpiceMainChannel *main, guint selection,
|
||||||
|
s->clipboard_by_guest[selection] = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+typedef struct SpiceGtkClipboardRelease {
|
||||||
|
+ SpiceGtkSession *self;
|
||||||
|
+ guint selection;
|
||||||
|
+} SpiceGtkClipboardRelease;
|
||||||
|
+
|
||||||
|
+static gboolean clipboard_release_timeout(gpointer user_data)
|
||||||
|
+{
|
||||||
|
+ SpiceGtkClipboardRelease *rel = user_data;
|
||||||
|
+
|
||||||
|
+ clipboard_release_delay_remove(rel->self, rel->selection, true);
|
||||||
|
+
|
||||||
|
+ return G_SOURCE_REMOVE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * The agents send release between two grabs. This may trigger
|
||||||
|
+ * clipboard managers trying to grab the clipboard. We end up with two
|
||||||
|
+ * sides, client and remote, racing for the clipboard grab, and
|
||||||
|
+ * believing each other is the owner.
|
||||||
|
+ *
|
||||||
|
+ * Workaround this problem by delaying the release event by 0.5 sec.
|
||||||
|
+ * FIXME: protocol change to solve the conflict and set client priority.
|
||||||
|
+ */
|
||||||
|
+#define CLIPBOARD_RELEASE_DELAY 500 /* ms */
|
||||||
|
+
|
||||||
|
+static void clipboard_release_delay(SpiceMainChannel *main, guint selection,
|
||||||
|
+ gpointer user_data)
|
||||||
|
+{
|
||||||
|
+ SpiceGtkSession *self = SPICE_GTK_SESSION(user_data);
|
||||||
|
+ SpiceGtkSessionPrivate *s = self->priv;
|
||||||
|
+ GtkClipboard* clipboard = get_clipboard_from_selection(s, selection);
|
||||||
|
+ SpiceGtkClipboardRelease *rel;
|
||||||
|
+
|
||||||
|
+ if (!clipboard)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ clipboard_release_delay_remove(self, selection, true);
|
||||||
|
+
|
||||||
|
+ rel = g_new0(SpiceGtkClipboardRelease, 1);
|
||||||
|
+ rel->self = self;
|
||||||
|
+ rel->selection = selection;
|
||||||
|
+ s->clipboard_release_delay[selection] =
|
||||||
|
+ g_timeout_add_full(G_PRIORITY_DEFAULT, CLIPBOARD_RELEASE_DELAY,
|
||||||
|
+ clipboard_release_timeout, rel, g_free);
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void channel_new(SpiceSession *session, SpiceChannel *channel,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
@@ -1088,7 +1152,7 @@ static void channel_new(SpiceSession *session, SpiceChannel *channel,
|
||||||
|
g_signal_connect(channel, "main-clipboard-selection-request",
|
||||||
|
G_CALLBACK(clipboard_request), self);
|
||||||
|
g_signal_connect(channel, "main-clipboard-selection-release",
|
||||||
|
- G_CALLBACK(clipboard_release), self);
|
||||||
|
+ G_CALLBACK(clipboard_release_delay), self);
|
||||||
|
}
|
||||||
|
if (SPICE_IS_INPUTS_CHANNEL(channel)) {
|
||||||
|
spice_g_signal_connect_object(channel, "inputs-modifiers",
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
From c771229a978c69323869d4063228306dc41e15b4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Jakub=20Jank=C5=AF?= <jjanku@redhat.com>
|
||||||
|
Date: Mon, 30 Sep 2019 18:44:05 +0200
|
||||||
|
Subject: [PATCH 3/6] fixup! clipboard: do not release between remote grabs
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Signed-off-by: Jakub Janků <jjanku@redhat.com>
|
||||||
|
---
|
||||||
|
src/spice-gtk-session.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c
|
||||||
|
index 79385a4..cbfe3bf 100644
|
||||||
|
--- a/src/spice-gtk-session.c
|
||||||
|
+++ b/src/spice-gtk-session.c
|
||||||
|
@@ -782,6 +782,11 @@ static void clipboard_get(GtkClipboard *clipboard,
|
||||||
|
g_return_if_fail(info < SPICE_N_ELEMENTS(atom2agent));
|
||||||
|
g_return_if_fail(s->main != NULL);
|
||||||
|
|
||||||
|
+ if (s->clipboard_release_delay[selection]) {
|
||||||
|
+ SPICE_DEBUG("not requesting data from guest during delayed release");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
ri.selection_data = selection_data;
|
||||||
|
ri.info = info;
|
||||||
|
ri.loop = g_main_loop_new(NULL, FALSE);
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
@ -0,0 +1,79 @@
|
|||||||
|
From 31a44bfd0acc3ae18682ae19ff1c8a8101bc96f4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
||||||
|
Date: Fri, 22 Mar 2019 15:20:12 +0100
|
||||||
|
Subject: [PATCH 4/6] clipboard: do not delay release if agent has "no release
|
||||||
|
on regrab"
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||||
|
---
|
||||||
|
meson.build | 2 +-
|
||||||
|
src/channel-main.c | 2 ++
|
||||||
|
src/spice-gtk-session.c | 9 ++++++++-
|
||||||
|
3 files changed, 11 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 171a3f6..b89a15b 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -81,7 +81,7 @@ endforeach
|
||||||
|
#
|
||||||
|
# check for mandatory dependencies
|
||||||
|
#
|
||||||
|
-spice_protocol_version='>= 0.12.15'
|
||||||
|
+spice_protocol_version='>= 0.14.1'
|
||||||
|
|
||||||
|
glib_version = '2.46'
|
||||||
|
glib_version_info = '>= @0@'.format(glib_version)
|
||||||
|
diff --git a/src/channel-main.c b/src/channel-main.c
|
||||||
|
index 4305dcd..adf6bab 100644
|
||||||
|
--- a/src/channel-main.c
|
||||||
|
+++ b/src/channel-main.c
|
||||||
|
@@ -222,6 +222,7 @@ static const char *agent_caps[] = {
|
||||||
|
[ VD_AGENT_CAP_AUDIO_VOLUME_SYNC ] = "volume-sync",
|
||||||
|
[ VD_AGENT_CAP_MONITORS_CONFIG_POSITION ] = "monitors config position",
|
||||||
|
[ VD_AGENT_CAP_FILE_XFER_DISABLED ] = "file transfer disabled",
|
||||||
|
+ [ VD_AGENT_CAP_CLIPBOARD_NO_RELEASE_ON_REGRAB ] = "no release on re-grab",
|
||||||
|
};
|
||||||
|
#define NAME(_a, _i) ((_i) < SPICE_N_ELEMENTS(_a) ? (_a[(_i)] ?: "?") : "?")
|
||||||
|
|
||||||
|
@@ -1333,6 +1334,7 @@ static void agent_announce_caps(SpiceMainChannel *channel)
|
||||||
|
VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_SELECTION);
|
||||||
|
VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MONITORS_CONFIG_POSITION);
|
||||||
|
VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS);
|
||||||
|
+ VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_NO_RELEASE_ON_REGRAB);
|
||||||
|
|
||||||
|
agent_msg_queue(channel, VD_AGENT_ANNOUNCE_CAPABILITIES, size, caps);
|
||||||
|
g_free(caps);
|
||||||
|
diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c
|
||||||
|
index cbfe3bf..34ae4a1 100644
|
||||||
|
--- a/src/spice-gtk-session.c
|
||||||
|
+++ b/src/spice-gtk-session.c
|
||||||
|
@@ -1114,7 +1114,8 @@ static gboolean clipboard_release_timeout(gpointer user_data)
|
||||||
|
* sides, client and remote, racing for the clipboard grab, and
|
||||||
|
* believing each other is the owner.
|
||||||
|
*
|
||||||
|
- * Workaround this problem by delaying the release event by 0.5 sec.
|
||||||
|
+ * Workaround this problem by delaying the release event by 0.5 sec,
|
||||||
|
+ * unless the no-release-on-regrab capability is present.
|
||||||
|
* FIXME: protocol change to solve the conflict and set client priority.
|
||||||
|
*/
|
||||||
|
#define CLIPBOARD_RELEASE_DELAY 500 /* ms */
|
||||||
|
@@ -1132,6 +1133,12 @@ static void clipboard_release_delay(SpiceMainChannel *main, guint selection,
|
||||||
|
|
||||||
|
clipboard_release_delay_remove(self, selection, true);
|
||||||
|
|
||||||
|
+ if (spice_main_channel_agent_test_capability(s->main,
|
||||||
|
+ VD_AGENT_CAP_CLIPBOARD_NO_RELEASE_ON_REGRAB)) {
|
||||||
|
+ clipboard_release(self, selection);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
rel = g_new0(SpiceGtkClipboardRelease, 1);
|
||||||
|
rel->self = self;
|
||||||
|
rel->selection = selection;
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
33
0005-clipboard-pre-condition-on-selection-value-256.patch
Normal file
33
0005-clipboard-pre-condition-on-selection-value-256.patch
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
From 7bbf04e5484129037d29018352ab6d3333fddf05 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
||||||
|
Date: Fri, 22 Mar 2019 15:20:13 +0100
|
||||||
|
Subject: [PATCH 5/6] clipboard: pre-condition on selection value < 256
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The protocol uses a u8 for the selection value. Make sure the given
|
||||||
|
argument value fits there, or throw a critical.
|
||||||
|
|
||||||
|
The other places seem to use u8 variables already.
|
||||||
|
|
||||||
|
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||||
|
---
|
||||||
|
src/channel-main.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/src/channel-main.c b/src/channel-main.c
|
||||||
|
index adf6bab..8574ae6 100644
|
||||||
|
--- a/src/channel-main.c
|
||||||
|
+++ b/src/channel-main.c
|
||||||
|
@@ -1354,6 +1354,7 @@ static void agent_clipboard_grab(SpiceMainChannel *channel, guint selection,
|
||||||
|
if (!c->agent_connected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ g_return_if_fail(selection < 256);
|
||||||
|
g_return_if_fail(test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND));
|
||||||
|
|
||||||
|
size = sizeof(VDAgentClipboardGrab) + sizeof(uint32_t) * ntypes;
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
121
0006-clipboard-implement-CAP_CLIPBOARD_GRAB_SERIAL.patch
Normal file
121
0006-clipboard-implement-CAP_CLIPBOARD_GRAB_SERIAL.patch
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
From 48e516347587f6f9e21f3ba9616079521296888d Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
||||||
|
Date: Fri, 22 Mar 2019 15:20:14 +0100
|
||||||
|
Subject: [PATCH 6/6] clipboard: implement CAP_CLIPBOARD_GRAB_SERIAL
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||||
|
---
|
||||||
|
src/channel-main.c | 32 +++++++++++++++++++++++++++++++-
|
||||||
|
src/spice-gtk-session.c | 1 -
|
||||||
|
2 files changed, 31 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/channel-main.c b/src/channel-main.c
|
||||||
|
index 8574ae6..0062593 100644
|
||||||
|
--- a/src/channel-main.c
|
||||||
|
+++ b/src/channel-main.c
|
||||||
|
@@ -111,6 +111,7 @@ struct _SpiceMainChannelPrivate {
|
||||||
|
guint migrate_delayed_id;
|
||||||
|
spice_migrate *migrate_data;
|
||||||
|
int max_clipboard;
|
||||||
|
+ uint32_t clipboard_serial[256];
|
||||||
|
|
||||||
|
gboolean agent_volume_playback_sync;
|
||||||
|
gboolean agent_volume_record_sync;
|
||||||
|
@@ -223,6 +224,7 @@ static const char *agent_caps[] = {
|
||||||
|
[ VD_AGENT_CAP_MONITORS_CONFIG_POSITION ] = "monitors config position",
|
||||||
|
[ VD_AGENT_CAP_FILE_XFER_DISABLED ] = "file transfer disabled",
|
||||||
|
[ VD_AGENT_CAP_CLIPBOARD_NO_RELEASE_ON_REGRAB ] = "no release on re-grab",
|
||||||
|
+ [ VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL ] = "clipboard grab serial",
|
||||||
|
};
|
||||||
|
#define NAME(_a, _i) ((_i) < SPICE_N_ELEMENTS(_a) ? (_a[(_i)] ?: "?") : "?")
|
||||||
|
|
||||||
|
@@ -412,6 +414,7 @@ static void spice_main_channel_reset_agent(SpiceMainChannel *channel)
|
||||||
|
|
||||||
|
spice_main_channel_reset_all_xfer_operations(channel);
|
||||||
|
file_xfer_flushed(channel, FALSE);
|
||||||
|
+ memset(c->clipboard_serial, 0, sizeof(c->clipboard_serial));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* main or coroutine context */
|
||||||
|
@@ -1335,6 +1338,7 @@ static void agent_announce_caps(SpiceMainChannel *channel)
|
||||||
|
VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MONITORS_CONFIG_POSITION);
|
||||||
|
VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS);
|
||||||
|
VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_NO_RELEASE_ON_REGRAB);
|
||||||
|
+ VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL);
|
||||||
|
|
||||||
|
agent_msg_queue(channel, VD_AGENT_ANNOUNCE_CAPABILITIES, size, caps);
|
||||||
|
g_free(caps);
|
||||||
|
@@ -1365,6 +1369,10 @@ static void agent_clipboard_grab(SpiceMainChannel *channel, guint selection,
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL)) {
|
||||||
|
+ size += sizeof(uint32_t);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
msg = g_alloca(size);
|
||||||
|
memset(msg, 0, size);
|
||||||
|
|
||||||
|
@@ -1372,7 +1380,13 @@ static void agent_clipboard_grab(SpiceMainChannel *channel, guint selection,
|
||||||
|
|
||||||
|
if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
|
||||||
|
msg[0] = selection;
|
||||||
|
- grab = (VDAgentClipboardGrab *)(msg + 4);
|
||||||
|
+ grab = (void *)grab + 4;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL)) {
|
||||||
|
+ guint32 *serial = (guint32 *)grab;
|
||||||
|
+ *serial = GUINT32_TO_LE(c->clipboard_serial[selection]++);
|
||||||
|
+ grab = (void *)grab + sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ntypes; i++) {
|
||||||
|
@@ -1974,6 +1988,7 @@ static void main_agent_handle_msg(SpiceChannel *channel,
|
||||||
|
SpiceMainChannel *self = SPICE_MAIN_CHANNEL(channel);
|
||||||
|
SpiceMainChannelPrivate *c = self->priv;
|
||||||
|
guint8 selection = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
|
||||||
|
+ guint32 serial;
|
||||||
|
|
||||||
|
g_return_if_fail(msg->protocol == VD_AGENT_PROTOCOL);
|
||||||
|
|
||||||
|
@@ -2045,6 +2060,21 @@ static void main_agent_handle_msg(SpiceChannel *channel,
|
||||||
|
case VD_AGENT_CLIPBOARD_GRAB:
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
+
|
||||||
|
+ if (test_agent_cap(self, VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL)) {
|
||||||
|
+ serial = GUINT32_FROM_LE(*((guint32 *)payload));
|
||||||
|
+ payload = ((guint8*)payload) + sizeof(uint32_t);
|
||||||
|
+ msg->size -= sizeof(uint32_t);
|
||||||
|
+
|
||||||
|
+ if (serial == c->clipboard_serial[selection]) {
|
||||||
|
+ c->clipboard_serial[selection]++;
|
||||||
|
+ } else {
|
||||||
|
+ CHANNEL_DEBUG(channel, "grab discard, serial:%u != c->serial:%u",
|
||||||
|
+ serial, c->clipboard_serial[selection]);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD_SELECTION_GRAB], 0, selection,
|
||||||
|
(guint8*)payload, msg->size / sizeof(uint32_t), &ret);
|
||||||
|
if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD)
|
||||||
|
diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c
|
||||||
|
index 34ae4a1..439199b 100644
|
||||||
|
--- a/src/spice-gtk-session.c
|
||||||
|
+++ b/src/spice-gtk-session.c
|
||||||
|
@@ -1116,7 +1116,6 @@ static gboolean clipboard_release_timeout(gpointer user_data)
|
||||||
|
*
|
||||||
|
* Workaround this problem by delaying the release event by 0.5 sec,
|
||||||
|
* unless the no-release-on-regrab capability is present.
|
||||||
|
- * FIXME: protocol change to solve the conflict and set client priority.
|
||||||
|
*/
|
||||||
|
#define CLIPBOARD_RELEASE_DELAY 500 /* ms */
|
||||||
|
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Name: spice-gtk
|
Name: spice-gtk
|
||||||
Version: 0.37
|
Version: 0.37
|
||||||
Release: 3%{?dist}
|
Release: 4%{?dist}
|
||||||
Summary: A GTK+ widget for SPICE clients
|
Summary: A GTK+ widget for SPICE clients
|
||||||
|
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
@ -13,6 +13,16 @@ Source1: https://www.spice-space.org/download/gtk/%{name}-%{version}%{?_v
|
|||||||
Source2: victortoso-E37A484F.keyring
|
Source2: victortoso-E37A484F.keyring
|
||||||
|
|
||||||
Patch0001: 0001-vmcstream-Fix-buffer-overflow-sending-data-to-task.patch
|
Patch0001: 0001-vmcstream-Fix-buffer-overflow-sending-data-to-task.patch
|
||||||
|
# clipboard-race patches: together with patches for spice-protocol
|
||||||
|
# and spice-gtk these fix problems interacting with mutter's new
|
||||||
|
# clipboard manager
|
||||||
|
# https://bugzilla.redhat.com/show_bug.cgi?id=1755038
|
||||||
|
Patch0002: 0001-clipboard-do-not-release-between-client-grabs.patch
|
||||||
|
Patch0003: 0002-clipboard-do-not-release-between-remote-grabs.patch
|
||||||
|
Patch0004: 0003-fixup-clipboard-do-not-release-between-remote-grabs.patch
|
||||||
|
Patch0005: 0004-clipboard-do-not-delay-release-if-agent-has-no-relea.patch
|
||||||
|
Patch0006: 0005-clipboard-pre-condition-on-selection-value-256.patch
|
||||||
|
Patch0007: 0006-clipboard-implement-CAP_CLIPBOARD_GRAB_SERIAL.patch
|
||||||
|
|
||||||
BuildRequires: git-core
|
BuildRequires: git-core
|
||||||
BuildRequires: meson
|
BuildRequires: meson
|
||||||
@ -194,6 +204,9 @@ gpgv2 --quiet --keyring %{SOURCE2} %{SOURCE1} %{SOURCE0}
|
|||||||
%{_bindir}/spicy-stats
|
%{_bindir}/spicy-stats
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Oct 04 2019 Adam Williamson <awilliam@redhat.com> - 0.37-4
|
||||||
|
- Backport clipboard-race patches for #1755038
|
||||||
|
|
||||||
* Fri Jul 26 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.37-3
|
* Fri Jul 26 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.37-3
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user