diff --git a/banning.c b/banning.c index 0d746837c..faeea022b 100644 --- a/banning.c +++ b/banning.c @@ -31,18 +31,11 @@ static void reban(screen_t *screen) { - uint32_t select_input_val[] = { CLIENT_SELECT_INPUT_EVENT_MASK & ~(XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW) }; + client_ignore_enterleave_events(); foreach(_c, globalconf.clients) { client_t *c = *_c; - /* Bob Marley v2: - * While we arrange, we do not want to receive EnterNotify or LeaveNotify - * events, or we would get spurious events. */ - xcb_change_window_attributes(globalconf.connection, - c->win, - XCB_CW_EVENT_MASK, - select_input_val); /* Restore titlebar before client, so geometry is ok again. */ if(titlebar_isvisible(c, screen)) @@ -66,15 +59,9 @@ reban(screen_t *screen) client_ban(c); } - screen->need_reban = false; + client_restore_enterleave_events(); - /* Now, we want to receive EnterNotify and LeaveNotify events back. */ - select_input_val[0] = CLIENT_SELECT_INPUT_EVENT_MASK; - foreach(c, globalconf.clients) - xcb_change_window_attributes(globalconf.connection, - (*c)->win, - XCB_CW_EVENT_MASK, - select_input_val); + screen->need_reban = false; } /** Refresh the client disposition. diff --git a/client.c b/client.c index d05da3d18..5589fa8da 100644 --- a/client.c +++ b/client.c @@ -248,6 +248,29 @@ client_ban(client_t *c) } } +/** This is part of The Bob Marley Algorithmm: we ignore enter and leave window + * in certain cases, like map/unmap or move, so we don't get spurious events. + */ +void +client_ignore_enterleave_events(void) +{ + foreach(c, globalconf.clients) + xcb_change_window_attributes(globalconf.connection, + (*c)->win, + XCB_CW_EVENT_MASK, + (const uint32_t []) { CLIENT_SELECT_INPUT_EVENT_MASK & ~(XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW) }); +} + +void +client_restore_enterleave_events(void) +{ + foreach(c, globalconf.clients) + xcb_change_window_attributes(globalconf.connection, + (*c)->win, + XCB_CW_EVENT_MASK, + (const uint32_t []) { CLIENT_SELECT_INPUT_EVENT_MASK }); +} + /** Record that a client got focus. * \param c Client being focused. */ @@ -752,11 +775,16 @@ client_resize(client_t *c, area_t geometry, bool hints) titlebar_update_geometry(c); + /* Ignore all spurious enter/leave notify events */ + client_ignore_enterleave_events(); + xcb_configure_window(globalconf.connection, c->win, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values); + client_restore_enterleave_events(); + screen_client_moveto(c, new_screen, true, false); /* execute hook */ diff --git a/client.h b/client.h index 16142e836..2bdb69e12 100644 --- a/client.h +++ b/client.h @@ -195,6 +195,8 @@ void client_unfocus_update(client_t *); void client_stack_refresh(void); bool client_hasproto(client_t *, xcb_atom_t); void client_setfocus(client_t *, bool); +void client_ignore_enterleave_events(void); +void client_restore_enterleave_events(void); static inline void client_stack(void)