Try to honor ICCCM input focus policy

This commit is contained in:
Bastien Dejean 2015-11-11 23:01:54 +01:00
parent 54d9215f79
commit 56c8025e4d
5 changed files with 25 additions and 18 deletions

View file

@ -285,17 +285,21 @@ void focus_in(xcb_generic_event_t *evt)
{
xcb_focus_in_event_t *e = (xcb_focus_in_event_t *) evt;
if (e->mode == XCB_NOTIFY_MODE_GRAB ||
e->mode == XCB_NOTIFY_MODE_UNGRAB)
if (e->mode == XCB_NOTIFY_MODE_GRAB || e->mode == XCB_NOTIFY_MODE_UNGRAB
|| e->detail == XCB_NOTIFY_DETAIL_POINTER || e->detail == XCB_NOTIFY_DETAIL_POINTER_ROOT
|| e->detail == XCB_NOTIFY_DETAIL_NONE) {
return;
/* prevent focus stealing */
if ((e->detail == XCB_NOTIFY_DETAIL_ANCESTOR ||
e->detail == XCB_NOTIFY_DETAIL_INFERIOR ||
e->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL ||
e->detail == XCB_NOTIFY_DETAIL_NONLINEAR) &&
(mon->desk->focus == NULL ||
mon->desk->focus->client->window != e->event))
}
if (mon->desk->focus != NULL && e->event == mon->desk->focus->client->window) {
return;
}
coordinates_t loc;
if (locate_window(e->event, &loc)) {
// prevent input focus stealing
update_input_focus();
}
}
void enter_notify(xcb_generic_event_t *evt)

9
tree.c
View file

@ -422,6 +422,7 @@ client_t *make_client(xcb_window_t win, unsigned int border_width)
snprintf(c->instance_name, sizeof(c->instance_name), "%s", MISSING_VALUE);
c->border_width = border_width;
c->locked = c->sticky = c->urgent = c->private = c->icccm_focus = false;
c->icccm_input = true;
xcb_icccm_get_wm_protocols_reply_t protocols;
if (xcb_icccm_get_wm_protocols_reply(dpy, xcb_icccm_get_wm_protocols(dpy, win, ewmh->WM_PROTOCOLS), &protocols, NULL) == 1) {
if (has_proto(WM_TAKE_FOCUS, &protocols)) {
@ -432,10 +433,16 @@ client_t *make_client(xcb_window_t win, unsigned int border_width)
c->num_states = 0;
xcb_ewmh_get_atoms_reply_t wm_state;
if (xcb_ewmh_get_wm_state_reply(ewmh, xcb_ewmh_get_wm_state(ewmh, win), &wm_state, NULL) == 1) {
for (unsigned int i = 0; i < wm_state.atoms_len && i < MAX_STATE; i++)
for (unsigned int i = 0; i < wm_state.atoms_len && i < MAX_STATE; i++) {
ewmh_wm_state_add(c, wm_state.atoms[i]);
}
xcb_ewmh_get_atoms_reply_wipe(&wm_state);
}
xcb_icccm_wm_hints_t hints;
if (xcb_icccm_get_wm_hints_reply(dpy, xcb_icccm_get_wm_hints(dpy, win), &hints, NULL) == 1
&& (hints.flags & XCB_ICCCM_WM_HINT_INPUT)) {
c->icccm_input = hints.input;
}
return c;
}

View file

@ -158,6 +158,7 @@ typedef struct {
bool urgent;
bool private;
bool icccm_focus;
bool icccm_input;
client_state_t state;
client_state_t last_state;
stack_layer_t layer;

View file

@ -828,10 +828,10 @@ void set_input_focus(node_t *n)
if (n == NULL) {
clear_input_focus();
} else {
if (n->client->icccm_focus && strstr(ICCCM_FOCUS_EXCEPTIONS, n->client->class_name) == NULL) {
if (n->client->icccm_input) {
xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_PARENT, n->client->window, XCB_CURRENT_TIME);
} else if (n->client->icccm_focus) {
send_client_message(n->client->window, ewmh->WM_PROTOCOLS, WM_TAKE_FOCUS);
} else {
xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, n->client->window, XCB_CURRENT_TIME);
}
}
}

View file

@ -25,11 +25,6 @@
#ifndef BSPWM_WINDOW_H
#define BSPWM_WINDOW_H
/* A comma separated list of class names of programs that include the
* WM_TAKE_FOCUS atom in their WM_PROTOCOLS property but don't handle the
* corresponding client message */
#define ICCCM_FOCUS_EXCEPTIONS "Skype"
#include <stdarg.h>
#include <xcb/xcb.h>
#include <xcb/xcb_event.h>