Merge pull request #187 from tatokis/xcb-fullscreen-query

Use XCB to check if an application is fullscreen
This commit is contained in:
yshui 2019-07-19 15:43:53 +01:00 committed by GitHub
commit 35ad3059f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 43 additions and 2 deletions

View File

@ -256,6 +256,9 @@ May also be one of the predefined kernels: `3x3box` (default), `5x5box`, `7x7box
*--benchmark-wid* 'WINDOW_ID':: *--benchmark-wid* 'WINDOW_ID'::
Specify window ID to repaint in benchmark mode. If omitted or is 0, the whole screen is repainted. Specify window ID to repaint in benchmark mode. If omitted or is 0, the whole screen is repainted.
*--no-ewmh-fullscreen*::
Do not use EWMH to detect fullscreen windows. Reverts to checking if a window is fullscreen based only on its size and coordinates.
FORMAT OF CONDITIONS FORMAT OF CONDITIONS
-------------------- --------------------
Some options accept a condition string to match certain windows. A condition string is formed by one or more conditions, joined by logical operators. Some options accept a condition string to match certain windows. A condition string is formed by one or more conditions, joined by logical operators.

View File

@ -34,7 +34,9 @@
_NET_WM_WINDOW_TYPE_TOOLTIP, \ _NET_WM_WINDOW_TYPE_TOOLTIP, \
_NET_WM_WINDOW_TYPE_NOTIFICATION, \ _NET_WM_WINDOW_TYPE_NOTIFICATION, \
_NET_WM_WINDOW_TYPE_COMBO, \ _NET_WM_WINDOW_TYPE_COMBO, \
_NET_WM_WINDOW_TYPE_DND _NET_WM_WINDOW_TYPE_DND, \
_NET_WM_STATE, \
_NET_WM_STATE_FULLSCREEN
#define ATOM_DEF(x) xcb_atom_t a##x #define ATOM_DEF(x) xcb_atom_t a##x

View File

@ -554,6 +554,7 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable,
.focus_blacklist = NULL, .focus_blacklist = NULL,
.detect_transient = false, .detect_transient = false,
.detect_client_leader = false, .detect_client_leader = false,
.no_ewmh_fullscreen = false,
.track_wdata = false, .track_wdata = false,
.track_leader = false, .track_leader = false,

View File

@ -224,6 +224,9 @@ typedef struct options {
bool track_wdata; bool track_wdata;
/// Whether compton needs to track window leaders. /// Whether compton needs to track window leaders.
bool track_leader; bool track_leader;
// Don't use EWMH to detect fullscreen applications
bool no_ewmh_fullscreen;
} options_t; } options_t;
extern const char *const BACKEND_STRS[NUM_BKEND + 1]; extern const char *const BACKEND_STRS[NUM_BKEND + 1];

View File

@ -355,6 +355,8 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
lcfg_lookup_bool(&cfg, "detect-transient", &opt->detect_transient); lcfg_lookup_bool(&cfg, "detect-transient", &opt->detect_transient);
// --detect-client-leader // --detect-client-leader
lcfg_lookup_bool(&cfg, "detect-client-leader", &opt->detect_client_leader); lcfg_lookup_bool(&cfg, "detect-client-leader", &opt->detect_client_leader);
// --no-ewmh-fullscreen
lcfg_lookup_bool(&cfg, "no-ewmh-fullscreen", &opt->no_ewmh_fullscreen);
// --shadow-exclude // --shadow-exclude
parse_cfg_condlst(&cfg, &opt->shadow_blacklist, "shadow-exclude"); parse_cfg_condlst(&cfg, &opt->shadow_blacklist, "shadow-exclude");
// --fade-exclude // --fade-exclude

View File

@ -315,7 +315,11 @@ static void usage(int ret) {
"\n" "\n"
"--debug-mode\n" "--debug-mode\n"
" Render into a separate window, and don't take over the screen. Useful\n" " Render into a separate window, and don't take over the screen. Useful\n"
" when you want to attach a debugger to compton\n"; " when you want to attach a debugger to compton\n"
"\n"
"--no-ewmh-fullscreen\n"
" Do not use EWMH to detect fullscreen windows. Reverts to checking\n"
" if a window is fullscreen based only on its size and coordinates.\n";
FILE *f = (ret ? stderr : stdout); FILE *f = (ret ? stderr : stdout);
fputs(usage_text, f); fputs(usage_text, f);
#undef WARNING_DISABLED #undef WARNING_DISABLED
@ -412,6 +416,7 @@ static const struct option longopts[] = {
{"monitor-repaint", no_argument, NULL, 800}, {"monitor-repaint", no_argument, NULL, 800},
{"diagnostics", no_argument, NULL, 801}, {"diagnostics", no_argument, NULL, 801},
{"debug-mode", no_argument, NULL, 802}, {"debug-mode", no_argument, NULL, 802},
{"no-ewmh-fullscreen", no_argument, NULL, 803},
// Must terminate with a NULL entry // Must terminate with a NULL entry
{NULL, 0, NULL, 0}, {NULL, 0, NULL, 0},
}; };
@ -784,6 +789,7 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
P_CASEBOOL(800, monitor_repaint); P_CASEBOOL(800, monitor_repaint);
case 801: opt->print_diagnostics = true; break; case 801: opt->print_diagnostics = true; break;
P_CASEBOOL(802, debug_mode); P_CASEBOOL(802, debug_mode);
P_CASEBOOL(803, no_ewmh_fullscreen);
default: usage(1); break; default: usage(1); break;
#undef P_CASEBOOL #undef P_CASEBOOL
} }

View File

@ -2151,12 +2151,36 @@ static inline bool rect_is_fullscreen(const session_t *ps, int x, int y, int wid
return (x <= 0 && y <= 0 && (x + wid) >= ps->root_width && (y + hei) >= ps->root_height); return (x <= 0 && y <= 0 && (x + wid) >= ps->root_width && (y + hei) >= ps->root_height);
} }
/**
* Check if a window is fulscreen using EWMH
*/
static inline bool win_is_fullscreen_xcb(xcb_connection_t *c, const struct atom *a, const xcb_window_t w) {
xcb_get_property_cookie_t prop = xcb_get_property(c, 0, w, a->a_NET_WM_STATE, XCB_ATOM_ATOM, 0, 12);
xcb_get_property_reply_t *reply = xcb_get_property_reply(c, prop, NULL);
if(!reply)
return false;
if(reply->length) {
xcb_atom_t *val = xcb_get_property_value(reply);
for(uint32_t i = 0; i < reply->length; i++) {
if(val[i] != a->a_NET_WM_STATE_FULLSCREEN)
continue;
free(reply);
return true;
}
}
free(reply);
return false;
}
/** /**
* Check if a window is a fullscreen window. * Check if a window is a fullscreen window.
* *
* It's not using w->border_size for performance measures. * It's not using w->border_size for performance measures.
*/ */
bool win_is_fullscreen(const session_t *ps, const struct managed_win *w) { bool win_is_fullscreen(const session_t *ps, const struct managed_win *w) {
if(!ps->o.no_ewmh_fullscreen && win_is_fullscreen_xcb(ps->c, ps->atoms, w->client_win))
return true;
return rect_is_fullscreen(ps, w->g.x, w->g.y, w->widthb, w->heightb) && return rect_is_fullscreen(ps, w->g.x, w->g.y, w->widthb, w->heightb) &&
(!w->bounding_shaped || w->rounded_corners); (!w->bounding_shaped || w->rounded_corners);
} }