From bb676013ed1b1b48847694a2159e3b009636b181 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Sun, 25 Feb 2018 09:57:30 +0100 Subject: add xwayland unmanaged tests to support dmenu This adds `wlr_xwayland_surface_is_unamanged`, to allow compositors more fine grained control over XWayland focus. A surface that is unmanaged should not receive focus, while other windows that are just override redirect may want it (dmenu). The way unamanged is determined is taken from wlc. --- xwayland/xwayland.c | 21 +++++++++++++++++++++ xwayland/xwm.c | 20 ++++++++++++++++++++ 2 files changed, 41 insertions(+) (limited to 'xwayland') diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index 1d935180..8dffd040 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -405,3 +405,24 @@ void wlr_xwayland_set_seat(struct wlr_xwayland *xwayland, xwayland->seat_destroy.notify = wlr_xwayland_handle_seat_destroy; wl_signal_add(&seat->events.destroy, &xwayland->seat_destroy); } + + +bool wlr_xwayland_surface_is_unmanaged(const struct wlr_xwayland_surface *surface) { + static enum atom_name needles[] = { + NET_WM_WINDOW_TYPE_UTILITY, + NET_WM_WINDOW_TYPE_TOOLTIP, + NET_WM_WINDOW_TYPE_DND, + NET_WM_WINDOW_TYPE_DROPDOWN_MENU, + NET_WM_WINDOW_TYPE_POPUP_MENU, + NET_WM_WINDOW_TYPE_COMBO, + }; + + for (size_t i = 0; i < sizeof(needles) / sizeof(needles[0]); ++i) { + if (wlr_xwm_atoms_contains(surface->xwm, surface->window_type, + surface->window_type_len, needles[i])) { + return true; + } + } + + return false; +} diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 0d957260..c41b8d47 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -54,6 +54,12 @@ const char *atom_map[ATOM_LAST] = { "INCR", "TEXT", "TIMESTAMP", + "_NET_WM_WINDOW_TYPE_UTILITY", + "_NET_WM_WINDOW_TYPE_TOOLTIP", + "_NET_WM_WINDOW_TYPE_DND", + "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", + "_NET_WM_WINDOW_TYPE_POPUP_MENU", + "_NET_WM_WINDOW_TYPE_COMBO", }; /* General helpers */ @@ -1446,3 +1452,17 @@ void wlr_xwayland_surface_set_fullscreen(struct wlr_xwayland_surface *surface, xsurface_set_net_wm_state(surface); xcb_flush(surface->xwm->xcb_conn); } + +bool wlr_xwm_atoms_contains(struct wlr_xwm *xwm, xcb_atom_t *atoms, + size_t num_atoms, enum atom_name needle) { + xcb_atom_t atom = xwm->atoms[needle]; + + for (size_t i = 0; i < num_atoms; ++i) { + if (atom == atoms[i]) { + return true; + } + } + + return false; +} + -- cgit v1.2.3