diff --git a/data/org.gnome.mutter.wayland.gschema.xml.in b/data/org.gnome.mutter.wayland.gschema.xml.in
index 23ce8386c..b8674b3ac 100644
--- a/data/org.gnome.mutter.wayland.gschema.xml.in
+++ b/data/org.gnome.mutter.wayland.gschema.xml.in
@@ -1,4 +1,10 @@
+
+
+
+
+
+
@@ -104,6 +110,21 @@
+
+ ["Security"]
+ Disable selected X extensions in Xwayland
+
+ This option disables the selected X extensions in Xwayland if
+ Xwayland was built with support for those X extensions.
+
+ This option has no effect if Xwayland was built without support
+ for the selected extensions.
+
+ Xwayland needs to be restarted for this setting to take effect.
+
+
+
diff --git a/src/backends/meta-settings-private.h b/src/backends/meta-settings-private.h
index 5e5d8e8dd..91b3eb17a 100644
--- a/src/backends/meta-settings-private.h
+++ b/src/backends/meta-settings-private.h
@@ -37,6 +37,12 @@ typedef enum _MetaExperimentalFeature
META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND = (1 << 3),
} MetaExperimentalFeature;
+typedef enum _MetaXwaylandExtension
+{
+ META_XWAYLAND_EXTENSION_SECURITY = (1 << 0),
+ META_XWAYLAND_EXTENSION_XTEST = (1 << 1),
+} MetaXwaylandExtension;
+
#define META_TYPE_SETTINGS (meta_settings_get_type ())
G_DECLARE_FINAL_TYPE (MetaSettings, meta_settings,
META, SETTINGS, GObject)
@@ -69,4 +75,6 @@ void meta_settings_get_xwayland_grab_patterns (MetaSettings *settings,
gboolean meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings);
+int meta_settings_get_xwayland_disable_extensions (MetaSettings *settings);
+
#endif /* META_SETTINGS_PRIVATE_H */
diff --git a/src/backends/meta-settings.c b/src/backends/meta-settings.c
index 14a9ead22..f14dbfae6 100644
--- a/src/backends/meta-settings.c
+++ b/src/backends/meta-settings.c
@@ -68,6 +68,9 @@ struct _MetaSettings
gboolean xwayland_allow_grabs;
GPtrArray *xwayland_grab_allow_list_patterns;
GPtrArray *xwayland_grab_deny_list_patterns;
+
+ /* A bitmask of MetaXwaylandExtension enum */
+ int xwayland_disable_extensions;
};
G_DEFINE_TYPE (MetaSettings, meta_settings, G_TYPE_OBJECT)
@@ -387,6 +390,14 @@ update_xwayland_allow_grabs (MetaSettings *settings)
"xwayland-allow-grabs");
}
+static void
+update_xwayland_disable_extensions (MetaSettings *settings)
+{
+ settings->xwayland_disable_extensions =
+ g_settings_get_flags (settings->wayland_settings,
+ "xwayland-disable-extension");
+}
+
static void
wayland_settings_changed (GSettings *wayland_settings,
gchar *key,
@@ -401,6 +412,10 @@ wayland_settings_changed (GSettings *wayland_settings,
{
update_xwayland_grab_access_rules (settings);
}
+ else if (g_str_equal (key, "xwayland-disable-extension"))
+ {
+ update_xwayland_disable_extensions (settings);
+ }
}
void
@@ -418,6 +433,12 @@ meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings)
return (settings->xwayland_allow_grabs);
}
+int
+meta_settings_get_xwayland_disable_extensions (MetaSettings *settings)
+{
+ return (settings->xwayland_disable_extensions);
+}
+
MetaSettings *
meta_settings_new (MetaBackend *backend)
{
@@ -471,6 +492,7 @@ meta_settings_init (MetaSettings *settings)
update_experimental_features (settings);
update_xwayland_grab_access_rules (settings);
update_xwayland_allow_grabs (settings);
+ update_xwayland_disable_extensions (settings);
}
static void
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 1b67c0a92..4a9d07ea9 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -39,8 +39,10 @@
#include
#include
+#include "backends/meta-settings-private.h"
#include "core/main-private.h"
#include "meta/main.h"
+#include "meta/meta-backend.h"
#include "wayland/meta-xwayland-surface.h"
#include "x11/meta-x11-display-private.h"
@@ -574,12 +576,25 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ struct {
+ const char *extension_name;
+ MetaXwaylandExtension disable_extension;
+ } x11_extension_names[] = {
+ { "SECURITY", META_XWAYLAND_EXTENSION_SECURITY },
+ { "XTEST", META_XWAYLAND_EXTENSION_XTEST },
+ };
+
int xwayland_client_fd[2];
int displayfd[2];
g_autoptr(GSubprocessLauncher) launcher = NULL;
GSubprocessFlags flags;
GError *error = NULL;
g_autoptr (GTask) task = NULL;
+ MetaBackend *backend;
+ MetaSettings *settings;
+ const char *args[32];
+ int xwayland_disable_extensions;
+ int i, j;
task = g_task_new (NULL, cancellable, callback, user_data);
g_task_set_source_tag (task, meta_xwayland_start_xserver);
@@ -614,6 +629,11 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager,
flags |= G_SUBPROCESS_FLAGS_STDERR_SILENCE;
}
+ backend = meta_get_backend ();
+ settings = meta_backend_get_settings (backend);
+ xwayland_disable_extensions =
+ meta_settings_get_xwayland_disable_extensions (settings);
+
launcher = g_subprocess_launcher_new (flags);
g_subprocess_launcher_take_fd (launcher, xwayland_client_fd[1], 3);
@@ -624,23 +644,46 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager,
g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
- manager->proc = g_subprocess_launcher_spawn (launcher, &error,
- XWAYLAND_PATH,
- manager->public_connection.name,
- "-rootless",
- "-noreset",
- "-accessx",
- "-core",
- "-auth", manager->auth_file,
- "-listen", "4",
- "-listen", "5",
- "-displayfd", "6",
+ i = 0;
+ args[i++] = XWAYLAND_PATH;
+ args[i++] = manager->public_connection.name;
+ args[i++] = "-rootless";
+ args[i++] = "-noreset";
+ args[i++] = "-accessx";
+ args[i++] = "-core";
+ args[i++] = "-auth";
+ args[i++] = manager->auth_file;
+ args[i++] = "-listen";
+ args[i++] = "4";
+ args[i++] = "-listen";
+ args[i++] = "5";
+ args[i++] = "-displayfd";
+ args[i++] = "6",
#ifdef HAVE_XWAYLAND_INITFD
- "-initfd", "7",
+ args[i++] = "-initfd";
+ args[i++] = "7";
#else
- "-listen", "7",
+ args[i++] = "-listen";
+ args[i++] = "7";
#endif
- NULL);
+ for (j = 0; j < G_N_ELEMENTS (x11_extension_names); j++)
+ {
+ /* Make sure we don't go past the array size - We need room for
+ * 2 arguments, plus the last NULL terminator.
+ */
+ if (i + 3 > G_N_ELEMENTS (args))
+ break;
+
+ if (xwayland_disable_extensions & x11_extension_names[j].disable_extension)
+ {
+ args[i++] = "-extension";
+ args[i++] = x11_extension_names[j].extension_name;
+ }
+ }
+ /* Terminator */
+ args[i++] = NULL;
+
+ manager->proc = g_subprocess_launcher_spawnv (launcher, args, &error);
if (!manager->proc)
{