Handle synthetic UnmapNotify events

According to the Inter-Client Communication Conventions Manual, if you want to
switch your window to withdrawn state, you unmap it and send a synthetic
UnmapNotify to the root window.

This synthetic event fixes a race condition. When you map and unmap a window
quickly, the map will generate a MapRequest for the WM but won't actually map
the window. Thus, the unmap will be discarded (-> window not yet mapped) and the
window stays map once the WM handles the MapRequest

Before this patch, awesome just ignored the synthetic unmap notify which caused
the bug to appear again. With this patch it doesn't happen anymore.

Signed-off-by: Uli Schlachter <psychon@znc.in>
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2009-12-28 16:41:39 +01:00
parent a4fb1e00f7
commit 742d85dd0e
1 changed files with 17 additions and 4 deletions

21
event.c
View File

@ -676,10 +676,23 @@ event_handle_unmapnotify(void *data __attribute__ ((unused)),
if((c = client_getbywin(ev->window))) if((c = client_getbywin(ev->window)))
{ {
if(ev->event == xutil_screen_get(connection, c->phys_screen)->root if(ev->event == xutil_screen_get(connection, c->phys_screen)->root)
&& XCB_EVENT_SENT(ev) {
&& window_state_get_reply(window_state_get_unchecked(c->window)) == XCB_WM_STATE_NORMAL) if(!XCB_EVENT_SENT(ev))
client_unmanage(c); {
/* A regular UnmapNotify, remove that client from our lists */
client_unmanage(c);
}
else
{
/* According to ICCCM 4.1.4 a client sends a synthetic
* UnmapNotify when it wants to switch to Widthdrawn state.
* We handle these by unmapping the client and waiting for the
* "real" UnmapNotify.
*/
xcb_unmap_window(connection, ev->window);
}
}
} }
else else
for(int i = 0; i < globalconf.embedded.len; i++) for(int i = 0; i < globalconf.embedded.len; i++)