diff options
author | Hans de Goede <hdegoede@redhat.com> | 2011-04-06 12:02:03 +0200 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@redhat.com> | 2011-04-08 13:29:59 +0200 |
commit | c354b0a23441f04022b34e19cba082a0160ccff8 (patch) | |
tree | e1d55fc7c0b37180f242650f9691ee6eb4705320 /gtk | |
parent | 288f843568c49b0618894d430b86b935f433bfde (diff) |
gtk: fixup clipboard_by_guest tracking
clipboard_by_guest tracking was used more or less for 2 things, to keep track
if the agent has clipboard data ready to send, and to see if we have done a
clipboard_set_with_data on behalf of the guest agent.
This patch splits the tracking of the 2, fixing several issues:
1) spice_display_paste_from_guest would not work if since receiving
the grab from the agent some other app has copied something to
the client clipboard.
2) We would do a clipboard_clear unconditionally even if we were
not the clipboard owner in the client (iow some other app has
done a clipboard_set_with_data since out last one).
This patch changes the meaning of the clipboard_by_guest boolean to just
track if we've done a clipboard_set_with_data on behalf of the guest
and are the last one to have a done a clipboard_set_with_data (iow we are the
client os' clipboard owner). It adds a checks to clipboard_release to
only call clipboard_clear if we are the current ownerm fixing 1).
This patch uses nclip_targets to keep track of the agent having data
available which we could paste, fixing 2).
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/spice-widget.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c index 95d9006..ed3784d 100644 --- a/gtk/spice-widget.c +++ b/gtk/spice-widget.c @@ -1105,9 +1105,11 @@ static void clipboard_get_targets(GtkClipboard *clipboard, } } if (!d->clip_grabbed[selection] && t > 0) { - d->clip_grabbed[selection] = true; + d->clip_grabbed[selection] = TRUE; spice_main_clipboard_selection_grab(d->main, get_selection_from_clipboard(d, clipboard), types, t); + /* Sending a grab causes the agent to do an impicit release */ + d->nclip_targets[selection] = 0; } } @@ -1455,6 +1457,7 @@ static void disconnect_main(SpiceDisplay *display) for (int i = 0; i < CLIPBOARD_LAST; ++i) { d->clipboard_by_guest[i] = FALSE; d->clip_grabbed[i] = FALSE; + d->nclip_targets[i] = 0; } } @@ -1569,7 +1572,8 @@ static void clipboard_get(GtkClipboard *clipboard, GtkSelectionData *selection_d static void clipboard_clear(GtkClipboard *clipboard, gpointer display) { SPICE_DEBUG("clipboard_clear"); - // clipboard release ? + /* We watch for clipboard ownership changes and act on those, so we + don't need to do anything here */ } static gboolean clipboard_grab(SpiceMainChannel *main, guint selection, @@ -1610,7 +1614,7 @@ static gboolean clipboard_grab(SpiceMainChannel *main, guint selection, /* Receiving a grab implies we've released our own grab */ d->clip_grabbed[selection] = FALSE; - if (!d->auto_clipboard_enable) + if (!d->auto_clipboard_enable || d->nclip_targets[selection] == 0) goto skip_grab_clipboard; if (!gtk_clipboard_set_with_data(cb, targets, i, @@ -1619,10 +1623,10 @@ static gboolean clipboard_grab(SpiceMainChannel *main, guint selection, return FALSE; } d->clipboard_selfgrab_pending[selection] = TRUE; + d->clipboard_by_guest[selection] = TRUE; d->clip_hasdata[selection] = FALSE; skip_grab_clipboard: - d->clipboard_by_guest[selection] = TRUE; return TRUE; } @@ -1694,7 +1698,12 @@ static void clipboard_release(SpiceMainChannel *main, guint selection, gpointer if (!clipboard) return; + d->nclip_targets[selection] = 0; + + if (!d->clipboard_by_guest[selection]) + return; gtk_clipboard_clear(clipboard); + d->clipboard_by_guest[selection] = FALSE; } static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data) @@ -1859,7 +1868,7 @@ void spice_display_paste_from_guest(SpiceDisplay *display) spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display); int selection = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD; - if (!d->clipboard_by_guest[selection]) { + if (d->nclip_targets[selection] == 0) { g_warning("Guest clipboard is not available."); return; } @@ -1871,6 +1880,7 @@ void spice_display_paste_from_guest(SpiceDisplay *display) return; } d->clipboard_selfgrab_pending[selection] = TRUE; + d->clipboard_by_guest[selection] = TRUE; d->clip_hasdata[selection] = FALSE; } |