xwayland: use wlr_xwayland_surface_offer_focus()

Offer focus by sending WM_TAKE_FOCUS to a client window supporting it.
The client may accept or ignore the offer. If it accepts, the surface will
emit a focus_in signal notifying the compositor that it has received focus.
The compositor should then call wlr_xwayland_surface_activate(surface, true).

This is a more compatible method of giving focus to windows using the
Globally Active input model (see wlr_xwayland_icccm_input_model()) than
calling wlr_xwayland_surface_activate() unconditionally, since there is no
reliable way to know in advance whether these windows want to be focused.

v2: add caution not to use view_offer_focus() directly
v3: remove obsolete comment
This commit is contained in:
John Lindgren 2024-07-20 11:25:10 -04:00 committed by Consolatis
parent 95552c261d
commit c00baa1651
5 changed files with 51 additions and 15 deletions

View file

@ -147,6 +147,7 @@ struct view_impl {
struct view_size_hints (*get_size_hints)(struct view *self);
/* if not implemented, VIEW_WANTS_FOCUS_ALWAYS is assumed */
enum view_wants_focus (*wants_focus)(struct view *self);
void (*offer_focus)(struct view *self);
/* returns true if view reserves space at screen edge */
bool (*has_strut_partial)(struct view *self);
/* returns true if view declared itself a window type */
@ -479,6 +480,12 @@ enum view_edge view_edge_invert(enum view_edge edge);
*/
bool view_is_focusable(struct view *view);
/*
* For use by desktop_focus_view() only - please do not call directly.
* See the description of VIEW_WANTS_FOCUS_OFFER for more information.
*/
void view_offer_focus(struct view *view);
void mappable_connect(struct mappable *mappable, struct wlr_surface *surface,
wl_notify_func_t notify_map, wl_notify_func_t notify_unmap);
void mappable_disconnect(struct mappable *mappable);