summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2015-01-27 16:26:49 -0600
committerBryce Harrington <bryce@osg.samsung.com>2015-02-04 19:51:34 -0800
commitd540f4bb76359988cdc54b12d7ae4268a07375fa (patch)
treeccd36ed27c6a45cab76f5c2fe658c3f64c116904
parent3e4d4bdd94f6db154e77df72cc2da366cf72629f (diff)
downloadweston-d540f4bb76359988cdc54b12d7ae4268a07375fa.tar.gz
compositor-x11: Move the x11 window close to an idle handler
The input loop is actually dispatched in the middle of the frame repaint. When the X11 event results in closing the compositor, this can cause the current output to be destroyed just prior to trying to process animations on it. We fix this by handling the window close event in an idle callback. NOTE: this requires a patch for wayland that moves the idle handler dispatch to after epoll_wait in the event loop processing. Closes bug: https://bugs.freedesktop.org/show_bug.cgi?id=81314 Signed-off-by: Derek Foreman <derekf@osg.samsung.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
-rw-r--r--src/compositor-x11.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 27922510..aa1e5197 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -117,6 +117,11 @@ struct x11_output {
int32_t scale;
};
+struct window_delete_data {
+ struct x11_compositor *compositor;
+ xcb_window_t window;
+};
+
struct gl_renderer_interface *gl_renderer;
static struct xkb_keymap *
@@ -941,6 +946,14 @@ x11_compositor_delete_window(struct x11_compositor *c, xcb_window_t window)
wl_display_terminate(c->base.wl_display);
}
+static void delete_cb(void *data)
+{
+ struct window_delete_data *wd = data;
+
+ x11_compositor_delete_window(wd->compositor, wd->window);
+ free(wd);
+}
+
#ifdef HAVE_XCB_XKB
static void
update_xkb_state(struct x11_compositor *c, xcb_xkb_state_notify_event_t *state)
@@ -1284,8 +1297,23 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
client_message = (xcb_client_message_event_t *) event;
atom = client_message->data.data32[0];
window = client_message->window;
- if (atom == c->atom.wm_delete_window)
- x11_compositor_delete_window(c, window);
+ if (atom == c->atom.wm_delete_window) {
+ struct wl_event_loop *loop;
+ struct window_delete_data *data = malloc(sizeof *data);
+
+ /* if malloc failed we should at least try to
+ * delete the window, even if it may result in
+ * a crash.
+ */
+ if (!data) {
+ x11_compositor_delete_window(c, window);
+ break;
+ }
+ data->compositor = c;
+ data->window = window;
+ loop = wl_display_get_event_loop(c->base.wl_display);
+ wl_event_loop_add_idle(loop, delete_cb, data);
+ }
break;
case XCB_FOCUS_IN: