aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrassyPanache <brassy.panache@gmail.com>2021-01-13 01:10:38 +1100
committerSimon Ser <contact@emersion.fr>2021-01-20 10:38:58 +0100
commitd6649a8a4ba19fda25fe8607bc62acea8acb5fed (patch)
treeb101454595c1e1bc627074693d2f2b8f21593c7d
parentf6fe43971876082b0c201696bf01dcd57de866c3 (diff)
Expose ICCCM input status
In certain situations windows can have their input field set to false but still expect to receive input focus by passively listening to key presses via a parent window. The ICCCM specification outlines how focus should be given to clients. Further reading: https://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7 Relates to #2604
-rw-r--r--include/wlr/xwayland.h17
-rw-r--r--xwayland/xwm.c32
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;
}