xwayland: Make setup/teardown a bit more symmetrical

We setup Xwayland in an early phase of the X11 display, before we had a
MetaX11Display, and teared down in a couple of places happening when
tearing down the Xwayland integration if the X server died or
terminated. It was a bit hard to follow what happened and when it
happened. Attempt to clean this up a bit, with things being structured
as follows:

 * Early during X11 display connection setup, only setup the rudimentary
   X11 hooks, being the libX11 error callbacks, and adding the local
   user to XHost.

 * Move "initialize Xwayland component" code to a new
   'x11-display-setup' signal handler. Things setup here are cleaned up
   in the 'x11-display-closing' handler.

 * Connect to 'x11-display-setup' and 'x11-display-closing' up front,
   and stay connected to these two.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1796>
This commit is contained in:
Jonas Ådahl 2021-03-23 16:47:45 +01:00
parent 69f9b36643
commit b4fe1fdd95
6 changed files with 62 additions and 25 deletions

View File

@ -889,8 +889,12 @@ meta_display_new (MetaContext *context,
#ifdef HAVE_WAYLAND
if (meta_is_wayland_compositor ())
{
MetaWaylandCompositor *wayland_compositor =
meta_wayland_compositor_get_default ();
MetaX11DisplayPolicy x11_display_policy;
meta_wayland_compositor_init_display (wayland_compositor, display);
x11_display_policy = meta_context_get_x11_display_policy (context);
if (x11_display_policy == META_X11_DISPLAY_POLICY_MANDATORY)
{

View File

@ -400,6 +400,13 @@ set_gnome_env (const char *name,
}
}
void
meta_wayland_compositor_init_display (MetaWaylandCompositor *compositor,
MetaDisplay *display)
{
meta_xwayland_init_display (&compositor->xwayland_manager, display);
}
static void meta_wayland_log_func (const char *, va_list) G_GNUC_PRINTF (1, 0);
static void

View File

@ -36,6 +36,9 @@ MetaWaylandCompositor * meta_wayland_compositor_new (MetaContext *co
void meta_wayland_compositor_prepare_shutdown (MetaWaylandCompositor *compositor);
void meta_wayland_compositor_init_display (MetaWaylandCompositor *compositor,
MetaDisplay *display);
META_EXPORT_TEST
MetaWaylandCompositor *meta_wayland_compositor_get_default (void);

View File

@ -31,8 +31,12 @@ meta_xwayland_init (MetaXWaylandManager *manager,
GError **error);
void
meta_xwayland_complete_init (MetaDisplay *display,
Display *xdisplay);
meta_xwayland_init_display (MetaXWaylandManager *manager,
MetaDisplay *display);
void
meta_xwayland_setup_xdisplay (MetaXWaylandManager *manager,
Display *xdisplay);
void
meta_xwayland_shutdown (MetaXWaylandManager *manager);

View File

@ -1137,9 +1137,6 @@ meta_xwayland_stop_xserver (MetaXWaylandManager *manager)
{
if (manager->proc)
g_subprocess_send_signal (manager->proc, SIGTERM);
g_signal_handlers_disconnect_by_func (meta_get_display (),
window_created_cb,
manager);
g_clear_object (&manager->xserver_died_cancellable);
g_clear_object (&manager->proc);
}
@ -1230,6 +1227,9 @@ on_x11_display_closing (MetaDisplay *display,
g_signal_handlers_disconnect_by_func (display,
on_x11_display_closing,
manager);
g_signal_handlers_disconnect_by_func (display,
window_created_cb,
manager);
}
static void
@ -1254,15 +1254,41 @@ meta_xwayland_init_xrandr (MetaXWaylandManager *manager,
meta_xwayland_set_primary_output (xdisplay);
}
/* To be called right after connecting */
void
meta_xwayland_complete_init (MetaDisplay *display,
Display *xdisplay)
static void
on_x11_display_setup (MetaDisplay *display,
MetaXWaylandManager *manager)
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaXWaylandManager *manager = &compositor->xwayland_manager;
MetaX11Display *x11_display = meta_display_get_x11_display (display);
MetaContext *context = meta_display_get_context (display);
Display *xdisplay = meta_x11_display_get_xdisplay (x11_display);
MetaX11DisplayPolicy x11_display_policy;
meta_xwayland_init_dnd (xdisplay);
meta_xwayland_init_xrandr (manager, xdisplay);
meta_xwayland_stop_xserver_timeout (manager);
x11_display_policy = meta_context_get_x11_display_policy (context);
if (x11_display_policy == META_X11_DISPLAY_POLICY_ON_DEMAND)
{
g_signal_connect (display, "window-created",
G_CALLBACK (window_created_cb), manager);
}
}
void
meta_xwayland_init_display (MetaXWaylandManager *manager,
MetaDisplay *display)
{
g_signal_connect (display, "x11-display-setup",
G_CALLBACK (on_x11_display_setup), manager);
g_signal_connect (display, "x11-display-closing",
G_CALLBACK (on_x11_display_closing), manager);
}
void
meta_xwayland_setup_xdisplay (MetaXWaylandManager *manager,
Display *xdisplay)
{
/* We install an X IO error handler in addition to the child watch,
because after Xlib connects our child watch may not be called soon
enough, and therefore we won't crash when X exits (and most important
@ -1273,20 +1299,7 @@ meta_xwayland_complete_init (MetaDisplay *display,
XSetIOErrorExitHandler (xdisplay, x_io_error_exit, manager);
#endif
g_signal_connect (display, "x11-display-closing",
G_CALLBACK (on_x11_display_closing), manager);
meta_xwayland_init_dnd (xdisplay);
add_local_user_to_xhost (xdisplay);
meta_xwayland_init_xrandr (manager, xdisplay);
x11_display_policy =
meta_context_get_x11_display_policy (compositor->context);
if (x11_display_policy == META_X11_DISPLAY_POLICY_ON_DEMAND)
{
meta_xwayland_stop_xserver_timeout (manager);
g_signal_connect (meta_get_display (), "window-created",
G_CALLBACK (window_created_cb), manager);
}
}
static void

View File

@ -1151,7 +1151,13 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
#ifdef HAVE_WAYLAND
if (meta_is_wayland_compositor ())
meta_xwayland_complete_init (display, xdisplay);
{
MetaContext *context = meta_display_get_context (display);
MetaWaylandCompositor *compositor =
meta_context_get_wayland_compositor (context);
meta_xwayland_setup_xdisplay (&compositor->xwayland_manager, xdisplay);
}
#endif
if (meta_is_syncing ())