From 10d5c9b2f93fa040156e98eddd5972cdc992bcc7 Mon Sep 17 00:00:00 2001 From: Tasos Sahanidis Date: Thu, 6 Jun 2019 04:37:06 +0300 Subject: [PATCH 1/2] Use XCB to check if an application is fullscreen --- src/atom.h | 4 +++- src/win.c | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/atom.h b/src/atom.h index 69a5e5cde2..2164afd6b6 100644 --- a/src/atom.h +++ b/src/atom.h @@ -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 diff --git a/src/win.c b/src/win.c index e42ff9ba38..ab88f8be51 100644 --- a/src/win.c +++ b/src/win.c @@ -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(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); } From 93642e537ff5d5ece4d3a325c0c9c8d96cf13ac9 Mon Sep 17 00:00:00 2001 From: Tasos Sahanidis Date: Sat, 8 Jun 2019 02:13:28 +0300 Subject: [PATCH 2/2] Add --no-ewmh-fullscreen This arg reverts to the old behaviour of checking for fullscreen windows. --- man/compton.1.asciidoc | 3 +++ src/config.c | 1 + src/config.h | 3 +++ src/config_libconfig.c | 2 ++ src/options.c | 8 +++++++- src/win.c | 2 +- 6 files changed, 17 insertions(+), 2 deletions(-) diff --git a/man/compton.1.asciidoc b/man/compton.1.asciidoc index 37d30e0755..dc77fbd4f3 100644 --- a/man/compton.1.asciidoc +++ b/man/compton.1.asciidoc @@ -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. diff --git a/src/config.c b/src/config.c index 536c1b3e1c..97ee9da50f 100644 --- a/src/config.c +++ b/src/config.c @@ -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, diff --git a/src/config.h b/src/config.h index ceb87854a4..f8e1dd0509 100644 --- a/src/config.h +++ b/src/config.h @@ -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]; diff --git a/src/config_libconfig.c b/src/config_libconfig.c index 4a6bbb5fcd..0083ab5ec3 100644 --- a/src/config_libconfig.c +++ b/src/config_libconfig.c @@ -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 diff --git a/src/options.c b/src/options.c index 569df2061f..7c1c016299 100644 --- a/src/options.c +++ b/src/options.c @@ -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 @@ -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}, }; @@ -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 } diff --git a/src/win.c b/src/win.c index ab88f8be51..da1f3659d5 100644 --- a/src/win.c +++ b/src/win.c @@ -2179,7 +2179,7 @@ static inline bool win_is_fullscreen_xcb(xcb_connection_t *c, const struct atom * It's not using w->border_size for performance measures. */ bool win_is_fullscreen(const session_t *ps, const struct managed_win *w) { - if(win_is_fullscreen_xcb(ps->c, ps->atoms, w->client_win)) + 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);