Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use XCB to check if an application is fullscreen #187

Merged
merged 2 commits into from
Jul 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions man/compton.1.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@ May also be one of the predefined kernels: `3x3box` (default), `5x5box`, `7x7box
*--benchmark-wid* 'WINDOW_ID'::
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
--------------------
Some options accept a condition string to match certain windows. A condition string is formed by one or more conditions, joined by logical operators.
Expand Down
4 changes: 3 additions & 1 deletion src/atom.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
_NET_WM_WINDOW_TYPE_TOOLTIP, \
_NET_WM_WINDOW_TYPE_NOTIFICATION, \
_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

Expand Down
1 change: 1 addition & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,7 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable,
.focus_blacklist = NULL,
.detect_transient = false,
.detect_client_leader = false,
.no_ewmh_fullscreen = false,

.track_wdata = false,
.track_leader = false,
Expand Down
3 changes: 3 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ typedef struct options {
bool track_wdata;
/// Whether compton needs to track window leaders.
bool track_leader;

// Don't use EWMH to detect fullscreen applications
bool no_ewmh_fullscreen;
} options_t;

extern const char *const BACKEND_STRS[NUM_BKEND + 1];
Expand Down
2 changes: 2 additions & 0 deletions src/config_libconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
// --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
parse_cfg_condlst(&cfg, &opt->shadow_blacklist, "shadow-exclude");
// --fade-exclude
Expand Down
8 changes: 7 additions & 1 deletion src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,11 @@ static void usage(int ret) {
"\n"
"--debug-mode\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);
fputs(usage_text, f);
#undef WARNING_DISABLED
Expand Down Expand Up @@ -412,6 +416,7 @@ static const struct option longopts[] = {
{"monitor-repaint", no_argument, NULL, 800},
{"diagnostics", no_argument, NULL, 801},
{"debug-mode", no_argument, NULL, 802},
{"no-ewmh-fullscreen", no_argument, NULL, 803},
// Must terminate with a NULL entry
{NULL, 0, NULL, 0},
};
Expand Down Expand Up @@ -784,6 +789,7 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
P_CASEBOOL(800, monitor_repaint);
case 801: opt->print_diagnostics = true; break;
P_CASEBOOL(802, debug_mode);
P_CASEBOOL(803, no_ewmh_fullscreen);
default: usage(1); break;
#undef P_CASEBOOL
}
Expand Down
24 changes: 24 additions & 0 deletions src/win.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
* 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.
*
* It's not using w->border_size for performance measures.
*/
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) &&
(!w->bounding_shaped || w->rounded_corners);
}
Expand Down