diff --git a/config.h.meson b/config.h.meson index b2a23596f..f4d6000e1 100644 --- a/config.h.meson +++ b/config.h.meson @@ -71,6 +71,9 @@ /* Whether Xwayland has -initfd option */ #mesondefine HAVE_XWAYLAND_INITFD +/* Whether libX11 has XSetIOErrorExitHandler */ +#mesondefine HAVE_XSETIOERROREXITHANDLER + /* Whether the mkostemp function exists */ #mesondefine HAVE_MKOSTEMP diff --git a/meson.build b/meson.build index 885437931..07b2d0066 100644 --- a/meson.build +++ b/meson.build @@ -424,6 +424,13 @@ if have_wayland endif endif +have_xsetioerrorexithandler = false +if cc.has_function('XSetIOErrorExitHandler', dependencies: x11_dep, + prefix: '''#include ''') + have_xsetioerrorexithandler = true + cdata.set('HAVE_XSETIOERROREXITHANDLER', 1) +endif + optional_functions = [ 'mkostemp', 'posix_fallocate', @@ -495,6 +502,7 @@ output = [ ' Introspection............ ' + have_introspection.to_string(), ' Profiler................. ' + have_profiler.to_string(), ' Xwayland initfd.......... ' + have_xwayland_initfd.to_string(), + ' Safe X11 I/O errors...... ' + have_xsetioerrorexithandler.to_string(), '', ' Tests:', '', diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 88a04e5a2..f3dd19260 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -334,6 +334,20 @@ x_io_error (Display *display) return 0; } +#ifdef HAVE_XSETIOERROREXITHANDLER +static void +x_io_error_exit (Display *display, + MetaX11Display *x11_display) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandManager *manager = &compositor->xwayland_manager; + + g_warning ("Xwayland just died, attempting to recover"); + manager->xserver_grace_period_id = + g_idle_add (shutdown_xwayland_cb, manager); +} +#endif + void meta_xwayland_override_display_number (int number) { @@ -795,6 +809,9 @@ meta_xwayland_complete_init (MetaDisplay *display, we won't reset the tty). */ XSetIOErrorHandler (x_io_error); +#ifdef HAVE_XSETIOERROREXITHANDLER + XSetIOErrorExitHandler (xdisplay, x_io_error_exit, display); +#endif g_signal_connect (display, "x11-display-closing", G_CALLBACK (on_x11_display_closing), NULL);