[Spice-devel] [spice-gtk 2/2] clipboard: Use gtk_clipboard_request_text for text data

Pavel Grunt pgrunt at redhat.com
Mon Aug 15 10:56:44 UTC 2016


Hi,

On Wed, 2016-08-10 at 12:26 +0200, Christophe Fergeau wrote:
> Currently, when the agent asks us for VD_AGENT_CLIPBOARD_UTF8_TEXT data,
> spice-gtk looks up for the first X11 target which would provide it with
> UTF8_TEXT data, and uses that for the clipboard request. This means we
> will use UTF8_STRING as the target for gtk_clipboard_request_contents().
> 
> However, some applications who can copy and paste text do not
> necessarily support the UTF8_STRING target. This is the case for Motif
> applications which support the STRING target however. It turns out gtk+
> also provides a gtk_clipboard_request_text() method which will try
> several targets (UTF8_TEXT, COMPOUND_TEXT, TEXT), and will ensure the
> returned string is UTF-8, so we can use that when the agent asks us for
> some text data.
> 
Sounds good to me

> This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1348624
> ---
>  src/spice-gtk-session.c | 65 +++++++++++++++++++++++++++++++++++++++---------
> -
>  1 file changed, 52 insertions(+), 13 deletions(-)
> 
> diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c
> index 1343302..5855610 100644
> --- a/src/spice-gtk-session.c
> +++ b/src/spice-gtk-session.c
> @@ -947,6 +947,40 @@ static char *fixup_clipboard_text(SpiceGtkSession *self,
> const char *text, int *
>      return conv;
>  }
>  
> +static void clipboard_received_text_cb(GtkClipboard *clipboard,
> +                                       const gchar *text,
> +                                       gpointer user_data)
> +{
> +    WeakRef *weakref = user_data;
> +    SpiceGtkSession *self = (SpiceGtkSession*)weakref->object;
> +    char *conv = NULL;
> +    int len = 0;
> +    int selection;
> +
> +    weak_unref(weakref);
> +
> +    if (self == NULL)
> +        return;
> +
> +    g_return_if_fail(SPICE_IS_GTK_SESSION(self));
> +
> +    selection = get_selection_from_clipboard(self->priv, clipboard);
> +    g_return_if_fail(selection != -1);
> +
> +    len = strlen(text);
> +    if (!check_clipboard_size_limits(self, len)) {
> +        return;
> +    }
> +
> +    /* gtk+ internal utf8 newline is always LF, even on windows */
> +    conv = fixup_clipboard_text(self, text, &len);
> +
> +    spice_main_clipboard_selection_notify(self->priv->main, selection,
> +                                          VD_AGENT_CLIPBOARD_UTF8_TEXT,
> +                                          (guchar *)conv ?: (guchar*)text, 
or just (guchar *) (conv ?: text)

OT: '?:' is in C or just in gcc ?
> len);
> +    g_free(conv);
> +}
> +
>  static void clipboard_received_cb(GtkClipboard *clipboard,
>                                    GtkSelectionData *selection_data,
>                                    gpointer user_data)
> @@ -994,10 +1028,10 @@ static void clipboard_received_cb(GtkClipboard
> *clipboard,
>      const guchar *data = gtk_selection_data_get_data(selection_data);
>      gpointer conv = NULL;

'conv' is not used ^, should be removed

Pavel

>  
> -    /* gtk+ internal utf8 newline is always LF, even on windows */
> -    if (type == VD_AGENT_CLIPBOARD_UTF8_TEXT) {
> -        conv = fixup_clipboard_text(self, (gchar *)data, &len);
> -    }
> +    /* text should be handled through clipboard_received_text_cb(), not
> +     * clipboard_received_cb().
> +     */
> +    g_warn_if_fail(type != VD_AGENT_CLIPBOARD_UTF8_TEXT);
>  
>      spice_main_clipboard_selection_notify(s->main, selection, type,
>                                            conv ?: data, len);
> @@ -1024,16 +1058,21 @@ static gboolean clipboard_request(SpiceMainChannel
> *main, guint selection,
>      cb = get_clipboard_from_selection(s, selection);
>      g_return_val_if_fail(cb != NULL, FALSE);
>  
> -    for (m = 0; m < SPICE_N_ELEMENTS(atom2agent); m++) {
> -        if (atom2agent[m].vdagent == type)
> -            break;
> -    }
> -
> -    g_return_val_if_fail(m < SPICE_N_ELEMENTS(atom2agent), FALSE);
> -
> -    atom = gdk_atom_intern_static_string(atom2agent[m].xatom);
> -    gtk_clipboard_request_contents(cb, atom, clipboard_received_cb,
> +    if (type == VD_AGENT_CLIPBOARD_UTF8_TEXT) {
> +        gtk_clipboard_request_text(cb, clipboard_received_text_cb,
>                                     weak_ref(G_OBJECT(self)));
> +    } else {
> +        for (m = 0; m < SPICE_N_ELEMENTS(atom2agent); m++) {
> +            if (atom2agent[m].vdagent == type)
> +                break;
> +        }
> +
> +        g_return_val_if_fail(m < SPICE_N_ELEMENTS(atom2agent), FALSE);
> +
> +        atom = gdk_atom_intern_static_string(atom2agent[m].xatom);
> +        gtk_clipboard_request_contents(cb, atom, clipboard_received_cb,
> +                                       weak_ref(G_OBJECT(self)));
> +    }
>  
>      return TRUE;
>  }


More information about the Spice-devel mailing list