diff --git a/src/x11/events.c b/src/x11/events.c index 59caeb4b9..1e77538db 100644 --- a/src/x11/events.c +++ b/src/x11/events.c @@ -1138,6 +1138,18 @@ process_selection_request (MetaX11Display *x11_display, 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 process_selection_clear (MetaX11Display *x11_display, XEvent *event) @@ -1163,8 +1175,13 @@ process_selection_clear (MetaX11Display *x11_display, meta_verbose ("Got selection clear for on display %s\n", x11_display->name); - meta_display_close (x11_display->display, - event->xselectionclear.time); + /* We can't close a GdkDisplay in an even handler. */ + 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; } @@ -1818,11 +1835,8 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display, { if (process_selection_clear (x11_display, event)) { - /* This means we called meta_display_unmanage_screen, which - * means the MetaDisplay is effectively dead. We don't want - * to poke into display->current_time below, since that would - * crash, so just directly return. */ - return TRUE; + bypass_gtk = TRUE; + goto out; } } diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h index 05019e8cf..fdd642bbc 100644 --- a/src/x11/meta-x11-display-private.h +++ b/src/x11/meta-x11-display-private.h @@ -92,6 +92,9 @@ struct _MetaX11Display Atom wm_sn_atom; guint32 wm_sn_timestamp; + guint display_close_idle; + guint32 xselectionclear_timestamp; + Window wm_cm_selection_window; Window composite_overlay_window; diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 83f7dfbae..4a6d64e08 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -215,6 +215,12 @@ meta_x11_display_dispose (GObject *object) 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); x11_display->name = NULL; @@ -1186,6 +1192,9 @@ meta_x11_display_new (MetaDisplay *display, GError **error) x11_display->timestamp_pinging_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->focus_serial = 0; x11_display->server_focus_window = None;