From: Victor Toso <me@xxxxxxxxxxxxxx> If SpiceGtkSession::allow-clipboard-managers is disabled, while the spice client does not hold the keyboard-grab, every owner-change event to clipboard change will be delayed and requested later when keyboard-grab is received. Signed-off-by: Victor Toso <victortoso@xxxxxxxxxx> --- src/spice-gtk-session.c | 77 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c index 7391e6a..384d090 100644 --- a/src/spice-gtk-session.c +++ b/src/spice-gtk-session.c @@ -56,6 +56,7 @@ struct _SpiceGtkSessionPrivate { GtkClipboard *clipboard_primary; GtkTargetEntry *clip_targets[CLIPBOARD_LAST]; guint nclip_targets[CLIPBOARD_LAST]; + gboolean request_delayed_ptr[CLIPBOARD_LAST]; gboolean clip_hasdata[CLIPBOARD_LAST]; gboolean clip_grabbed[CLIPBOARD_LAST]; gboolean clipboard_by_guest[CLIPBOARD_LAST]; @@ -259,6 +260,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); + s->request_delayed_ptr[i] = FALSE; } /* Chain up to the parent class */ @@ -588,6 +590,9 @@ static void clipboard_get_targets(GtkClipboard *clipboard, int a; int selection; + /* Disable owner-event requests now if allow_clipboard_managers is disabled */ + s->back_from_focus_out = FALSE; + if (s->main == NULL) return; @@ -644,6 +649,56 @@ static void clipboard_get_targets(GtkClipboard *clipboard, s->nclip_targets[selection] = 0; } +static bool clipboard_client_request_targets(SpiceGtkSession *self, + GtkClipboard *clipboard) +{ + SpiceGtkSessionPrivate *s = self->priv; + gint selection = get_selection_from_clipboard(s, clipboard); + + SPICE_DEBUG("clipboard request: %p %d", clipboard, selection); + s->clipboard_by_guest[selection] = FALSE; + s->clip_hasdata[selection] = TRUE; + if (s->auto_clipboard_enable && !read_only(self)) { + gtk_clipboard_request_targets(clipboard, clipboard_get_targets, + get_weak_ref(self)); + return true; + } + return false; +} + +static bool clipboard_owner_change_delayed(SpiceGtkSession *self, gint selection) +{ + SpiceGtkSessionPrivate *s = self->priv; + GtkClipboard *clipboard = get_clipboard_from_selection(s, selection); + + g_return_val_if_fail(clipboard != NULL, false); + + if (s->clip_grabbed[selection]) { + SPICE_DEBUG("clipboard delayed request: already made for %p %d", + clipboard, selection); + } + + s->request_delayed_ptr[selection] = FALSE; + return clipboard_client_request_targets(self, clipboard); +} + +static bool request_delayed_run_all(SpiceGtkSession *self) +{ + gint i; + bool ret = false; + SpiceGtkSessionPrivate *s = self->priv; + + for (i = 0; i < CLIPBOARD_LAST; ++i) { + if (s->request_delayed_ptr[i]) { + if (clipboard_owner_change_delayed(self, i)) { + ret = true; + } + } + } + return ret; +} + + /* Callback for every owner-change event for given @clipboard. * This event is triggered in different ways depending on the environment of * the Client, some examples: @@ -700,11 +755,17 @@ static void clipboard_owner_change(GtkClipboard *clipboard, return; } - s->clipboard_by_guest[selection] = FALSE; - s->clip_hasdata[selection] = TRUE; - if (s->auto_clipboard_enable && !read_only(self)) - gtk_clipboard_request_targets(clipboard, clipboard_get_targets, - get_weak_ref(self)); + if (!s->allow_clipboard_managers && !s->back_from_focus_out) { + if (!s->request_delayed_ptr[selection]) { + SPICE_DEBUG("clipboard: owner-change: wait focus-in for clipboard-request %p %d", + clipboard, selection); + } + s->request_delayed_ptr[selection] = TRUE; + return; + } + + s->request_delayed_ptr[selection] = FALSE; + clipboard_client_request_targets(self, clipboard); } typedef struct @@ -1324,6 +1385,12 @@ void spice_gtk_session_set_keyboard_has_focus(SpiceGtkSession *self, s->back_from_focus_out = FALSE; } + /* Clipboard requests made while on focus-out may be done now, if any is + * successfull, we can reset back_from_focus_out helper */ + if (s->back_from_focus_out && request_delayed_run_all(self)) { + s->back_from_focus_out = FALSE; + } + s->keyboard_has_focus = keyboard_has_focus; } -- 2.20.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel