diff --git a/meson.build b/meson.build index adc9faacc..d88a8653d 100644 --- a/meson.build +++ b/meson.build @@ -116,6 +116,7 @@ xrandr_dep = dependency('xrandr', version: xrandr_req) xcb_randr_dep = dependency('xcb-randr') xcb_res_dep = dependency('xcb-res') xinerama_dep = dependency('xinerama') +xau_dep = dependency('xau') ice_dep = dependency('ice') atk_dep = dependency('atk', version: atk_req) libcanberra_dep = dependency('libcanberra', version: libcanberra_req) diff --git a/src/meson.build b/src/meson.build index 53db81e85..805b9a20e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -101,6 +101,7 @@ if have_x11 x11_xcb_dep, xcb_randr_dep, xcb_res_dep, + xau_dep, ] if have_sm diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index f2410be4c..594088535 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -52,6 +52,7 @@ typedef struct struct wl_client *client; struct wl_resource *xserver_resource; char *display_name; + char *auth_file; GCancellable *xserver_died_cancellable; GSubprocess *proc; diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index f6ce88ee6..dee5cdd59 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -361,6 +361,12 @@ meta_wayland_override_display_name (const char *display_name) _display_name_override = g_strdup (display_name); } +static const char * +meta_wayland_get_xwayland_auth_file (MetaWaylandCompositor *compositor) +{ + return compositor->xwayland_manager.auth_file; +} + void meta_wayland_init (void) { @@ -438,7 +444,10 @@ meta_wayland_init (void) } if (meta_should_autostart_x11_display ()) - set_gnome_env ("DISPLAY", meta_wayland_get_xwayland_display_name (compositor)); + { + set_gnome_env ("DISPLAY", meta_wayland_get_xwayland_display_name (compositor)); + set_gnome_env ("XAUTHORITY", meta_wayland_get_xwayland_auth_file (compositor)); + } set_gnome_env ("WAYLAND_DISPLAY", meta_wayland_get_wayland_display_name (compositor)); } diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 43bf4c1e3..92a2224b2 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -31,6 +31,9 @@ #include #include #include +#include +#include +#include #include "compositor/meta-surface-actor-wayland.h" #include "meta/main.h" @@ -438,6 +441,75 @@ choose_xdisplay (MetaXWaylandManager *manager) return TRUE; } +G_DEFINE_AUTOPTR_CLEANUP_FUNC (FILE, fclose) + +static gboolean +prepare_auth_file (MetaXWaylandManager *manager) +{ + Xauth auth_entry = { 0 }; + g_autoptr (FILE) fp = NULL; + char hostname[HOST_NAME_MAX + 1]; + char auth_data[16]; + int fd; + + manager->auth_file = g_build_filename (g_get_user_runtime_dir (), + ".mutter-Xwaylandauth.XXXXXX", + NULL); + + if (gethostname (hostname, HOST_NAME_MAX) < 0) + g_strlcpy (hostname, "localhost", HOST_NAME_MAX); + + if (getrandom (auth_data, sizeof (auth_data), 0) != sizeof (auth_data)) + { + g_warning ("Failed to get random data: %s", g_strerror (errno)); + return FALSE; + } + + auth_entry.family = FamilyLocal; + auth_entry.address = hostname; + auth_entry.address_length = strlen (auth_entry.address); + auth_entry.name = (char *) "MIT-MAGIC-COOKIE-1"; + auth_entry.name_length = strlen (auth_entry.name); + auth_entry.data = auth_data; + auth_entry.data_length = sizeof (auth_data); + + fd = g_mkstemp (manager->auth_file); + if (fd < 0) + { + g_warning ("Failed to open Xauthority file: %s", g_strerror (errno)); + return FALSE; + } + + fp = fdopen (fd, "w+"); + if (!fp) + { + g_warning ("Failed to open Xauthority stream: %s", g_strerror (errno)); + close (fd); + return FALSE; + } + + if (!XauWriteAuth (fp, &auth_entry)) + { + g_warning ("Error writing to Xauthority file: %s", g_strerror (errno)); + return FALSE; + } + + auth_entry.family = FamilyWild; + if (!XauWriteAuth (fp, &auth_entry)) + { + g_warning ("Error writing to Xauthority file: %s", g_strerror (errno)); + return FALSE; + } + + if (fflush (fp) == EOF) + { + g_warning ("Error writing to Xauthority file: %s", g_strerror (errno)); + return FALSE; + } + + return TRUE; +} + static void xserver_finished_init (MetaXWaylandManager *manager) { @@ -512,6 +584,7 @@ meta_xwayland_init_xserver (MetaXWaylandManager *manager) "-noreset", "-accessx", "-core", + "-auth", manager->auth_file, "-listen", "4", "-listen", "5", "-displayfd", "6", @@ -545,6 +618,9 @@ meta_xwayland_start (MetaXWaylandManager *manager, if (!choose_xdisplay (manager)) return FALSE; + if (!prepare_auth_file (manager)) + return FALSE; + manager->wayland_display = wl_display; return meta_xwayland_init_xserver (manager); } @@ -584,6 +660,11 @@ meta_xwayland_stop (MetaXWaylandManager *manager) unlink (path); g_clear_pointer (&manager->display_name, g_free); + if (manager->auth_file) + { + unlink (manager->auth_file); + g_clear_pointer (&manager->auth_file, g_free); + } if (manager->lock_file) { unlink (manager->lock_file);