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 <psychon@znc.in>
This commit is contained in:
parent
547f732b00
commit
af8fd15a8f
8
event.c
8
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue