settings: Add xwayland grab settings

Add new settings to control which X11 windows are allowed to
issue Xwayland grabs.

https://bugzilla.gnome.org/show_bug.cgi?id=783342
This commit is contained in:
Olivier Fourdan 2017-09-01 13:53:18 +02:00
parent 5f132f3975
commit 519a0fd93d
5 changed files with 187 additions and 0 deletions

View File

@ -105,6 +105,7 @@ MUTTER_PC_MODULES="
xcb-randr xcb-randr
xcb-res xcb-res
" "
XWAYLAND_GRAB_DEFAULT_ACCESS_RULES="gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr"
GLIB_GSETTINGS GLIB_GSETTINGS
@ -312,6 +313,21 @@ AS_IF([test "$have_wayland" = "yes"], [
]) ])
AM_CONDITIONAL([HAVE_WAYLAND],[test "$have_wayland" = "yes"]) AM_CONDITIONAL([HAVE_WAYLAND],[test "$have_wayland" = "yes"])
AC_ARG_WITH([xwayland-grab-default-access-rules],
[AS_HELP_STRING([--with-xwayland-grab-default-access-rules="app-res1,app-res2,..."],
[comma delimited list of applications ressources or class allowed to issue X11 grabs in Xwayland"])],
[with_XWAYLAND_GRAB_DEFAULT_ACCESS_RULES="$withval"],
[with_XWAYLAND_GRAB_DEFAULT_ACCESS_RULES="$XWAYLAND_GRAB_DEFAULT_ACCESS_RULES"])
case "$with_XWAYLAND_GRAB_DEFAULT_ACCESS_RULES" in
yes) with_XWAYLAND_GRAB_DEFAULT_ACCESS_RULES="$XWAYLAND_GRAB_DEFAULT_ACCESS_RULES" ;;
no) with_XWAYLAND_GRAB_DEFAULT_ACCESS_RULES='' ;;
esac
AC_DEFINE_UNQUOTED([XWAYLAND_GRAB_DEFAULT_ACCESS_RULES],
"$with_XWAYLAND_GRAB_DEFAULT_ACCESS_RULES",
[Xwayland applications allowed to issue keyboard grabs])
AC_SUBST(XWAYLAND_GRAB_DEFAULT_ACCESS_RULES)
PKG_CHECK_EXISTS([xi >= 1.6.99.1], PKG_CHECK_EXISTS([xi >= 1.6.99.1],
AC_DEFINE([HAVE_XI23],[1],[Define if you have support for XInput 2.3 or greater])) AC_DEFINE([HAVE_XI23],[1],[Define if you have support for XInput 2.3 or greater]))

View File

@ -24,6 +24,7 @@ gsettings_SCHEMAS = $(gschema_in_files:.xml.in=.xml)
%.gschema.xml: %.gschema.xml.in Makefile %.gschema.xml: %.gschema.xml.in Makefile
$(AM_V_GEN) sed -e 's|@GETTEXT_DOMAIN[@]|$(GETTEXT_PACKAGE)|g' \ $(AM_V_GEN) sed -e 's|@GETTEXT_DOMAIN[@]|$(GETTEXT_PACKAGE)|g' \
-e 's|@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES[@]|$(XWAYLAND_GRAB_DEFAULT_ACCESS_RULES)|g' \
$< > $@ || rm $@ $< > $@ || rm $@
@GSETTINGS_RULES@ @GSETTINGS_RULES@

View File

@ -54,4 +54,48 @@
<summary>Re-enable shortcuts</summary> <summary>Re-enable shortcuts</summary>
</key> </key>
</schema> </schema>
<schema id="org.gnome.mutter.wayland" path="/org/gnome/mutter/wayland/"
gettext-domain="@GETTEXT_DOMAIN@">
<key name="xwayland-allow-grabs" type="b">
<default>false</default>
<summary>Allow grabs with Xwayland</summary>
<description>
Allow keyboard grabs issued by X11 applications running in Xwayland
to be taken into account.
For a X11 grab to be taken into account under Wayland, the client must
also either send a specific X11 ClientMessage to the root window or be
among the applications white-listed in key “xwayland-grab-access-rules“.
</description>
</key>
<key name="xwayland-grab-access-rules" type="as">
<default>[]</default>
<summary>Xwayland applications allowed to issue keyboard grabs</summary>
<description>
List the resource names or resource class of X11 windows either
allowed or not allowed to issue X11 keyboard grabs under Xwayland.
The resource name or resource class of a given X11 window can be
obtained using the command “xprop WM_CLASS“.
Wildcards '*' and jokers '?' in the values are supported.
Values starting with '!' are blacklisted, which has precedence over
the whitelist, to revoke applications from the default system list.
The default system list includes the following applications:
“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@“
Users can break an existing grab by using the specific keyboard
short-cut defined by the keybinding key “restore-shortcuts“.
</description>
</key>
</schema>
</schemalist> </schemalist>

View File

@ -58,4 +58,10 @@ void meta_settings_override_experimental_features (MetaSettings *settings);
void meta_settings_enable_experimental_feature (MetaSettings *settings, void meta_settings_enable_experimental_feature (MetaSettings *settings,
MetaExperimentalFeature feature); MetaExperimentalFeature feature);
void meta_settings_get_xwayland_grab_patterns (MetaSettings *settings,
GPtrArray **whitelist_patterns,
GPtrArray **blacklist_patterns);
gboolean meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings);
#endif /* META_SETTINGS_PRIVATE_H */ #endif /* META_SETTINGS_PRIVATE_H */

View File

@ -30,6 +30,11 @@
#include "backends/meta-monitor-manager-private.h" #include "backends/meta-monitor-manager-private.h"
#include "ui/theme-private.h" #include "ui/theme-private.h"
#ifndef XWAYLAND_GRAB_DEFAULT_ACCESS_RULES
# warning "XWAYLAND_GRAB_DEFAULT_ACCESS_RULES is not set"
# define XWAYLAND_GRAB_DEFAULT_ACCESS_RULES ""
#endif
enum enum
{ {
UI_SCALING_FACTOR_CHANGED, UI_SCALING_FACTOR_CHANGED,
@ -50,6 +55,7 @@ struct _MetaSettings
GSettings *interface_settings; GSettings *interface_settings;
GSettings *mutter_settings; GSettings *mutter_settings;
GSettings *wayland_settings;
int ui_scaling_factor; int ui_scaling_factor;
int global_scaling_factor; int global_scaling_factor;
@ -58,6 +64,10 @@ struct _MetaSettings
MetaExperimentalFeature experimental_features; MetaExperimentalFeature experimental_features;
gboolean experimental_features_overridden; gboolean experimental_features_overridden;
gboolean xwayland_allow_grabs;
GPtrArray *xwayland_grab_whitelist_patterns;
GPtrArray *xwayland_grab_blacklist_patterns;
}; };
G_DEFINE_TYPE (MetaSettings, meta_settings, G_TYPE_OBJECT) G_DEFINE_TYPE (MetaSettings, meta_settings, G_TYPE_OBJECT)
@ -299,6 +309,105 @@ mutter_settings_changed (GSettings *mutter_settings,
(unsigned int) old_experimental_features); (unsigned int) old_experimental_features);
} }
static void
xwayland_grab_list_add_item (MetaSettings *settings,
char *item)
{
/* If first character is '!', it's a blacklisted item */
if (item[0] != '!')
g_ptr_array_add (settings->xwayland_grab_whitelist_patterns,
g_pattern_spec_new (item));
else if (item[1] != 0)
g_ptr_array_add (settings->xwayland_grab_blacklist_patterns,
g_pattern_spec_new (&item[1]));
}
static gboolean
xwayland_grab_access_rules_handler (GVariant *variant,
gpointer *result,
gpointer data)
{
MetaSettings *settings = data;
GVariantIter iter;
char *item;
/* Create a GPatternSpec for each element */
g_variant_iter_init (&iter, variant);
while (g_variant_iter_loop (&iter, "s", &item))
xwayland_grab_list_add_item (settings, item);
*result = GINT_TO_POINTER (TRUE);
return TRUE;
}
static void
update_xwayland_grab_access_rules (MetaSettings *settings)
{
gchar **system_defaults;
int i;
/* Free previous patterns and create new arrays */
g_ptr_array_free (settings->xwayland_grab_whitelist_patterns, TRUE);
settings->xwayland_grab_whitelist_patterns =
g_ptr_array_new_with_free_func ((GDestroyNotify) g_pattern_spec_free);
g_ptr_array_free (settings->xwayland_grab_blacklist_patterns, TRUE);
settings->xwayland_grab_blacklist_patterns =
g_ptr_array_new_with_free_func ((GDestroyNotify) g_pattern_spec_free);
/* Add system defaults values */
system_defaults = g_strsplit (XWAYLAND_GRAB_DEFAULT_ACCESS_RULES, ",", -1);
for (i = 0; system_defaults[i]; i++)
xwayland_grab_list_add_item (settings, system_defaults[i]);
g_strfreev (system_defaults);
/* Then add gsettings values */
g_settings_get_mapped (settings->wayland_settings,
"xwayland-grab-access-rules",
xwayland_grab_access_rules_handler,
settings);
}
static void
update_xwayland_allow_grabs (MetaSettings *settings)
{
settings->xwayland_allow_grabs =
g_settings_get_boolean (settings->wayland_settings,
"xwayland-allow-grabs");
}
static void
wayland_settings_changed (GSettings *wayland_settings,
gchar *key,
MetaSettings *settings)
{
if (g_str_equal (key, "xwayland-allow-grabs"))
{
update_xwayland_allow_grabs (settings);
}
else if (g_str_equal (key, "xwayland-grab-access-rules"))
{
update_xwayland_grab_access_rules (settings);
}
}
void
meta_settings_get_xwayland_grab_patterns (MetaSettings *settings,
GPtrArray **whitelist_patterns,
GPtrArray **blacklist_patterns)
{
*whitelist_patterns = settings->xwayland_grab_whitelist_patterns;
*blacklist_patterns = settings->xwayland_grab_blacklist_patterns;
}
gboolean
meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings)
{
return (settings->xwayland_allow_grabs);
}
MetaSettings * MetaSettings *
meta_settings_new (MetaBackend *backend) meta_settings_new (MetaBackend *backend)
{ {
@ -317,6 +426,11 @@ meta_settings_dispose (GObject *object)
g_clear_object (&settings->mutter_settings); g_clear_object (&settings->mutter_settings);
g_clear_object (&settings->interface_settings); g_clear_object (&settings->interface_settings);
g_clear_object (&settings->wayland_settings);
g_clear_pointer (&settings->xwayland_grab_whitelist_patterns,
g_ptr_array_unref);
g_clear_pointer (&settings->xwayland_grab_blacklist_patterns,
g_ptr_array_unref);
G_OBJECT_CLASS (meta_settings_parent_class)->dispose (object); G_OBJECT_CLASS (meta_settings_parent_class)->dispose (object);
} }
@ -332,6 +446,10 @@ meta_settings_init (MetaSettings *settings)
g_signal_connect (settings->mutter_settings, "changed", g_signal_connect (settings->mutter_settings, "changed",
G_CALLBACK (mutter_settings_changed), G_CALLBACK (mutter_settings_changed),
settings); settings);
settings->wayland_settings = g_settings_new ("org.gnome.mutter.wayland");
g_signal_connect (settings->wayland_settings, "changed",
G_CALLBACK (wayland_settings_changed),
settings);
/* Chain up inter-dependent settings. */ /* Chain up inter-dependent settings. */
g_signal_connect (settings, "global-scaling-factor-changed", g_signal_connect (settings, "global-scaling-factor-changed",
@ -341,6 +459,8 @@ meta_settings_init (MetaSettings *settings)
update_global_scaling_factor (settings); update_global_scaling_factor (settings);
update_experimental_features (settings); update_experimental_features (settings);
update_xwayland_grab_access_rules (settings);
update_xwayland_allow_grabs (settings);
} }
static void static void