x11: Map x11 (UTF8_)STRING requests to text/plain mimetypes

Make the x11 selection proxy map UTF8_STRING and STRING to proper
mimetypes, as the selection source (wayland or memory) might not
offer those for backwards compatibility.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1355
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1005
This commit is contained in:
Carlos Garnacho 2020-01-13 14:18:00 +01:00 committed by Robert Mader
parent c1df48befd
commit a6c195b05c

View File

@ -27,6 +27,9 @@
#include "x11/meta-x11-selection-output-stream-private.h" #include "x11/meta-x11-selection-output-stream-private.h"
#include "x11/meta-x11-selection-private.h" #include "x11/meta-x11-selection-private.h"
#define UTF8_STRING_MIMETYPE "text/plain;charset=utf-8"
#define STRING_MIMETYPE "text/plain"
static gboolean static gboolean
atom_to_selection_type (Display *xdisplay, atom_to_selection_type (Display *xdisplay,
Atom selection, Atom selection,
@ -142,6 +145,45 @@ transfer_cb (MetaSelection *selection,
g_object_unref (output); g_object_unref (output);
} }
static char *
meta_x11_selection_find_target (MetaX11Display *x11_display,
MetaSelection *selection,
MetaSelectionType selection_type,
Atom selection_atom)
{
GList* mimetypes = NULL;
const gchar *atom_name;
char *retval;
mimetypes = meta_selection_get_mimetypes (selection, selection_type);
atom_name = gdk_x11_get_xatom_name (selection_atom);
if (g_list_find_custom (mimetypes, atom_name, (GCompareFunc) g_strcmp0))
{
retval = g_strdup (atom_name);
}
else if (strcmp (atom_name, "UTF8_STRING") == 0 &&
g_list_find_custom (mimetypes, UTF8_STRING_MIMETYPE,
(GCompareFunc) g_strcmp0))
{
retval = g_strdup (UTF8_STRING_MIMETYPE);
}
else if (strcmp (atom_name, "STRING") == 0 &&
g_list_find_custom (mimetypes, STRING_MIMETYPE,
(GCompareFunc) g_strcmp0))
{
retval = g_strdup (STRING_MIMETYPE);
}
else
{
retval = NULL;
}
g_list_free_full (mimetypes, g_free);
return retval;
}
static gboolean static gboolean
meta_x11_selection_handle_selection_request (MetaX11Display *x11_display, meta_x11_selection_handle_selection_request (MetaX11Display *x11_display,
XEvent *xevent) XEvent *xevent)
@ -198,15 +240,12 @@ meta_x11_selection_handle_selection_request (MetaX11Display *x11_display,
} }
else else
{ {
gboolean has_target; g_autofree char *target = NULL;
mimetypes = meta_selection_get_mimetypes (selection, selection_type); target = meta_x11_selection_find_target (x11_display, selection,
has_target = g_list_find_custom (mimetypes, selection_type, event->target);
gdk_x11_get_xatom_name (event->target),
(GCompareFunc) g_strcmp0) != NULL;
g_list_free_full (mimetypes, g_free);
if (has_target) if (target != NULL)
{ {
output = meta_x11_selection_output_stream_new (x11_display, output = meta_x11_selection_output_stream_new (x11_display,
event->requestor, event->requestor,
@ -218,7 +257,7 @@ meta_x11_selection_handle_selection_request (MetaX11Display *x11_display,
meta_selection_transfer_async (selection, meta_selection_transfer_async (selection,
selection_type, selection_type,
gdk_x11_get_xatom_name (event->target), target,
-1, -1,
output, output,
NULL, NULL,
@ -227,7 +266,9 @@ meta_x11_selection_handle_selection_request (MetaX11Display *x11_display,
return TRUE; return TRUE;
} }
else else
send_selection_notify (event, FALSE); {
send_selection_notify (event, FALSE);
}
} }
return FALSE; return FALSE;