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 #ifdef HAVE_WAYLAND
if (meta_is_wayland_compositor ()) if (meta_is_wayland_compositor ())
{ {
MetaWaylandCompositor *wayland_compositor =
meta_wayland_compositor_get_default ();
MetaX11DisplayPolicy x11_display_policy; MetaX11DisplayPolicy x11_display_policy;
meta_wayland_compositor_init_display (wayland_compositor, display);
x11_display_policy = meta_context_get_x11_display_policy (context); x11_display_policy = meta_context_get_x11_display_policy (context);
if (x11_display_policy == META_X11_DISPLAY_POLICY_MANDATORY) 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 meta_wayland_log_func (const char *, va_list) G_GNUC_PRINTF (1, 0);
static void 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_prepare_shutdown (MetaWaylandCompositor *compositor);
void meta_wayland_compositor_init_display (MetaWaylandCompositor *compositor,
MetaDisplay *display);
META_EXPORT_TEST META_EXPORT_TEST
MetaWaylandCompositor *meta_wayland_compositor_get_default (void); MetaWaylandCompositor *meta_wayland_compositor_get_default (void);

View File

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

View File

@ -1137,9 +1137,6 @@ meta_xwayland_stop_xserver (MetaXWaylandManager *manager)
{ {
if (manager->proc) if (manager->proc)
g_subprocess_send_signal (manager->proc, SIGTERM); 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->xserver_died_cancellable);
g_clear_object (&manager->proc); g_clear_object (&manager->proc);
} }
@ -1230,6 +1227,9 @@ on_x11_display_closing (MetaDisplay *display,
g_signal_handlers_disconnect_by_func (display, g_signal_handlers_disconnect_by_func (display,
on_x11_display_closing, on_x11_display_closing,
manager); manager);
g_signal_handlers_disconnect_by_func (display,
window_created_cb,
manager);
} }
static void static void
@ -1254,15 +1254,41 @@ meta_xwayland_init_xrandr (MetaXWaylandManager *manager,
meta_xwayland_set_primary_output (xdisplay); meta_xwayland_set_primary_output (xdisplay);
} }
/* To be called right after connecting */ static void
void on_x11_display_setup (MetaDisplay *display,
meta_xwayland_complete_init (MetaDisplay *display, MetaXWaylandManager *manager)
Display *xdisplay)
{ {
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); MetaX11Display *x11_display = meta_display_get_x11_display (display);
MetaXWaylandManager *manager = &compositor->xwayland_manager; MetaContext *context = meta_display_get_context (display);
Display *xdisplay = meta_x11_display_get_xdisplay (x11_display);
MetaX11DisplayPolicy x11_display_policy; 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, /* 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 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 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); XSetIOErrorExitHandler (xdisplay, x_io_error_exit, manager);
#endif #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); 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 static void

View File

@ -1151,7 +1151,13 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
#ifdef HAVE_WAYLAND #ifdef HAVE_WAYLAND
if (meta_is_wayland_compositor ()) 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 #endif
if (meta_is_syncing ()) if (meta_is_syncing ())