Partially handle _NET_WM_BYPASS_COMPOSITOR

Unredirect the screen when some window sets _NET_WM_BYPASS_COMPOSITOR
to 1, but ignore the case where some window requests the screen to be
redirected by setting _NET_WM_BYPASS_COMPOSITOR to 2.

Closes #267

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2020-01-18 18:00:35 +00:00
parent c9417bf367
commit b026708026
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
5 changed files with 47 additions and 1 deletions

View File

@ -6,6 +6,7 @@
#include "meta.h"
#include "cache.h"
// clang-format off
// Splitted into 2 lists because of the limitation of our macros
#define ATOM_LIST \
_NET_WM_WINDOW_OPACITY, \
@ -36,7 +37,9 @@
_NET_WM_WINDOW_TYPE_COMBO, \
_NET_WM_WINDOW_TYPE_DND, \
_NET_WM_STATE, \
_NET_WM_STATE_FULLSCREEN
_NET_WM_STATE_FULLSCREEN, \
_NET_WM_BYPASS_COMPOSITOR
// clang-format on
#define ATOM_DEF(x) xcb_atom_t a##x

View File

@ -461,6 +461,11 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
win_update_wintype(ps, w);
}
if (ev->atom == ps->atoms->a_NET_WM_BYPASS_COMPOSITOR) {
// Unnecessay until we remove the queue_redraw in ev_handle
queue_redraw(ps);
}
// If _NET_WM_OPACITY changes
if (ev->atom == ps->atoms->a_NET_WM_WINDOW_OPACITY) {
auto w = find_managed_win(ps, ev->window) ?: find_toplevel(ps, ev->window);

View File

@ -81,12 +81,14 @@ const char *const WINTYPES[NUM_WINTYPES] = {
"popup_menu", "tooltip", "notify", "combo", "dnd",
};
// clang-format off
/// Names of backends.
const char *const BACKEND_STRS[] = {[BKEND_XRENDER] = "xrender",
[BKEND_GLX] = "glx",
[BKEND_XR_GLX_HYBRID] = "xr_glx_hybrid",
[BKEND_DUMMY] = "dummy",
NULL};
// clang-format on
// === Global variables ===
@ -582,6 +584,17 @@ static struct managed_win *paint_preprocess(session_t *ps, bool *fade_running) {
}
}
// Unredirect screen if some window is requesting compositor bypass, even
// if that window is not on the top.
if (ps->o.unredir_if_possible && win_is_bypassing_compositor(ps, w) &&
!w->unredir_if_possible_excluded) {
// Here we deviate from EWMH a bit. EWMH says we must not
// unredirect the screen if the window requesting bypassing would
// look different after unredirecting. Instead we always follow
// the request.
unredir_possible = true;
}
w->prev_trans = bottom;
if (bottom) {
w->stacking_rank = bottom->stacking_rank + 1;

View File

@ -2251,6 +2251,8 @@ static inline bool rect_is_fullscreen(const session_t *ps, int x, int y, int wid
/**
* Check if a window is fulscreen using EWMH
*
* TODO cache this property
*/
static inline bool
win_is_fullscreen_xcb(xcb_connection_t *c, const struct atom *a, const xcb_window_t w) {
@ -2312,6 +2314,25 @@ bool win_is_fullscreen(const session_t *ps, const struct managed_win *w) {
(!w->bounding_shaped || w->rounded_corners);
}
/**
* Check if a window has BYPASS_COMPOSITOR property set
*
* TODO cache this property
*/
bool win_is_bypassing_compositor(const session_t *ps, const struct managed_win *w) {
bool ret = false;
auto prop = x_get_prop(ps, w->client_win, ps->atoms->a_NET_WM_BYPASS_COMPOSITOR,
1L, XCB_ATOM_CARDINAL, 32);
if (prop.nitems && *prop.c32 == 1) {
ret = true;
}
free_winprop(&prop);
return ret;
}
/**
* Check if a window is really focused.
*/

View File

@ -330,6 +330,10 @@ void win_update_leader(session_t *ps, struct managed_win *w);
*/
// XXX was win_border_size
void win_update_bounding_shape(session_t *ps, struct managed_win *w);
/**
* Check if a window has BYPASS_COMPOSITOR property set
*/
bool win_is_bypassing_compositor(const session_t *ps, const struct managed_win *w);
/**
* Get a rectangular region in global coordinates a window (and possibly
* its shadow) occupies.