diff --git a/include/client.h b/include/client.h index 45b8f4a7..2381b817 100644 --- a/include/client.h +++ b/include/client.h @@ -31,6 +31,12 @@ void client_remove_from_container(xcb_connection_t *conn, Client *client, */ void client_warp_pointer_into(xcb_connection_t *conn, Client *client); +/** + * Returns true if the client supports the given protocol atom (like WM_DELETE_WINDOW) + * + */ +bool client_supports_protocol(xcb_connection_t *conn, Client *client, xcb_atom_t atom); + /** * Kills the given window using WM_DELETE_WINDOW or xcb_kill_window * diff --git a/include/data.h b/include/data.h index a8b31d3b..f4f6f971 100644 --- a/include/data.h +++ b/include/data.h @@ -444,6 +444,9 @@ struct Client { * one. Therefore, this flag is set when reparenting. */ bool awaiting_useless_unmap; + /* Whether the client needs WM_TAKE_FOCUS */ + bool needs_take_focus; + /* XCB contexts */ xcb_window_t frame; /**< Our window: The frame around the * client */ diff --git a/src/client.c b/src/client.c index fc0d46ac..af7ba4bb 100644 --- a/src/client.c +++ b/src/client.c @@ -74,7 +74,7 @@ void client_warp_pointer_into(xcb_connection_t *conn, Client *client) { * Returns true if the client supports the given protocol atom (like WM_DELETE_WINDOW) * */ -static bool client_supports_protocol(xcb_connection_t *conn, Client *client, xcb_atom_t atom) { +bool client_supports_protocol(xcb_connection_t *conn, Client *client, xcb_atom_t atom) { xcb_get_property_cookie_t cookie; xcb_icccm_get_wm_protocols_reply_t protocols; bool result = false; diff --git a/src/manage.c b/src/manage.c index 0b33034e..fe5338c0 100644 --- a/src/manage.c +++ b/src/manage.c @@ -477,6 +477,7 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child, redecorate_window(conn, new); } + new->needs_take_focus = client_supports_protocol(conn, new, A_WM_TAKE_FOCUS); new->initialized = true; /* Check if the window already got the fullscreen hint set */ @@ -512,7 +513,8 @@ map: } if (new->container == CUR_CELL || client_is_floating(new)) { xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, new->child, XCB_CURRENT_TIME); - take_focus(conn, new); + if (new->needs_take_focus) + take_focus(conn, new); ewmh_update_active_window(new->child); } } diff --git a/src/util.c b/src/util.c index ae5c86a0..e34140e3 100644 --- a/src/util.c +++ b/src/util.c @@ -280,7 +280,8 @@ void set_focus(xcb_connection_t *conn, Client *client, bool set_anyways) { CLIENT_LOG(client); /* Set focus to the entered window, and flush xcb buffer immediately */ xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, client->child, XCB_CURRENT_TIME); - take_focus(conn, client); + if (client->needs_take_focus) + take_focus(conn, client); ewmh_update_active_window(client->child); //xcb_warp_pointer(conn, XCB_NONE, client->child, 0, 0, 0, 0, 10, 10);