Never explicitly focus the root window
Whenever client.focus == nil, we set the input focus to the root window to express "nothing has the input focus". However, thanks to the way X11 input works, this means that whatever is under the mouse cursor gets keyboard input events. This can easily be reproduced with urxvt and some small addition to the config to unfocus things. This commit changes things. Instead of focusing the root window, we create a special "no focus" window that gets focused if we want nothing to have the focus. Closes https://github.com/awesomeWM/awesome/pull/470. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
dd657c0531
commit
2f78ec5b30
16
awesome.c
16
awesome.c
|
@ -569,23 +569,27 @@ main(int argc, char **argv)
|
||||||
xkb_init();
|
xkb_init();
|
||||||
|
|
||||||
/* The default GC is just a newly created associated with a window with
|
/* The default GC is just a newly created associated with a window with
|
||||||
* depth globalconf.default_depth */
|
* depth globalconf.default_depth.
|
||||||
xcb_window_t tmp_win = xcb_generate_id(globalconf.connection);
|
* The window_no_focus is used for "nothing has the input focus". */
|
||||||
|
globalconf.focus.window_no_focus = xcb_generate_id(globalconf.connection);
|
||||||
globalconf.gc = xcb_generate_id(globalconf.connection);
|
globalconf.gc = xcb_generate_id(globalconf.connection);
|
||||||
xcb_create_window(globalconf.connection, globalconf.default_depth,
|
xcb_create_window(globalconf.connection, globalconf.default_depth,
|
||||||
tmp_win, globalconf.screen->root,
|
globalconf.focus.window_no_focus, globalconf.screen->root,
|
||||||
-1, -1, 1, 1, 0,
|
-1, -1, 1, 1, 0,
|
||||||
XCB_COPY_FROM_PARENT, globalconf.visual->visual_id,
|
XCB_COPY_FROM_PARENT, globalconf.visual->visual_id,
|
||||||
XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP,
|
XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL |
|
||||||
|
XCB_CW_OVERRIDE_REDIRECT | XCB_CW_COLORMAP,
|
||||||
(const uint32_t [])
|
(const uint32_t [])
|
||||||
{
|
{
|
||||||
globalconf.screen->black_pixel,
|
globalconf.screen->black_pixel,
|
||||||
globalconf.screen->black_pixel,
|
globalconf.screen->black_pixel,
|
||||||
|
1,
|
||||||
globalconf.default_cmap
|
globalconf.default_cmap
|
||||||
});
|
});
|
||||||
xcb_create_gc(globalconf.connection, globalconf.gc, tmp_win, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND,
|
xcb_map_window(globalconf.connection, globalconf.focus.window_no_focus);
|
||||||
|
xcb_create_gc(globalconf.connection, globalconf.gc, globalconf.focus.window_no_focus,
|
||||||
|
XCB_GC_FOREGROUND | XCB_GC_BACKGROUND,
|
||||||
(const uint32_t[]) { globalconf.screen->black_pixel, globalconf.screen->white_pixel });
|
(const uint32_t[]) { globalconf.screen->black_pixel, globalconf.screen->white_pixel });
|
||||||
xcb_destroy_window(globalconf.connection, tmp_win);
|
|
||||||
|
|
||||||
/* Get the window tree associated to this screen */
|
/* Get the window tree associated to this screen */
|
||||||
tree_c = xcb_query_tree_unchecked(globalconf.connection,
|
tree_c = xcb_query_tree_unchecked(globalconf.connection,
|
||||||
|
|
|
@ -117,6 +117,8 @@ typedef struct
|
||||||
client_t *client;
|
client_t *client;
|
||||||
/** Is there a focus change pending? */
|
/** Is there a focus change pending? */
|
||||||
bool need_update;
|
bool need_update;
|
||||||
|
/** When nothing has the input focus, this window actually is focused */
|
||||||
|
xcb_window_t window_no_focus;
|
||||||
} focus;
|
} focus;
|
||||||
/** Drawins */
|
/** Drawins */
|
||||||
drawin_array_t drawins;
|
drawin_array_t drawins;
|
||||||
|
|
|
@ -433,7 +433,7 @@ void
|
||||||
client_focus_refresh(void)
|
client_focus_refresh(void)
|
||||||
{
|
{
|
||||||
client_t *c = globalconf.focus.client;
|
client_t *c = globalconf.focus.client;
|
||||||
xcb_window_t win = globalconf.screen->root;
|
xcb_window_t win = globalconf.focus.window_no_focus;
|
||||||
|
|
||||||
if(!globalconf.focus.need_update)
|
if(!globalconf.focus.need_update)
|
||||||
return;
|
return;
|
||||||
|
@ -447,10 +447,11 @@ client_focus_refresh(void)
|
||||||
if(!c->nofocus)
|
if(!c->nofocus)
|
||||||
win = c->window;
|
win = c->window;
|
||||||
else
|
else
|
||||||
/* Focus the root window to make sure the previously focused client
|
/* Move the focus away from whatever has it to make sure the
|
||||||
* doesn't get any input in case WM_TAKE_FOCUS gets ignored.
|
* previously focused client doesn't get any input in case
|
||||||
|
* WM_TAKE_FOCUS gets ignored.
|
||||||
*/
|
*/
|
||||||
win = globalconf.screen->root;
|
win = globalconf.focus.window_no_focus;
|
||||||
|
|
||||||
if(client_hasproto(c, WM_TAKE_FOCUS))
|
if(client_hasproto(c, WM_TAKE_FOCUS))
|
||||||
xwindow_takefocus(c->window);
|
xwindow_takefocus(c->window);
|
||||||
|
|
Loading…
Reference in New Issue