summaryrefslogtreecommitdiff
path: root/src/compositor-x11.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compositor-x11.c')
-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: