diff --git a/events.c b/events.c index 963a516..ddb6039 100644 --- a/events.c +++ b/events.c @@ -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) diff --git a/tree.c b/tree.c index 759d8fc..2ca7d38 100644 --- a/tree.c +++ b/tree.c @@ -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; } diff --git a/types.h b/types.h index e99f9d1..eb88b5c 100644 --- a/types.h +++ b/types.h @@ -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; diff --git a/window.c b/window.c index 0347487..0d01f7c 100644 --- a/window.c +++ b/window.c @@ -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); } } } diff --git a/window.h b/window.h index 92da5d6..1e55947 100644 --- a/window.h +++ b/window.h @@ -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 #include #include