diff --git a/config.h.meson b/config.h.meson index 0bab71848..0edff4d57 100644 --- a/config.h.meson +++ b/config.h.meson @@ -67,3 +67,6 @@ /* Either or */ #mesondefine HAVE_SYS_RANDOM #mesondefine HAVE_LINUX_RANDOM + +/* Whether Xwayland has -initfd option */ +#mesondefine HAVE_XWAYLAND_INITFD diff --git a/meson.build b/meson.build index 666ba68a7..ababd6eb2 100644 --- a/meson.build +++ b/meson.build @@ -377,6 +377,7 @@ if cc.has_header_symbol('sys/prctl.h', 'prctl') cdata.set('HAVE_SYS_PRCTL', 1) endif +have_xwayland_initfd = false if have_wayland xwayland_path = get_option('xwayland_path') if xwayland_path == '' @@ -392,6 +393,19 @@ if have_wayland else error('Required function getrandom not found') endif + + # For Xwayland -initfd usage + use_initfd = get_option('xwayland_initfd') + if use_initfd.auto() + xwayland_options = run_command(xwayland_path, '-help') + have_xwayland_initfd = xwayland_options.stderr().contains('-initfd') + else + have_xwayland_initfd = use_initfd.enabled() + endif + + if (have_xwayland_initfd) + cdata.set('HAVE_XWAYLAND_INITFD', 1) + endif endif xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules') @@ -450,6 +464,7 @@ output = [ ' Startup notification..... ' + have_startup_notification.to_string(), ' Introspection............ ' + have_introspection.to_string(), ' Profiler................. ' + have_profiler.to_string(), + ' Xwayland initfd.......... ' + have_xwayland_initfd.to_string(), '', ' Tests:', '', diff --git a/meson_options.txt b/meson_options.txt index 73aa7adde..097809a93 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -152,3 +152,9 @@ option('xwayland_grab_default_access_rules', value: 'gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr', description: 'Comma delimited list of applications ressources or class allowed to issue X11 grabs in Xwayland' ) + +option('xwayland_initfd', + type: 'feature', + value: 'auto', + description: 'Whether Xwayland -initfd argument is used' +) diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index aa8e4deab..e28ca06d6 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -48,11 +48,18 @@ typedef struct char *lock_file; int abstract_fd; int unix_fd; + char *name; +} MetaXWaylandConnection; + +typedef struct +{ + MetaXWaylandConnection private_connection; + MetaXWaylandConnection public_connection; + guint xserver_grace_period_id; struct wl_display *wayland_display; struct wl_client *client; struct wl_resource *xserver_resource; - char *display_name; char *auth_file; GCancellable *xserver_died_cancellable; diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 876b4925a..70c3db87d 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -446,7 +446,7 @@ meta_wayland_init (void) if (meta_get_x11_display_policy () != META_DISPLAY_POLICY_DISABLED) { - set_gnome_env ("DISPLAY", meta_wayland_get_xwayland_display_name (compositor)); + set_gnome_env ("DISPLAY", compositor->xwayland_manager.public_connection.name); set_gnome_env ("XAUTHORITY", meta_wayland_get_xwayland_auth_file (compositor)); } @@ -462,7 +462,7 @@ meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor) const char * meta_wayland_get_xwayland_display_name (MetaWaylandCompositor *compositor) { - return compositor->xwayland_manager.display_name; + return compositor->xwayland_manager.private_connection.name; } void diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 530dadc1a..ac55599d4 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -314,6 +314,7 @@ xserver_died (GObject *source, gpointer user_data) { GSubprocess *proc = G_SUBPROCESS (source); + MetaDisplay *display = meta_get_display (); g_autoptr (GError) error = NULL; if (!g_subprocess_wait_finish (proc, result, &error)) @@ -338,7 +339,6 @@ xserver_died (GObject *source, else if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND) { MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); - MetaDisplay *display = meta_get_display (); if (display->x11_display) meta_display_shutdown_x11 (display); @@ -381,6 +381,8 @@ meta_xwayland_override_display_number (int number) static gboolean open_display_sockets (MetaXWaylandManager *manager, int display_index, + int *abstract_fd_out, + int *unix_fd_out, gboolean *fatal) { int abstract_fd, unix_fd; @@ -398,14 +400,15 @@ open_display_sockets (MetaXWaylandManager *manager, return FALSE; } - manager->abstract_fd = abstract_fd; - manager->unix_fd = unix_fd; + *abstract_fd_out = abstract_fd; + *unix_fd_out = unix_fd; return TRUE; } static gboolean -choose_xdisplay (MetaXWaylandManager *manager) +choose_xdisplay (MetaXWaylandManager *manager, + MetaXWaylandConnection *connection) { int display = 0; char *lock_file = NULL; @@ -425,7 +428,10 @@ choose_xdisplay (MetaXWaylandManager *manager) return FALSE; } - if (!open_display_sockets (manager, display, &fatal)) + if (!open_display_sockets (manager, display, + &connection->abstract_fd, + &connection->unix_fd, + &fatal)) { unlink (lock_file); @@ -445,9 +451,9 @@ choose_xdisplay (MetaXWaylandManager *manager) } while (1); - manager->display_index = display; - manager->display_name = g_strdup_printf (":%d", manager->display_index); - manager->lock_file = lock_file; + connection->display_index = display; + connection->name = g_strdup_printf (":%d", connection->display_index); + connection->lock_file = lock_file; return TRUE; } @@ -611,14 +617,16 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager, launcher = g_subprocess_launcher_new (flags); g_subprocess_launcher_take_fd (launcher, xwayland_client_fd[1], 3); - g_subprocess_launcher_take_fd (launcher, manager->abstract_fd, 4); - g_subprocess_launcher_take_fd (launcher, manager->unix_fd, 5); + g_subprocess_launcher_take_fd (launcher, manager->public_connection.abstract_fd, 4); + g_subprocess_launcher_take_fd (launcher, manager->public_connection.unix_fd, 5); g_subprocess_launcher_take_fd (launcher, displayfd[1], 6); + g_subprocess_launcher_take_fd (launcher, manager->private_connection.abstract_fd, 7); g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE); manager->proc = g_subprocess_launcher_spawn (launcher, &error, - XWAYLAND_PATH, manager->display_name, + XWAYLAND_PATH, + manager->public_connection.name, "-rootless", "-noreset", "-accessx", @@ -627,7 +635,13 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager, "-listen", "4", "-listen", "5", "-displayfd", "6", +#ifdef HAVE_XWAYLAND_INITFD + "-initfd", "7", +#else + "-listen", "7", +#endif NULL); + if (!manager->proc) { g_task_return_error (task, error); @@ -728,9 +742,11 @@ meta_xwayland_init (MetaXWaylandManager *manager, MetaDisplayPolicy policy; gboolean fatal; - if (!manager->display_name) + if (!manager->public_connection.name) { - if (!choose_xdisplay (manager)) + if (!choose_xdisplay (manager, &manager->public_connection)) + return FALSE; + if (!choose_xdisplay (manager, &manager->private_connection)) return FALSE; if (!prepare_auth_file (manager)) @@ -738,7 +754,18 @@ meta_xwayland_init (MetaXWaylandManager *manager, } else { - if (!open_display_sockets (manager, manager->display_index, &fatal)) + if (!open_display_sockets (manager, + manager->public_connection.display_index, + &manager->public_connection.abstract_fd, + &manager->public_connection.unix_fd, + &fatal)) + return FALSE; + + if (!open_display_sockets (manager, + manager->private_connection.display_index, + &manager->private_connection.abstract_fd, + &manager->private_connection.unix_fd, + &fatal)) return FALSE; } @@ -747,7 +774,7 @@ meta_xwayland_init (MetaXWaylandManager *manager, if (policy == META_DISPLAY_POLICY_ON_DEMAND) { - g_unix_fd_add (manager->abstract_fd, G_IO_IN, + g_unix_fd_add (manager->public_connection.abstract_fd, G_IO_IN, xdisplay_connection_activity_cb, manager); } @@ -793,6 +820,13 @@ meta_xwayland_complete_init (MetaDisplay *display, } } +static void +meta_xwayland_connection_release (MetaXWaylandConnection *connection) +{ + unlink (connection->lock_file); + g_clear_pointer (&connection->lock_file, g_free); +} + void meta_xwayland_shutdown (MetaXWaylandManager *manager) { @@ -800,18 +834,21 @@ meta_xwayland_shutdown (MetaXWaylandManager *manager) g_cancellable_cancel (manager->xserver_died_cancellable); - snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->display_index); + snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->public_connection.display_index); unlink (path); - g_clear_pointer (&manager->display_name, g_free); + snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->private_connection.display_index); + unlink (path); + + g_clear_pointer (&manager->public_connection.name, g_free); + g_clear_pointer (&manager->private_connection.name, g_free); + + meta_xwayland_connection_release (&manager->public_connection); + meta_xwayland_connection_release (&manager->private_connection); + if (manager->auth_file) { unlink (manager->auth_file); g_clear_pointer (&manager->auth_file, g_free); } - if (manager->lock_file) - { - unlink (manager->lock_file); - g_clear_pointer (&manager->lock_file, g_free); - } }