summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2011-04-06 12:02:03 +0200
committerMarc-André Lureau <marcandre.lureau@redhat.com>2011-04-08 13:29:59 +0200
commitc354b0a23441f04022b34e19cba082a0160ccff8 (patch)
treee1d55fc7c0b37180f242650f9691ee6eb4705320 /gtk
parent288f843568c49b0618894d430b86b935f433bfde (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.c20
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;
}