diff options
author | Jonas Ådahl <jadahl@gmail.com> | 2017-12-26 15:58:54 +0800 |
---|---|---|
committer | Jonas Ådahl <jadahl@gmail.com> | 2018-07-06 19:54:46 +0200 |
commit | f635876eac2b892991a791009ff88d3975cb2c9a (patch) | |
tree | b441f954faeae73a4e9a22d0597cf3017fb5902f /src/x11/meta-x11-display.c | |
parent | 1caaf0cd1e770433f0c6ecc3a92f376fa2ed46f5 (diff) | |
download | mutter-f635876eac2b892991a791009ff88d3975cb2c9a.tar.gz |
x11: Open window decoration X11 connection earlier
If we wait with opening the X11 window decoration GDK connection, we
might end up with a terminated X11 server before we finish
initializing, depending on the things happening after spawning Xwayland
and before opening the MetaX11Dispaly. In gnome-shell, this involves
e.g. creating a couple of temporary X11 connections, and on disconnect,
if they happen to be the last client, the X server will terminate
itself.
https://bugzilla.gnome.org/show_bug.cgi?id=759538
Diffstat (limited to 'src/x11/meta-x11-display.c')
-rw-r--r-- | src/x11/meta-x11-display.c | 108 |
1 files changed, 67 insertions, 41 deletions
diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 3dd7f204d..f5bff0da9 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -80,6 +80,8 @@ typedef struct _MetaX11DisplayLogicalMonitorData int xinerama_index; } MetaX11DisplayLogicalMonitorData; +static GdkDisplay *prepared_gdk_display = NULL; + static const char *gnome_wm_keybindings = "Mutter"; static const char *net_wm_name = "Mutter"; @@ -972,39 +974,13 @@ meta_set_gnome_wm_keybindings (const char *wm_keybindings) gnome_wm_keybindings = wm_keybindings; } -/** - * meta_x11_display_new: - * - * Opens a new X11 display, sets it up, initialises all the X extensions - * we will need. - * - * Returns: #MetaX11Display if the display was opened successfully, - * and %NULL otherwise-- that is, if the display doesn't exist or - * it already has a window manager, and sets the error appropriately. - */ -MetaX11Display * -meta_x11_display_new (MetaDisplay *display, GError **error) +gboolean +meta_x11_init_gdk_display (GError **error) { - MetaX11Display *x11_display; - Display *xdisplay; - Screen *xscreen; - Window xroot; - int i, number; - Window new_wm_sn_owner; - gboolean replace_current_wm; - Atom wm_sn_atom; - char buf[128]; - guint32 timestamp; - MetaWorkspace *current_workspace; - uint32_t current_workspace_index = 0; - Atom atom_restart_helper; - Window restart_helper_window = None; + const char *xdisplay_name; GdkDisplay *gdk_display; const char *gdk_gl_env = NULL; - const char *xdisplay_name; - MetaBackend *backend = meta_get_backend (); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); + Display *xdisplay; xdisplay_name = g_getenv ("DISPLAY"); if (!xdisplay_name) @@ -1017,7 +993,15 @@ meta_x11_display_new (MetaDisplay *display, GError **error) gdk_set_allowed_backends ("x11"); gdk_gl_env = g_getenv ("GDK_GL"); - g_setenv("GDK_GL", "disable", TRUE); + g_setenv ("GDK_GL", "disable", TRUE); + + gdk_parse_args (NULL, NULL); + if (!gtk_parse_args (NULL, NULL)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to initialize gtk"); + return FALSE; + } gdk_display = gdk_display_open (xdisplay_name); @@ -1028,7 +1012,7 @@ meta_x11_display_new (MetaDisplay *display, GError **error) g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to initialize GDK"); - return NULL; + return FALSE; } if (gdk_gl_env) @@ -1041,14 +1025,6 @@ meta_x11_display_new (MetaDisplay *display, GError **error) scale handling */ gdk_x11_display_set_window_scale (gdk_display, 1); - /* A list of all atom names, so that we can intern them in one go. */ - const char *atom_names[] = { -#define item(x) #x, -#include "x11/atomnames.h" -#undef item - }; - Atom atoms[G_N_ELEMENTS(atom_names)]; - meta_verbose ("Opening display '%s'\n", XDisplayName (NULL)); xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display); @@ -1063,14 +1039,64 @@ meta_x11_display_new (MetaDisplay *display, GError **error) gdk_display_close (gdk_display); - return NULL; + return FALSE; } + prepared_gdk_display = gdk_display; + + return TRUE; +} + +/** + * meta_x11_display_new: + * + * Opens a new X11 display, sets it up, initialises all the X extensions + * we will need. + * + * Returns: #MetaX11Display if the display was opened successfully, + * and %NULL otherwise-- that is, if the display doesn't exist or + * it already has a window manager, and sets the error appropriately. + */ +MetaX11Display * +meta_x11_display_new (MetaDisplay *display, GError **error) +{ + MetaX11Display *x11_display; + Display *xdisplay; + Screen *xscreen; + Window xroot; + int i, number; + Window new_wm_sn_owner; + gboolean replace_current_wm; + Atom wm_sn_atom; + char buf[128]; + guint32 timestamp; + MetaWorkspace *current_workspace; + uint32_t current_workspace_index = 0; + Atom atom_restart_helper; + Window restart_helper_window = None; + GdkDisplay *gdk_display; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + + /* A list of all atom names, so that we can intern them in one go. */ + const char *atom_names[] = { +#define item(x) #x, +#include "x11/atomnames.h" +#undef item + }; + Atom atoms[G_N_ELEMENTS(atom_names)]; + + g_assert (prepared_gdk_display); + gdk_display = g_steal_pointer (&prepared_gdk_display); + #ifdef HAVE_WAYLAND if (meta_is_wayland_compositor ()) meta_xwayland_complete_init (display); #endif + xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display); + if (meta_is_syncing ()) XSynchronize (xdisplay, True); |