x11: close display in an idle function
Closing a GdkDisplay during an event handler is not currently supported by Gdk and it will result in a crash when doing e.g. 'mutter --replace'. Using an idle function will close it safely in a subsequent main loop iteration. Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/595
This commit is contained in:
parent
92cccf53df
commit
31f525d566
@ -1138,6 +1138,18 @@ process_selection_request (MetaX11Display *x11_display,
|
|||||||
meta_verbose ("Handled selection request\n");
|
meta_verbose ("Handled selection request\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
close_display_idle_cb (gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaX11Display *x11_display = META_X11_DISPLAY (user_data);
|
||||||
|
|
||||||
|
meta_display_close (x11_display->display,
|
||||||
|
x11_display->xselectionclear_timestamp);
|
||||||
|
x11_display->display_close_idle = 0;
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
process_selection_clear (MetaX11Display *x11_display,
|
process_selection_clear (MetaX11Display *x11_display,
|
||||||
XEvent *event)
|
XEvent *event)
|
||||||
@ -1163,8 +1175,13 @@ process_selection_clear (MetaX11Display *x11_display,
|
|||||||
meta_verbose ("Got selection clear for on display %s\n",
|
meta_verbose ("Got selection clear for on display %s\n",
|
||||||
x11_display->name);
|
x11_display->name);
|
||||||
|
|
||||||
meta_display_close (x11_display->display,
|
/* We can't close a GdkDisplay in an even handler. */
|
||||||
event->xselectionclear.time);
|
if (!x11_display->display_close_idle)
|
||||||
|
{
|
||||||
|
x11_display->xselectionclear_timestamp = event->xselectionclear.time;
|
||||||
|
x11_display->display_close_idle = g_idle_add (close_display_idle_cb, x11_display);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1818,11 +1835,8 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display,
|
|||||||
{
|
{
|
||||||
if (process_selection_clear (x11_display, event))
|
if (process_selection_clear (x11_display, event))
|
||||||
{
|
{
|
||||||
/* This means we called meta_display_unmanage_screen, which
|
bypass_gtk = TRUE;
|
||||||
* means the MetaDisplay is effectively dead. We don't want
|
goto out;
|
||||||
* to poke into display->current_time below, since that would
|
|
||||||
* crash, so just directly return. */
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,9 @@ struct _MetaX11Display
|
|||||||
Atom wm_sn_atom;
|
Atom wm_sn_atom;
|
||||||
guint32 wm_sn_timestamp;
|
guint32 wm_sn_timestamp;
|
||||||
|
|
||||||
|
guint display_close_idle;
|
||||||
|
guint32 xselectionclear_timestamp;
|
||||||
|
|
||||||
Window wm_cm_selection_window;
|
Window wm_cm_selection_window;
|
||||||
|
|
||||||
Window composite_overlay_window;
|
Window composite_overlay_window;
|
||||||
|
@ -215,6 +215,12 @@ meta_x11_display_dispose (GObject *object)
|
|||||||
x11_display->gdk_display = NULL;
|
x11_display->gdk_display = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (x11_display->display_close_idle)
|
||||||
|
{
|
||||||
|
g_source_remove (x11_display->display_close_idle);
|
||||||
|
x11_display->display_close_idle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
g_free (x11_display->name);
|
g_free (x11_display->name);
|
||||||
x11_display->name = NULL;
|
x11_display->name = NULL;
|
||||||
|
|
||||||
@ -1186,6 +1192,9 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
|
|||||||
x11_display->timestamp_pinging_window = None;
|
x11_display->timestamp_pinging_window = None;
|
||||||
x11_display->wm_sn_selection_window = None;
|
x11_display->wm_sn_selection_window = None;
|
||||||
|
|
||||||
|
x11_display->display_close_idle = 0;
|
||||||
|
x11_display->xselectionclear_timestamp = 0;
|
||||||
|
|
||||||
x11_display->last_bell_time = 0;
|
x11_display->last_bell_time = 0;
|
||||||
x11_display->focus_serial = 0;
|
x11_display->focus_serial = 0;
|
||||||
x11_display->server_focus_window = None;
|
x11_display->server_focus_window = None;
|
||||||
|
Loading…
Reference in New Issue
Block a user