From af8fd15a8f50fc741ff6de2cd67049364f3ac8e3 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Thu, 7 Oct 2010 12:05:43 +0200 Subject: [PATCH] client_unmanage(): Handle destroyed windows When we receive a DestroyNotify, we have to unmanage the client. However, we were just informed that the window was destroyed, so it doesn't make sense to try to do "something" with the window. This commits fixes some errors from the X server (which we ignored, but still they are gone now). Signed-off-by: Uli Schlachter --- event.c | 8 +++----- objects/client.c | 38 +++++++++++++++++++++++--------------- objects/client.h | 2 +- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/event.c b/event.c index ac9bb640..2eb6ec96 100644 --- a/event.c +++ b/event.c @@ -324,7 +324,7 @@ event_handle_destroynotify(xcb_destroy_notify_event_t *ev) client_t *c; if((c = client_getbywin(ev->window))) - client_unmanage(c); + client_unmanage(c, false); else for(int i = 0; i < globalconf.embedded.len; i++) if(globalconf.embedded.tab[i].win == ev->window) @@ -572,9 +572,7 @@ event_handle_unmapnotify(xcb_unmap_notify_event_t *ev) client_t *c; if((c = client_getbywin(ev->window))) - { - client_unmanage(c); - } + client_unmanage(c, true); else for(int i = 0; i < globalconf.embedded.len; i++) if(globalconf.embedded.tab[i].win == ev->window) @@ -687,7 +685,7 @@ event_handle_reparentnotify(xcb_reparent_notify_event_t *ev) /* Ignore reparents to the root window, they *might* be caused by * ourselves if a client quickly unmaps and maps itself again. */ if (ev->parent != globalconf.screen->root) - client_unmanage(c); + client_unmanage(c, true); } } diff --git a/objects/client.c b/objects/client.c index 1dbbf8fc..8892dd94 100644 --- a/objects/client.c +++ b/objects/client.c @@ -937,9 +937,10 @@ client_unban(client_t *c) /** Unmanage a client. * \param c The client. + * \param window_valid Is the client's window still valid? */ void -client_unmanage(client_t *c) +client_unmanage(client_t *c, bool window_valid) { tag_array_t *tags = &c->screen->tags; @@ -979,27 +980,34 @@ client_unmanage(client_t *c) /* Clear our event mask so that we don't receive any events from now on, * especially not for the following requests. */ - xcb_change_window_attributes(globalconf.connection, - c->window, - XCB_CW_EVENT_MASK, - (const uint32_t []) { 0 }); + if(window_valid) + xcb_change_window_attributes(globalconf.connection, + c->window, + XCB_CW_EVENT_MASK, + (const uint32_t []) { 0 }); xcb_change_window_attributes(globalconf.connection, c->frame_window, XCB_CW_EVENT_MASK, (const uint32_t []) { 0 }); - xcb_unmap_window(globalconf.connection, c->window); - xcb_reparent_window(globalconf.connection, c->window, globalconf.screen->root, - c->geometry.x, c->geometry.y); + if(window_valid) + { + xcb_unmap_window(globalconf.connection, c->window); + xcb_reparent_window(globalconf.connection, c->window, globalconf.screen->root, + c->geometry.x, c->geometry.y); + } xcb_destroy_window(globalconf.connection, c->frame_window); - /* Remove this window from the save set since this shouldn't be made visible - * after a restart anymore. */ - xcb_change_save_set(globalconf.connection, XCB_SET_MODE_DELETE, c->window); + if(window_valid) + { + /* Remove this window from the save set since this shouldn't be made visible + * after a restart anymore. */ + xcb_change_save_set(globalconf.connection, XCB_SET_MODE_DELETE, c->window); - /* Do this last to avoid races with clients. According to ICCCM, clients - * arent allowed to re-use the window until after this. */ - xwindow_set_state(c->window, XCB_WM_STATE_WITHDRAWN); + /* Do this last to avoid races with clients. According to ICCCM, clients + * arent allowed to re-use the window until after this. */ + xwindow_set_state(c->window, XCB_WM_STATE_WITHDRAWN); + } /* set client as invalid */ c->window = XCB_NONE; @@ -1234,7 +1242,7 @@ static int luaA_client_unmanage(lua_State *L) { client_t *c = luaA_checkudata(L, 1, &client_class); - client_unmanage(c); + client_unmanage(c, true); return 0; } diff --git a/objects/client.h b/objects/client.h index b6a0637e..3a24e00a 100644 --- a/objects/client.h +++ b/objects/client.h @@ -118,7 +118,7 @@ void client_unban(client_t *); void client_manage(xcb_window_t, xcb_get_geometry_reply_t *, bool); area_t client_geometry_hints(client_t *, area_t); bool client_resize(client_t *, area_t, bool); -void client_unmanage(client_t *); +void client_unmanage(client_t *, bool); void client_kill(client_t *); void client_set_sticky(lua_State *, int, bool); void client_set_above(lua_State *, int, bool);