diff options
-rw-r--r-- | include/wlr/xwayland.h | 17 | ||||
-rw-r--r-- | xwayland/xwm.c | 32 |
2 files changed, 42 insertions, 7 deletions
diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index fd14ff25..7dcb3935 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -120,6 +120,18 @@ struct wlr_xwayland_surface_size_hints { }; /** + * This represents the input focus described as follows: + * + * https://www.x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html#input_focus + */ +enum wlr_xwayland_icccm_input_model { + WLR_ICCCM_INPUT_MODEL_NONE = 0, + WLR_ICCCM_INPUT_MODEL_PASSIVE = 1, + WLR_ICCCM_INPUT_MODEL_LOCAL = 2, + WLR_ICCCM_INPUT_MODEL_GLOBAL = 3, +}; + +/** * An Xwayland user interface component. It has an absolute position in * layout-local coordinates. * @@ -303,7 +315,10 @@ void wlr_xwayland_surface_ping(struct wlr_xwayland_surface *surface); * false if it should be ignored */ bool wlr_xwayland_or_surface_wants_focus( - const struct wlr_xwayland_surface *surface); + const struct wlr_xwayland_surface *xsurface); + +enum wlr_xwayland_icccm_input_model wlr_xwayland_icccm_input_model( + const struct wlr_xwayland_surface *xsurface); #endif diff --git a/xwayland/xwm.c b/xwayland/xwm.c index a80a2ec6..10424f47 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -579,6 +579,7 @@ static void read_surface_hints(struct wlr_xwm *xwm, if (xsurface->hints == NULL) { return; } + memcpy(xsurface->hints, &hints, sizeof(struct wlr_xwayland_surface_hints)); xsurface->hints_urgency = xcb_icccm_wm_hints_get_urgency(&hints); @@ -1967,8 +1968,7 @@ void wlr_xwayland_surface_ping(struct wlr_xwayland_surface *surface) { } bool wlr_xwayland_or_surface_wants_focus( - const struct wlr_xwayland_surface *surface) { - bool ret = true; + const struct wlr_xwayland_surface *xsurface) { static enum atom_name needles[] = { NET_WM_WINDOW_TYPE_COMBO, NET_WM_WINDOW_TYPE_DND, @@ -1980,12 +1980,32 @@ bool wlr_xwayland_or_surface_wants_focus( NET_WM_WINDOW_TYPE_TOOLTIP, NET_WM_WINDOW_TYPE_UTILITY, }; + for (size_t i = 0; i < sizeof(needles) / sizeof(needles[0]); ++i) { - if (xwm_atoms_contains(surface->xwm, surface->window_type, - surface->window_type_len, needles[i])) { - ret = false; + if (xwm_atoms_contains(xsurface->xwm, xsurface->window_type, + xsurface->window_type_len, needles[i])) { + return false; } } - return ret; + return true; +} + +enum wlr_xwayland_icccm_input_model wlr_xwayland_icccm_input_model( + const struct wlr_xwayland_surface *xsurface) { + bool take_focus = xwm_atoms_contains(xsurface->xwm, + xsurface->protocols, xsurface->protocols_len, + WM_TAKE_FOCUS); + + if (xsurface->hints && xsurface->hints->input) { + if (take_focus) { + return WLR_ICCCM_INPUT_MODEL_LOCAL; + } + return WLR_ICCCM_INPUT_MODEL_PASSIVE; + } else { + if (take_focus) { + return WLR_ICCCM_INPUT_MODEL_GLOBAL; + } + } + return WLR_ICCCM_INPUT_MODEL_NONE; } |