mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 09:30:45 -05:00
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
This commit is contained in:
parent
1caaf0cd1e
commit
f635876eac
@ -612,6 +612,22 @@ meta_init (void)
|
|||||||
meta_fatal ("Can't specify both SM save file and SM client id\n");
|
meta_fatal ("Can't specify both SM save file and SM client id\n");
|
||||||
|
|
||||||
meta_main_loop = g_main_loop_new (NULL, FALSE);
|
meta_main_loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to make sure the first client connecting to the X server
|
||||||
|
* (e.g. Xwayland started from meta_wayland_init() above) is a permanent one,
|
||||||
|
* so prepare the GDK X11 connection now already. Without doing this, if
|
||||||
|
* there are any functionality that relies on X11 after here before
|
||||||
|
* meta_display_open(), the X server will terminate itself when such a client
|
||||||
|
* disconnects before the permanent GDK client connects.
|
||||||
|
*/
|
||||||
|
if (meta_should_autostart_x11_display ())
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!meta_x11_init_gdk_display (&error))
|
||||||
|
g_error ("Failed to open X11 display: %s", error->message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#define META_TYPE_X11_DISPLAY (meta_x11_display_get_type ())
|
#define META_TYPE_X11_DISPLAY (meta_x11_display_get_type ())
|
||||||
G_DECLARE_FINAL_TYPE (MetaX11Display, meta_x11_display, META, X11_DISPLAY, GObject)
|
G_DECLARE_FINAL_TYPE (MetaX11Display, meta_x11_display, META, X11_DISPLAY, GObject)
|
||||||
|
|
||||||
|
gboolean meta_x11_init_gdk_display (GError **error);
|
||||||
|
|
||||||
int meta_x11_display_get_screen_number (MetaX11Display *x11_display);
|
int meta_x11_display_get_screen_number (MetaX11Display *x11_display);
|
||||||
Display *meta_x11_display_get_xdisplay (MetaX11Display *x11_display);
|
Display *meta_x11_display_get_xdisplay (MetaX11Display *x11_display);
|
||||||
Window meta_x11_display_get_xroot (MetaX11Display *x11_display);
|
Window meta_x11_display_get_xroot (MetaX11Display *x11_display);
|
||||||
|
@ -80,6 +80,8 @@ typedef struct _MetaX11DisplayLogicalMonitorData
|
|||||||
int xinerama_index;
|
int xinerama_index;
|
||||||
} MetaX11DisplayLogicalMonitorData;
|
} MetaX11DisplayLogicalMonitorData;
|
||||||
|
|
||||||
|
static GdkDisplay *prepared_gdk_display = NULL;
|
||||||
|
|
||||||
static const char *gnome_wm_keybindings = "Mutter";
|
static const char *gnome_wm_keybindings = "Mutter";
|
||||||
static const char *net_wm_name = "Mutter";
|
static const char *net_wm_name = "Mutter";
|
||||||
|
|
||||||
@ -972,6 +974,79 @@ meta_set_gnome_wm_keybindings (const char *wm_keybindings)
|
|||||||
gnome_wm_keybindings = wm_keybindings;
|
gnome_wm_keybindings = wm_keybindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_x11_init_gdk_display (GError **error)
|
||||||
|
{
|
||||||
|
const char *xdisplay_name;
|
||||||
|
GdkDisplay *gdk_display;
|
||||||
|
const char *gdk_gl_env = NULL;
|
||||||
|
Display *xdisplay;
|
||||||
|
|
||||||
|
xdisplay_name = g_getenv ("DISPLAY");
|
||||||
|
if (!xdisplay_name)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Unable to open display, DISPLAY not set");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdk_set_allowed_backends ("x11");
|
||||||
|
|
||||||
|
gdk_gl_env = g_getenv ("GDK_GL");
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (!gdk_display)
|
||||||
|
{
|
||||||
|
meta_warning (_("Failed to initialize GDK\n"));
|
||||||
|
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Failed to initialize GDK");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gdk_gl_env)
|
||||||
|
g_setenv("GDK_GL", gdk_gl_env, TRUE);
|
||||||
|
else
|
||||||
|
unsetenv("GDK_GL");
|
||||||
|
|
||||||
|
/* We need to be able to fully trust that the window and monitor sizes
|
||||||
|
that Gdk reports corresponds to the X ones, so we disable the automatic
|
||||||
|
scale handling */
|
||||||
|
gdk_x11_display_set_window_scale (gdk_display, 1);
|
||||||
|
|
||||||
|
meta_verbose ("Opening display '%s'\n", XDisplayName (NULL));
|
||||||
|
|
||||||
|
xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display);
|
||||||
|
|
||||||
|
if (xdisplay == NULL)
|
||||||
|
{
|
||||||
|
meta_warning (_("Failed to open X Window System display “%s”\n"),
|
||||||
|
XDisplayName (NULL));
|
||||||
|
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Failed to open X11 display");
|
||||||
|
|
||||||
|
gdk_display_close (gdk_display);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
prepared_gdk_display = gdk_display;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_x11_display_new:
|
* meta_x11_display_new:
|
||||||
*
|
*
|
||||||
@ -1000,47 +1075,10 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
|
|||||||
Atom atom_restart_helper;
|
Atom atom_restart_helper;
|
||||||
Window restart_helper_window = None;
|
Window restart_helper_window = None;
|
||||||
GdkDisplay *gdk_display;
|
GdkDisplay *gdk_display;
|
||||||
const char *gdk_gl_env = NULL;
|
|
||||||
const char *xdisplay_name;
|
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaMonitorManager *monitor_manager =
|
MetaMonitorManager *monitor_manager =
|
||||||
meta_backend_get_monitor_manager (backend);
|
meta_backend_get_monitor_manager (backend);
|
||||||
|
|
||||||
xdisplay_name = g_getenv ("DISPLAY");
|
|
||||||
if (!xdisplay_name)
|
|
||||||
{
|
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
||||||
"Unable to open display, DISPLAY not set");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gdk_set_allowed_backends ("x11");
|
|
||||||
|
|
||||||
gdk_gl_env = g_getenv ("GDK_GL");
|
|
||||||
g_setenv("GDK_GL", "disable", TRUE);
|
|
||||||
|
|
||||||
gdk_display = gdk_display_open (xdisplay_name);
|
|
||||||
|
|
||||||
if (!gdk_display)
|
|
||||||
{
|
|
||||||
meta_warning (_("Failed to initialize GDK\n"));
|
|
||||||
|
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
||||||
"Failed to initialize GDK");
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gdk_gl_env)
|
|
||||||
g_setenv("GDK_GL", gdk_gl_env, TRUE);
|
|
||||||
else
|
|
||||||
unsetenv("GDK_GL");
|
|
||||||
|
|
||||||
/* We need to be able to fully trust that the window and monitor sizes
|
|
||||||
that Gdk reports corresponds to the X ones, so we disable the automatic
|
|
||||||
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. */
|
/* A list of all atom names, so that we can intern them in one go. */
|
||||||
const char *atom_names[] = {
|
const char *atom_names[] = {
|
||||||
#define item(x) #x,
|
#define item(x) #x,
|
||||||
@ -1049,28 +1087,16 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
|
|||||||
};
|
};
|
||||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||||
|
|
||||||
meta_verbose ("Opening display '%s'\n", XDisplayName (NULL));
|
g_assert (prepared_gdk_display);
|
||||||
|
gdk_display = g_steal_pointer (&prepared_gdk_display);
|
||||||
xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display);
|
|
||||||
|
|
||||||
if (xdisplay == NULL)
|
|
||||||
{
|
|
||||||
meta_warning (_("Failed to open X Window System display “%s”\n"),
|
|
||||||
XDisplayName (NULL));
|
|
||||||
|
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
||||||
"Failed to open X11 display");
|
|
||||||
|
|
||||||
gdk_display_close (gdk_display);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_WAYLAND
|
#ifdef HAVE_WAYLAND
|
||||||
if (meta_is_wayland_compositor ())
|
if (meta_is_wayland_compositor ())
|
||||||
meta_xwayland_complete_init (display);
|
meta_xwayland_complete_init (display);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display);
|
||||||
|
|
||||||
if (meta_is_syncing ())
|
if (meta_is_syncing ())
|
||||||
XSynchronize (xdisplay, True);
|
XSynchronize (xdisplay, True);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user