xwm: Perform a roundtrip to send a deferred WM_TAKE_FOCUS
WM_TAKE_FOCUS requires a valid timestamp that isn't XCB_TIME_CURRENT. To get one, we set a property on the window and wait for the notification that it was set - this notification comes with a valid timestamp. Once we have that timestamp, delete the property, and fire off the slightly delayed WM_TAKE_FOCUS client request. Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
@@ -139,6 +139,7 @@ x11_get_atoms(xcb_connection_t *connection, struct atom_x11 *atom)
|
|||||||
{ "XdndActionCopy", F(xdnd_action_copy) },
|
{ "XdndActionCopy", F(xdnd_action_copy) },
|
||||||
{ "_XWAYLAND_ALLOW_COMMITS", F(allow_commits) },
|
{ "_XWAYLAND_ALLOW_COMMITS", F(allow_commits) },
|
||||||
{ "WL_SURFACE_ID", F(wl_surface_id) },
|
{ "WL_SURFACE_ID", F(wl_surface_id) },
|
||||||
|
{ "_WESTON_FOCUS_PING", F(weston_focus_ping) },
|
||||||
};
|
};
|
||||||
|
|
||||||
xcb_intern_atom_cookie_t cookies[ARRAY_LENGTH(atoms)];
|
xcb_intern_atom_cookie_t cookies[ARRAY_LENGTH(atoms)];
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ struct atom_x11 {
|
|||||||
xcb_atom_t xdnd_action_copy;
|
xcb_atom_t xdnd_action_copy;
|
||||||
xcb_atom_t wl_surface_id;
|
xcb_atom_t wl_surface_id;
|
||||||
xcb_atom_t allow_commits;
|
xcb_atom_t allow_commits;
|
||||||
|
xcb_atom_t weston_focus_ping;
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
|||||||
+38
-12
@@ -931,8 +931,6 @@ static void
|
|||||||
weston_wm_send_focus_window(struct weston_wm *wm,
|
weston_wm_send_focus_window(struct weston_wm *wm,
|
||||||
struct weston_wm_window *window)
|
struct weston_wm_window *window)
|
||||||
{
|
{
|
||||||
xcb_client_message_event_t client_message;
|
|
||||||
|
|
||||||
if (window) {
|
if (window) {
|
||||||
uint32_t values[1];
|
uint32_t values[1];
|
||||||
|
|
||||||
@@ -940,16 +938,15 @@ weston_wm_send_focus_window(struct weston_wm *wm,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (window->take_focus) {
|
if (window->take_focus) {
|
||||||
client_message.response_type = XCB_CLIENT_MESSAGE;
|
/* Set a property to get a roundtrip
|
||||||
client_message.format = 32;
|
* with a timestamp for WM_TAKE_FOCUS */
|
||||||
client_message.window = window->id;
|
xcb_change_property(wm->conn,
|
||||||
client_message.type = wm->atom.wm_protocols;
|
XCB_PROP_MODE_REPLACE,
|
||||||
client_message.data.data32[0] = wm->atom.wm_take_focus;
|
window->id,
|
||||||
client_message.data.data32[1] = XCB_TIME_CURRENT_TIME;
|
wm->atom.weston_focus_ping,
|
||||||
|
XCB_ATOM_STRING,
|
||||||
xcb_send_event(wm->conn, 0, window->id,
|
8, /* format */
|
||||||
XCB_EVENT_MASK_NO_EVENT,
|
0, NULL);
|
||||||
(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,
|
||||||
@@ -1502,6 +1499,35 @@ weston_wm_handle_property_notify(struct weston_wm *wm, xcb_generic_event_t *even
|
|||||||
if (!wm_lookup_window(wm, property_notify->window, &window))
|
if (!wm_lookup_window(wm, property_notify->window, &window))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* We set the weston_focus_ping property on this window to
|
||||||
|
* get a timestamp to send a WM_TAKE_FOCUS... send it now,
|
||||||
|
* or just return if this is confirming we deleted the
|
||||||
|
* property.
|
||||||
|
*/
|
||||||
|
if (property_notify->atom == wm->atom.weston_focus_ping) {
|
||||||
|
xcb_client_message_event_t client_message;
|
||||||
|
|
||||||
|
if (property_notify->state == XCB_PROPERTY_DELETE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* delete our ping property */
|
||||||
|
xcb_delete_property(window->wm->conn,
|
||||||
|
window->id,
|
||||||
|
window->wm->atom.weston_focus_ping);
|
||||||
|
|
||||||
|
client_message.response_type = XCB_CLIENT_MESSAGE;
|
||||||
|
client_message.format = 32;
|
||||||
|
client_message.window = window->id;
|
||||||
|
client_message.type = wm->atom.wm_protocols;
|
||||||
|
client_message.data.data32[0] = wm->atom.wm_take_focus;
|
||||||
|
client_message.data.data32[1] = property_notify->time;
|
||||||
|
xcb_send_event(wm->conn, 0, window->id,
|
||||||
|
XCB_EVENT_MASK_NO_EVENT,
|
||||||
|
(char *) &client_message);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
window->properties_dirty = 1;
|
window->properties_dirty = 1;
|
||||||
|
|
||||||
if (wm_debug_is_enabled(wm))
|
if (wm_debug_is_enabled(wm))
|
||||||
|
|||||||
Reference in New Issue
Block a user