Exclude transparent-clipping-excluded windows from updating the ignored region

Transparent clipping interacts poorly with programs whose transparent
interface elements must show windows below them for functionality,
for example screenshot utilities.
This commit is contained in:
Stefan Radziuk 2021-12-01 22:51:57 +00:00
parent 8a373c38a6
commit 2328b97c23
8 changed files with 34 additions and 1 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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];

View File

@ -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

View File

@ -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) {

View File

@ -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) {

View File

@ -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

View File

@ -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;