Feature #113: Set opacity based on conditions
- Add --opacity-rule, which sets opacity based on conditions, as requested by zabbal. (#113) - Add a data field for each condition. - Correct the FAQ link in README.md. Silly me. - Code clean-up.
This commit is contained in:
@@ -2426,6 +2426,28 @@ win_determine_blur_background(session_t *ps, win *w) {
|
||||
add_damage_win(ps, w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update window opacity according to opacity rules.
|
||||
*/
|
||||
static void
|
||||
win_update_opacity_rule(session_t *ps, win *w) {
|
||||
// If long is 32-bit, unfortunately there's no way could we express "unset",
|
||||
// so we just entirely don't distinguish "unset" and OPAQUE
|
||||
long opacity = OPAQUE;
|
||||
void *val = NULL;
|
||||
if (c2_matchd(ps, w, ps->o.opacity_rules, &w->cache_oparule, &val))
|
||||
opacity = ((double) (long) val) / 100.0 * OPAQUE;
|
||||
|
||||
if (opacity == w->opacity_set)
|
||||
return;
|
||||
|
||||
if (OPAQUE != opacity)
|
||||
wid_set_opacity_prop(ps, w->id, opacity);
|
||||
else if (OPAQUE != w->opacity_set)
|
||||
wid_rm_opacity_prop(ps, w->id);
|
||||
w->opacity_set = opacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to be called on window type changes.
|
||||
*/
|
||||
@@ -2436,6 +2458,8 @@ win_on_wtype_change(session_t *ps, win *w) {
|
||||
win_update_focused(ps, w);
|
||||
if (ps->o.invert_color_list)
|
||||
win_determine_invert_color(ps, w);
|
||||
if (ps->o.opacity_rules)
|
||||
win_update_opacity_rule(ps, w);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2453,6 +2477,8 @@ win_on_factor_change(session_t *ps, win *w) {
|
||||
win_update_focused(ps, w);
|
||||
if (ps->o.blur_background_blacklist)
|
||||
win_determine_blur_background(ps, w);
|
||||
if (ps->o.opacity_rules)
|
||||
win_update_opacity_rule(ps, w);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2670,11 +2696,13 @@ add_win(session_t *ps, Window id, Window prev) {
|
||||
.cache_fcblst = NULL,
|
||||
.cache_ivclst = NULL,
|
||||
.cache_bbblst = NULL,
|
||||
.cache_oparule = NULL,
|
||||
|
||||
.opacity = 0,
|
||||
.opacity_tgt = 0,
|
||||
.opacity_prop = OPAQUE,
|
||||
.opacity_prop_client = OPAQUE,
|
||||
.opacity_set = OPAQUE,
|
||||
|
||||
.fade = false,
|
||||
.fade_force = UNSET,
|
||||
@@ -4351,6 +4379,12 @@ usage(int ret) {
|
||||
"--invert-color-include condition\n"
|
||||
" Specify a list of conditions of windows that should be painted with\n"
|
||||
" inverted color. Resource-hogging, and is not well tested.\n"
|
||||
"--opacity-rule opacity:condition\n"
|
||||
" Specify a list of opacity rules, in the format \"PERCENT:PATTERN\",\n"
|
||||
" like \'50:name *= \"Firefox\"'. compton-trans is recommended over\n"
|
||||
" this. Note we do not distinguish 100% and unset, and we don't make\n"
|
||||
" any guarantee about possible conflicts with other programs that set\n"
|
||||
" _NET_WM_WINDOW_OPACITY on frame or client windows.\n"
|
||||
"--backend backend\n"
|
||||
" Choose backend. Possible choices are xrender and glx" WARNING ".\n"
|
||||
"--glx-no-stencil\n"
|
||||
@@ -4638,6 +4672,9 @@ parse_conv_kern(session_t *ps, const char *src, const char **endptr) {
|
||||
return parse_matrix(ps, src, endptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a list of convolution kernels.
|
||||
*/
|
||||
static bool
|
||||
parse_conv_kern_lst(session_t *ps, const char *src, XFixed **dest, int max) {
|
||||
static const struct {
|
||||
@@ -4682,6 +4719,37 @@ parse_conv_kern_lst(session_t *ps, const char *src, XFixed **dest, int max) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a list of opacity rules.
|
||||
*/
|
||||
static inline bool
|
||||
parse_rule_opacity(session_t *ps, const char *src) {
|
||||
// Find opacity value
|
||||
char *endptr = NULL;
|
||||
long val = strtol(src, &endptr, 0);
|
||||
if (!endptr || endptr == src) {
|
||||
printf_errf("(\"%s\"): No opacity specified?", src);
|
||||
return false;
|
||||
}
|
||||
if (val > 100 || val < 0) {
|
||||
printf_errf("(\"%s\"): Opacity %ld invalid.", src, val);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip over spaces
|
||||
while (*endptr && isspace(*endptr))
|
||||
++endptr;
|
||||
if (':' != *endptr) {
|
||||
printf_errf("(\"%s\"): Opacity terminator not found.", src);
|
||||
return false;
|
||||
}
|
||||
++endptr;
|
||||
|
||||
// Parse pattern
|
||||
// I hope 1-100 is acceptable for (void *)
|
||||
return c2_parsed(ps, &ps->o.opacity_rules, endptr, (void *) val);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LIBCONFIG
|
||||
/**
|
||||
* Get a file stream of the configuration file to read.
|
||||
@@ -5049,6 +5117,7 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
|
||||
{ "blur-kern", required_argument, NULL, 301 },
|
||||
{ "resize-damage", required_argument, NULL, 302 },
|
||||
{ "glx-use-gpushader4", no_argument, NULL, 303 },
|
||||
{ "opacity-rule", required_argument, NULL, 304 },
|
||||
// Must terminate with a NULL entry
|
||||
{ NULL, 0, NULL, 0 },
|
||||
};
|
||||
@@ -5282,6 +5351,11 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
|
||||
ps->o.resize_damage = atoi(optarg);
|
||||
break;
|
||||
P_CASEBOOL(303, glx_use_gpushader4);
|
||||
case 304:
|
||||
// --opacity-rule
|
||||
if (!parse_rule_opacity(ps, optarg))
|
||||
exit(1);
|
||||
break;
|
||||
default:
|
||||
usage(1);
|
||||
break;
|
||||
@@ -6216,6 +6290,7 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||
.inactive_dim = 0.0,
|
||||
.inactive_dim_fixed = false,
|
||||
.invert_color_list = NULL,
|
||||
.opacity_rules = NULL,
|
||||
|
||||
.wintype_focus = { false },
|
||||
.use_ewmh_active_win = false,
|
||||
@@ -6635,6 +6710,7 @@ session_destroy(session_t *ps) {
|
||||
free_wincondlst(&ps->o.focus_blacklist);
|
||||
free_wincondlst(&ps->o.invert_color_list);
|
||||
free_wincondlst(&ps->o.blur_background_blacklist);
|
||||
free_wincondlst(&ps->o.opacity_rules);
|
||||
#endif
|
||||
|
||||
// Free tracked atom list
|
||||
|
||||
Reference in New Issue
Block a user