diff --git a/client.c b/client.c index bb204e20..4ba84dc0 100644 --- a/client.c +++ b/client.c @@ -191,12 +191,55 @@ client_unfocus(client_t *c) { xcb_window_t root_win = xutil_screen_get(globalconf.connection, c->phys_screen)->root; - /* Set focus on root window, so no events leak to the current window. */ - window_setfocus(root_win, true); + /* Set focus on root window, so no events leak to the current window. + * This kind of inlines client_setfocus(), but a root window will never have + * the WM_TAKE_FOCUS protocol. + */ + xcb_set_input_focus(globalconf.connection, XCB_INPUT_FOCUS_PARENT, + root_win, XCB_CURRENT_TIME); client_unfocus_update(c); } +/** Check if client supports protocol a protocole in WM_PROTOCOL. + * \param c The client. + * \return True if client has the atom in protocol, false otherwise. + */ +bool +client_hasproto(client_t *c, xcb_atom_t atom) +{ + uint32_t i; + xcb_get_wm_protocols_reply_t protocols; + bool ret = false; + + if(xcb_get_wm_protocols_reply(globalconf.connection, + xcb_get_wm_protocols_unchecked(globalconf.connection, + c->win, WM_PROTOCOLS), + &protocols, NULL)) + { + for(i = 0; !ret && i < protocols.atoms_len; i++) + if(protocols.atoms[i] == atom) + ret = true; + xcb_get_wm_protocols_reply_wipe(&protocols); + } + return ret; +} + +/** Sets focus on window - using xcb_set_input_focus or WM_TAKE_FOCUS + * \param c Client that should get focus + * \param set_input_focus Should we call xcb_set_input_focus + */ +void +client_setfocus(client_t *c, bool set_input_focus) +{ + bool takefocus = client_hasproto(c, WM_TAKE_FOCUS); + if(set_input_focus) + xcb_set_input_focus(globalconf.connection, XCB_INPUT_FOCUS_PARENT, + c->win, XCB_CURRENT_TIME); + if(takefocus) + window_takefocus(c->win); +} + /** Ban client and move it out of the viewport. * \param c The client. */ @@ -281,7 +324,7 @@ client_focus(client_t *c) if (!c->nofocus) client_focus_update(c); - window_setfocus(c->win, !c->nofocus); + client_setfocus(c, !c->nofocus); } /** Stack a window below. @@ -1050,7 +1093,7 @@ client_unmanage(client_t *c) void client_kill(client_t *c) { - if(window_hasproto(c->win, WM_DELETE_WINDOW)) + if(client_hasproto(c, WM_DELETE_WINDOW)) { xcb_client_message_event_t ev; diff --git a/client.h b/client.h index 8c41b91b..7d25b1b1 100644 --- a/client.h +++ b/client.h @@ -188,6 +188,8 @@ void client_focus_update(client_t *); void client_unfocus(client_t *); 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); static inline void client_stack(void) diff --git a/window.c b/window.c index 1d21ec40..dae553fb 100644 --- a/window.c +++ b/window.c @@ -162,30 +162,6 @@ window_opacity_set(xcb_window_t win, double opacity) xcb_delete_property(globalconf.connection, win, _NET_WM_WINDOW_OPACITY); } -/** Check if client supports protocol a protocole in WM_PROTOCOL. - * \param win The window. - * \return True if client has the atom in protocol, false otherwise. - */ -bool -window_hasproto(xcb_window_t win, xcb_atom_t atom) -{ - uint32_t i; - xcb_get_wm_protocols_reply_t protocols; - bool ret = false; - - if(xcb_get_wm_protocols_reply(globalconf.connection, - xcb_get_wm_protocols_unchecked(globalconf.connection, - win, WM_PROTOCOLS), - &protocols, NULL)) - { - for(i = 0; !ret && i < protocols.atoms_len; i++) - if(protocols.atoms[i] == atom) - ret = true; - xcb_get_wm_protocols_reply_wipe(&protocols); - } - return ret; -} - /** Send WM_TAKE_FOCUS client message to window * \param win destination window */ @@ -208,19 +184,4 @@ window_takefocus(xcb_window_t win) XCB_EVENT_MASK_NO_EVENT, (char *) &ev); } -/** Sets focus on window - using xcb_set_input_focus or WM_TAKE_FOCUS - * \param w Window that should get focus - * \param set_input_focus Should we call xcb_set_input_focus - */ -void -window_setfocus(xcb_window_t w, bool set_input_focus) -{ - bool takefocus = window_hasproto(w, WM_TAKE_FOCUS); - if(set_input_focus) - xcb_set_input_focus(globalconf.connection, XCB_INPUT_FOCUS_PARENT, - w, XCB_CURRENT_TIME); - if(takefocus) - window_takefocus(w); -} - // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/window.h b/window.h index 9bd42d2e..5d55a065 100644 --- a/window.h +++ b/window.h @@ -34,8 +34,6 @@ double window_opacity_get_from_reply(xcb_get_property_reply_t *); void window_opacity_set(xcb_window_t, double); void window_grabbuttons(xcb_window_t, xcb_window_t, button_array_t *); void window_takefocus(xcb_window_t); -bool window_hasproto(xcb_window_t, xcb_atom_t); -void window_setfocus(xcb_window_t, bool); #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80