xwayland: Respect client WM_TAKE_FOCUS setting

According to https://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7 we should
send this focus notification only if a client has WM_TAKE_FOCUS set in
their WM_PROTOCOLS property. We've been sending it unconditionally.

Rather, we've been not-sending it unconditionally because the event mask
is wrong, but that will be fixed in a future commit. Fixing the event
mask first would break some clients (such as xterm).

Co-authored-by: Steve Pronovost <spronovo@microsoft.com>
Co-authored-by: Brenton DeGeer <brdegeer@microsoft.com>
Signed-off-by: Hideyuki Nagase <hideyukn@microsoft.com>
Signed-off-by: Steve Pronovost <spronovo@microsoft.com>
Signed-off-by: Brenton DeGeer <brdegeer@microsoft.com>
This commit is contained in:
Hideyuki Nagase 2022-03-10 13:43:38 -06:00 committed by Derek Foreman
parent 6e529cb6ab
commit 55b2bf9393

View file

@ -171,6 +171,7 @@ struct weston_wm_window {
int delete_window; int delete_window;
int maximized_vert; int maximized_vert;
int maximized_horz; int maximized_horz;
int take_focus;
struct wm_size_hints size_hints; struct wm_size_hints size_hints;
struct motif_wm_hints motif_hints; struct motif_wm_hints motif_hints;
struct wl_list link; struct wl_list link;
@ -530,6 +531,7 @@ weston_wm_window_read_properties(struct weston_wm_window *window)
window->size_hints.flags = 0; window->size_hints.flags = 0;
window->motif_hints.flags = 0; window->motif_hints.flags = 0;
window->delete_window = 0; window->delete_window = 0;
window->take_focus = 0;
for (i = 0; i < ARRAY_LENGTH(props); i++) { for (i = 0; i < ARRAY_LENGTH(props); i++) {
reply = xcb_get_property_reply(wm->conn, cookie[i], NULL); reply = xcb_get_property_reply(wm->conn, cookie[i], NULL);
@ -572,7 +574,8 @@ weston_wm_window_read_properties(struct weston_wm_window *window)
for (i = 0; i < reply->value_len; i++) for (i = 0; i < reply->value_len; i++)
if (atom[i] == wm->atom.wm_delete_window) { if (atom[i] == wm->atom.wm_delete_window) {
window->delete_window = 1; window->delete_window = 1;
break; } else if (atom[i] == wm->atom.wm_take_focus) {
window->take_focus = 1;
} }
break; break;
case TYPE_WM_NORMAL_HINTS: case TYPE_WM_NORMAL_HINTS:
@ -936,16 +939,18 @@ weston_wm_send_focus_window(struct weston_wm *wm,
if (window->override_redirect) if (window->override_redirect)
return; return;
client_message.response_type = XCB_CLIENT_MESSAGE; if (window->take_focus) {
client_message.format = 32; client_message.response_type = XCB_CLIENT_MESSAGE;
client_message.window = window->id; client_message.format = 32;
client_message.type = wm->atom.wm_protocols; client_message.window = window->id;
client_message.data.data32[0] = wm->atom.wm_take_focus; client_message.type = wm->atom.wm_protocols;
client_message.data.data32[1] = XCB_TIME_CURRENT_TIME; client_message.data.data32[0] = wm->atom.wm_take_focus;
client_message.data.data32[1] = XCB_TIME_CURRENT_TIME;
xcb_send_event(wm->conn, 0, window->id, xcb_send_event(wm->conn, 0, window->id,
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
(char *) &client_message); (char *) &client_message);
}
xcb_set_input_focus (wm->conn, XCB_INPUT_FOCUS_POINTER_ROOT, xcb_set_input_focus (wm->conn, XCB_INPUT_FOCUS_POINTER_ROOT,
window->id, XCB_TIME_CURRENT_TIME); window->id, XCB_TIME_CURRENT_TIME);