mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2024-11-21 14:42:25 +00:00
xwayland: add focus_in and grab_focus events
Allows the compositor to know when the XWayland focus changes.
This commit is contained in:
parent
aa1163e640
commit
eb5312022a
@ -186,6 +186,8 @@ struct wlr_xwayland_surface {
|
||||
struct wl_signal set_strut_partial;
|
||||
struct wl_signal set_override_redirect;
|
||||
struct wl_signal set_geometry;
|
||||
struct wl_signal focus_in;
|
||||
struct wl_signal grab_focus;
|
||||
/* can be used to set initial maximized/fullscreen geometry */
|
||||
struct wl_signal map_request;
|
||||
struct wl_signal ping_timeout;
|
||||
|
@ -219,6 +219,8 @@ static struct wlr_xwayland_surface *xwayland_surface_create(
|
||||
wl_signal_init(&surface->events.set_strut_partial);
|
||||
wl_signal_init(&surface->events.set_override_redirect);
|
||||
wl_signal_init(&surface->events.set_geometry);
|
||||
wl_signal_init(&surface->events.focus_in);
|
||||
wl_signal_init(&surface->events.grab_focus);
|
||||
wl_signal_init(&surface->events.map_request);
|
||||
wl_signal_init(&surface->events.ping_timeout);
|
||||
|
||||
@ -1591,16 +1593,26 @@ static bool validate_focus_serial(uint16_t last_focus_seq, uint16_t event_seq) {
|
||||
|
||||
static void xwm_handle_focus_in(struct wlr_xwm *xwm,
|
||||
xcb_focus_in_event_t *ev) {
|
||||
// Do not interfere with grabs
|
||||
if (ev->mode == XCB_NOTIFY_MODE_GRAB ||
|
||||
ev->mode == XCB_NOTIFY_MODE_UNGRAB) {
|
||||
return;
|
||||
}
|
||||
// Ignore pointer focus change events
|
||||
if (ev->detail == XCB_NOTIFY_DETAIL_POINTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not interfere with keyboard grabs, but notify the
|
||||
// compositor. Note that many legitimate X11 applications use
|
||||
// keyboard grabs to "steal" focus for e.g. popup menus.
|
||||
struct wlr_xwayland_surface *xsurface = lookup_surface(xwm, ev->event);
|
||||
if (ev->mode == XCB_NOTIFY_MODE_GRAB) {
|
||||
if (xsurface) {
|
||||
wl_signal_emit_mutable(&xsurface->events.grab_focus, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (ev->mode == XCB_NOTIFY_MODE_UNGRAB) {
|
||||
/* Do we need an ungrab_focus event? */
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore any out-of-date FocusIn event (older than the last
|
||||
// known WM-initiated focus change) to avoid race conditions.
|
||||
// https://github.com/swaywm/wlroots/issues/2324
|
||||
@ -1611,9 +1623,9 @@ static void xwm_handle_focus_in(struct wlr_xwm *xwm,
|
||||
// Allow focus changes between surfaces belonging to the same
|
||||
// application. Steam for example relies on this:
|
||||
// https://github.com/swaywm/sway/issues/1865
|
||||
struct wlr_xwayland_surface *xsurface = lookup_surface(xwm, ev->event);
|
||||
if (xsurface && xwm->focus_surface && xsurface->pid == xwm->focus_surface->pid) {
|
||||
xwm_set_focused_window(xwm, xsurface);
|
||||
wl_signal_emit_mutable(&xsurface->events.focus_in, NULL);
|
||||
} else {
|
||||
// Try to prevent clients from changing focus between
|
||||
// applications, by refocusing the previous surface.
|
||||
|
Loading…
Reference in New Issue
Block a user