Only send WM_TAKE_FOCUS when the client supports it in the protocols atom
Fixes opening xterm, for example
This commit is contained in:
parent
0639a7d95b
commit
82e286ed7c
|
@ -246,6 +246,9 @@ struct Window {
|
||||||
/** Whether the application used _NET_WM_NAME */
|
/** Whether the application used _NET_WM_NAME */
|
||||||
bool uses_net_wm_name;
|
bool uses_net_wm_name;
|
||||||
|
|
||||||
|
/** Whether the application needs to receive WM_TAKE_FOCUS */
|
||||||
|
bool needs_take_focus;
|
||||||
|
|
||||||
/** Whether the window says it is a dock window */
|
/** Whether the window says it is a dock window */
|
||||||
enum { W_NODOCK = 0, W_DOCK_TOP = 1, W_DOCK_BOTTOM = 2 } dock;
|
enum { W_NODOCK = 0, W_DOCK_TOP = 1, W_DOCK_BOTTOM = 2 } dock;
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,12 @@ void x_reinit(Con *con);
|
||||||
*/
|
*/
|
||||||
void x_con_kill(Con *con);
|
void x_con_kill(Con *con);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the client supports the given protocol atom (like WM_DELETE_WINDOW)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool window_supports_protocol(xcb_window_t window, xcb_atom_t atom);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kills the given X11 window using WM_DELETE_WINDOW (if supported).
|
* Kills the given X11 window using WM_DELETE_WINDOW (if supported).
|
||||||
*
|
*
|
||||||
|
|
|
@ -116,6 +116,12 @@ void fake_configure_notify(xcb_connection_t *conn, Rect r, xcb_window_t window);
|
||||||
*/
|
*/
|
||||||
void fake_absolute_configure_notify(Con *con);
|
void fake_absolute_configure_notify(Con *con);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the WM_TAKE_FOCUS ClientMessage to the given window
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void send_take_focus(xcb_window_t window);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds out which modifier mask is the one for numlock, as the user may
|
* Finds out which modifier mask is the one for numlock, as the user may
|
||||||
* change this.
|
* change this.
|
||||||
|
|
|
@ -156,6 +156,9 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
|
||||||
window_update_transient_for(cwindow, xcb_get_property_reply(conn, transient_cookie, NULL));
|
window_update_transient_for(cwindow, xcb_get_property_reply(conn, transient_cookie, NULL));
|
||||||
window_update_strut_partial(cwindow, xcb_get_property_reply(conn, strut_cookie, NULL));
|
window_update_strut_partial(cwindow, xcb_get_property_reply(conn, strut_cookie, NULL));
|
||||||
|
|
||||||
|
/* check if the window needs WM_TAKE_FOCUS */
|
||||||
|
cwindow->needs_take_focus = window_supports_protocol(cwindow->id, A_WM_TAKE_FOCUS);
|
||||||
|
|
||||||
/* Where to start searching for a container that swallows the new one? */
|
/* Where to start searching for a container that swallows the new one? */
|
||||||
Con *search_at = croot;
|
Con *search_at = croot;
|
||||||
|
|
||||||
|
|
19
src/x.c
19
src/x.c
|
@ -178,7 +178,7 @@ void x_con_kill(Con *con) {
|
||||||
* Returns true if the client supports the given protocol atom (like WM_DELETE_WINDOW)
|
* Returns true if the client supports the given protocol atom (like WM_DELETE_WINDOW)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static bool window_supports_protocol(xcb_window_t window, xcb_atom_t atom) {
|
bool window_supports_protocol(xcb_window_t window, xcb_atom_t atom) {
|
||||||
xcb_get_property_cookie_t cookie;
|
xcb_get_property_cookie_t cookie;
|
||||||
xcb_icccm_get_wm_protocols_reply_t protocols;
|
xcb_icccm_get_wm_protocols_reply_t protocols;
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
@ -618,19 +618,10 @@ void x_push_changes(Con *con) {
|
||||||
xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, to_focus, XCB_CURRENT_TIME);
|
xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, to_focus, XCB_CURRENT_TIME);
|
||||||
|
|
||||||
/* TODO: check if that client acccepts WM_TAKE_FOCUS at all */
|
/* TODO: check if that client acccepts WM_TAKE_FOCUS at all */
|
||||||
xcb_client_message_event_t ev;
|
if (focused->window != NULL &&
|
||||||
|
focused->window->needs_take_focus) {
|
||||||
memset(&ev, 0, sizeof(xcb_client_message_event_t));
|
send_take_focus(to_focus);
|
||||||
|
}
|
||||||
ev.response_type = XCB_CLIENT_MESSAGE;
|
|
||||||
ev.window = to_focus;
|
|
||||||
ev.type = A_WM_PROTOCOLS;
|
|
||||||
ev.format = 32;
|
|
||||||
ev.data.data32[0] = A_WM_TAKE_FOCUS;
|
|
||||||
ev.data.data32[1] = XCB_CURRENT_TIME;
|
|
||||||
|
|
||||||
DLOG("Sending WM_TAKE_FOCUS to the client\n");
|
|
||||||
xcb_send_event(conn, false, to_focus, XCB_EVENT_MASK_NO_EVENT, (char*)&ev);
|
|
||||||
|
|
||||||
ewmh_update_active_window(to_focus);
|
ewmh_update_active_window(to_focus);
|
||||||
focused_id = to_focus;
|
focused_id = to_focus;
|
||||||
|
|
20
src/xcb.c
20
src/xcb.c
|
@ -206,6 +206,26 @@ void fake_absolute_configure_notify(Con *con) {
|
||||||
fake_configure_notify(conn, absolute, con->window->id);
|
fake_configure_notify(conn, absolute, con->window->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sends the WM_TAKE_FOCUS ClientMessage to the given window
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void send_take_focus(xcb_window_t window) {
|
||||||
|
xcb_client_message_event_t ev;
|
||||||
|
|
||||||
|
memset(&ev, 0, sizeof(xcb_client_message_event_t));
|
||||||
|
|
||||||
|
ev.response_type = XCB_CLIENT_MESSAGE;
|
||||||
|
ev.window = window;
|
||||||
|
ev.type = A_WM_PROTOCOLS;
|
||||||
|
ev.format = 32;
|
||||||
|
ev.data.data32[0] = A_WM_TAKE_FOCUS;
|
||||||
|
ev.data.data32[1] = XCB_CURRENT_TIME;
|
||||||
|
|
||||||
|
DLOG("Sending WM_TAKE_FOCUS to the client\n");
|
||||||
|
xcb_send_event(conn, false, window, XCB_EVENT_MASK_NO_EVENT, (char*)&ev);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finds out which modifier mask is the one for numlock, as the user may change this.
|
* Finds out which modifier mask is the one for numlock, as the user may change this.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue