From 029539bf27827f03a35fc5b2cee923c3564935d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 30 May 2012 11:28:24 -0400 Subject: [PATCH] xwm: Handle reparenting windows --- src/xwayland/window-manager.c | 79 +++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c index 8d4c9768..de17c4e8 100644 --- a/src/xwayland/window-manager.c +++ b/src/xwayland/window-manager.c @@ -655,23 +655,12 @@ weston_wm_handle_property_notify(struct weston_wm *wm, xcb_generic_event_t *even } static void -weston_wm_handle_create_notify(struct weston_wm *wm, xcb_generic_event_t *event) +weston_wm_window_create(struct weston_wm *wm, + xcb_window_t id, int width, int height) { - xcb_create_notify_event_t *create_notify = - (xcb_create_notify_event_t *) event; struct weston_wm_window *window; uint32_t values[1]; - fprintf(stderr, - "XCB_CREATE_NOTIFY (window %d, width %d, height %d%s%s)\n", - create_notify->window, - create_notify->width, create_notify->height, - create_notify->override_redirect ? ", override" : "", - our_resource(wm, create_notify->window) ? ", ours" : ""); - - if (our_resource(wm, create_notify->window)) - return; - window = malloc(sizeof *window); if (window == NULL) { fprintf(stderr, "failed to allocate window\n"); @@ -679,18 +668,44 @@ weston_wm_handle_create_notify(struct weston_wm *wm, xcb_generic_event_t *event) } values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE; - xcb_change_window_attributes(wm->conn, create_notify->window, - XCB_CW_EVENT_MASK, values); + xcb_change_window_attributes(wm->conn, id, XCB_CW_EVENT_MASK, values); memset(window, 0, sizeof *window); window->wm = wm; - window->id = create_notify->window; + window->id = id; window->properties_dirty = 1; - window->width = create_notify->width; - window->height = create_notify->height; + window->width = width; + window->height = height; - hash_table_insert(wm->window_hash, window->id, window); + hash_table_insert(wm->window_hash, id, window); +} + +static void +weston_wm_window_destroy(struct weston_wm_window *window) +{ + hash_table_remove(window->wm->window_hash, window->id); + free(window); +} + +static void +weston_wm_handle_create_notify(struct weston_wm *wm, xcb_generic_event_t *event) +{ + xcb_create_notify_event_t *create_notify = + (xcb_create_notify_event_t *) event; + + fprintf(stderr, + "XCB_CREATE_NOTIFY (window %d, width %d, height %d%s%s)\n", + create_notify->window, + create_notify->width, create_notify->height, + create_notify->override_redirect ? ", override" : "", + our_resource(wm, create_notify->window) ? ", ours" : ""); + + if (our_resource(wm, create_notify->window)) + return; + + weston_wm_window_create(wm, create_notify->window, + create_notify->width, create_notify->height); } static void @@ -709,10 +724,29 @@ weston_wm_handle_destroy_notify(struct weston_wm *wm, xcb_generic_event_t *event return; window = hash_table_lookup(wm->window_hash, destroy_notify->window); + weston_wm_window_destroy(window); +} - hash_table_remove(wm->window_hash, window->id); +static void +weston_wm_handle_reparent_notify(struct weston_wm *wm, xcb_generic_event_t *event) +{ + xcb_reparent_notify_event_t *reparent_notify = + (xcb_reparent_notify_event_t *) event; + struct weston_wm_window *window; - free(window); + fprintf(stderr, + "XCB_REPARENT_NOTIFY (window %d, parent %d, event %d)\n", + reparent_notify->window, + reparent_notify->parent, + reparent_notify->event); + + if (reparent_notify->parent == wm->screen->root) { + weston_wm_window_create(wm, reparent_notify->window, 10, 10); + } else if (!our_resource(wm, reparent_notify->parent)) { + window = hash_table_lookup(wm->window_hash, + reparent_notify->window); + weston_wm_window_destroy(window); + } } static void @@ -862,6 +896,9 @@ weston_wm_handle_event(int fd, uint32_t mask, void *data) case XCB_UNMAP_NOTIFY: weston_wm_handle_unmap_notify(wm, event); break; + case XCB_REPARENT_NOTIFY: + weston_wm_handle_reparent_notify(wm, event); + break; case XCB_CONFIGURE_REQUEST: weston_wm_handle_configure_request(wm, event); break;