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);