diff --git a/man/picom.1.asciidoc b/man/picom.1.asciidoc index 82085f21..17de2c88 100644 --- a/man/picom.1.asciidoc +++ b/man/picom.1.asciidoc @@ -259,6 +259,9 @@ May also be one of the predefined kernels: `3x3box` (default), `5x5box`, `7x7box *--transparent-clipping*:: Make transparent windows clip other windows like non-transparent windows do, instead of blending on top of them. +*--transparent-clipping-exclude* 'CONDITION':: + Specify a list of conditions of windows that should never have transparent clipping applied. Useful for screenshot tools, where you need to be able to see through transparent parts of the window. + *--window-shader-fg* 'SHADER':: Specify GLSL fragment shader path for rendering window contents. Does not work when *--legacy-backends* is enabled. Shader is searched first relative to the directory the configuration file is in, then in the usual places for a configuration file. See section *SHADER INTERFACE* below for more details on the interface. diff --git a/picom.sample.conf b/picom.sample.conf index 59255d03..071a9945 100644 --- a/picom.sample.conf +++ b/picom.sample.conf @@ -355,6 +355,12 @@ use-damage = true; # # transparent-clipping = false +# Specify a list of conditions of windows that should never have transparent +# clipping applied. Useful for screenshot tools, where you need to be able to +# see through transparent parts of the window. +# +# transparent-clipping-exclude = [] + # Set the log level. Possible values are: # "trace", "debug", "info", "warn", "error" # in increasing level of importance. Case doesn't matter. diff --git a/src/config.h b/src/config.h index e1dc2dd4..7259dc1d 100644 --- a/src/config.h +++ b/src/config.h @@ -253,6 +253,9 @@ typedef struct options { // Make transparent windows clip other windows, instead of blending on top of // them bool transparent_clipping; + /// A list of conditions of windows to which transparent clipping + /// should not apply + c2_lptr_t *transparent_clipping_blacklist; } options_t; extern const char *const BACKEND_STRS[NUM_BKEND + 1]; diff --git a/src/config_libconfig.c b/src/config_libconfig.c index e3c70ad5..461fff3b 100644 --- a/src/config_libconfig.c +++ b/src/config_libconfig.c @@ -452,6 +452,9 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad lcfg_lookup_bool(&cfg, "no-ewmh-fullscreen", &opt->no_ewmh_fullscreen); // --transparent-clipping lcfg_lookup_bool(&cfg, "transparent-clipping", &opt->transparent_clipping); + // --transparent-clipping-exclude + parse_cfg_condlst(&cfg, &opt->transparent_clipping_blacklist, + "transparent-clipping-exclude"); // --shadow-exclude parse_cfg_condlst(&cfg, &opt->shadow_blacklist, "shadow-exclude"); // --clip-shadow-above diff --git a/src/options.c b/src/options.c index 3186ddc9..9f6888ff 100644 --- a/src/options.c +++ b/src/options.c @@ -348,6 +348,11 @@ static void usage(const char *argv0, int ret) { " Make transparent windows clip other windows like non-transparent windows\n" " do, instead of blending on top of them\n" "\n" + "--transparent-clipping-exclude condition\n" + " Specify a list of conditions of windows that should never have\n" + " transparent clipping applied. Useful for screenshot tools, where you\n" + " need to be able to see through transparent parts of the window.\n" + "\n" "--window-shader-fg shader\n" " Specify GLSL fragment shader path for rendering window contents. Does\n" " not work when `--legacy-backends` is enabled.\n" @@ -455,6 +460,7 @@ static const struct option longopts[] = { {"clip-shadow-above", required_argument, NULL, 335}, {"window-shader-fg", required_argument, NULL, 336}, {"window-shader-fg-rule", required_argument, NULL, 337}, + {"transparent-clipping-exclude", required_argument, NULL, 338}, {"legacy-backends", no_argument, NULL, 733}, {"monitor-repaint", no_argument, NULL, 800}, {"diagnostics", no_argument, NULL, 801}, @@ -823,6 +829,11 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable, } break; } + case 338: { + // --transparent-clipping-exclude + condlst_add(&opt->transparent_clipping_blacklist, optarg); + break; + } case 321: { enum log_level tmp_level = string_to_log_level(optarg); if (tmp_level == LOG_LEVEL_INVALID) { diff --git a/src/picom.c b/src/picom.c index bac03b0f..e4a56077 100644 --- a/src/picom.c +++ b/src/picom.c @@ -831,7 +831,7 @@ paint_preprocess(session_t *ps, bool *fade_running, bool *animation) { // we add the window region to the ignored region // Otherwise last_reg_ignore shouldn't change if ((w->mode != WMODE_TRANS && !ps->o.force_win_blend) || - ps->o.transparent_clipping) { + (ps->o.transparent_clipping && !w->transparent_clipping_excluded)) { // w->mode == WMODE_SOLID or WMODE_FRAME_TRANS region_t *tmp = rc_region_new(); if (w->mode == WMODE_SOLID) { diff --git a/src/win.c b/src/win.c index 2ad6e867..370fbfd3 100644 --- a/src/win.c +++ b/src/win.c @@ -1225,6 +1225,9 @@ void win_on_factor_change(session_t *ps, struct managed_win *w) { w->fade_excluded = c2_match(ps, w, ps->o.fade_blacklist, NULL); + w->transparent_clipping_excluded = + c2_match(ps, w, ps->o.transparent_clipping_blacklist, NULL); + win_update_opacity_target(ps, w); w->reg_ignore_valid = false; @@ -1567,6 +1570,7 @@ struct win *fill_win(session_t *ps, struct win *w) { .rounded_corners = false, .paint_excluded = false, .fade_excluded = false, + .transparent_clipping_excluded = false, .unredir_if_possible_excluded = false, .prop_shadow = -1, // following 4 are set in win_mark_client diff --git a/src/win.h b/src/win.h index 8b79cb14..abc03d97 100644 --- a/src/win.h +++ b/src/win.h @@ -232,6 +232,9 @@ struct managed_win { /// Whether fading is excluded by the rules. Calculated. bool fade_excluded; + /// Whether transparent clipping is excluded by the rules. + bool transparent_clipping_excluded; + // Frame-opacity-related members /// Current window frame opacity. Affected by window opacity. double frame_opacity;