1
0
Fork 0
mirror of https://github.com/yshui/picom.git synced 2025-02-17 15:56:21 -05:00

options: warn if both new and old style rules are used

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2024-07-30 15:26:07 +01:00
parent dc83350fb5
commit 2bc273fc28
No known key found for this signature in database
GPG key ID: D3A4405BE6CC17F4
3 changed files with 162 additions and 46 deletions

View file

@ -427,6 +427,7 @@ typedef struct options {
struct script **all_scripts;
c2_lptr_t *rules;
bool has_both_style_of_rules;
} options_t;
extern const char *const BACKEND_STRS[NUM_BKEND + 1];
@ -505,4 +506,10 @@ static inline bool parse_vsync(const char *str) {
/// Generate animation script for legacy fading options
void generate_fading_config(struct options *opt);
static inline void log_warn_both_style_of_rules(const char *option_name) {
log_warn("Option \"%s\" is set along with \"rules\". \"rules\" will take "
"precedence, and \"%s\" will have no effect.",
option_name, option_name);
}
// vim: set noet sw=8 ts=8 :

View file

@ -764,6 +764,11 @@ bool parse_config_libconfig(options_t *opt, const char *config_file) {
}
}
config_setting_t *rules = config_lookup(&cfg, "rules");
if (rules) {
parse_rules(rules, &opt->rules);
}
// --dbus
lcfg_lookup_bool(&cfg, "dbus", &opt->dbus);
@ -790,10 +795,18 @@ bool parse_config_libconfig(options_t *opt, const char *config_file) {
// -i (inactive_opacity)
if (config_lookup_float(&cfg, "inactive-opacity", &dval)) {
opt->inactive_opacity = normalize_d(dval);
if (opt->rules) {
log_warn_both_style_of_rules("inactive-opacity");
opt->has_both_style_of_rules = true;
}
}
// --active_opacity
if (config_lookup_float(&cfg, "active-opacity", &dval)) {
opt->active_opacity = normalize_d(dval);
if (opt->rules) {
log_warn_both_style_of_rules("active-opacity");
opt->has_both_style_of_rules = true;
}
}
// --corner-radius
config_lookup_int(&cfg, "corner-radius", &opt->corner_radius);
@ -845,15 +858,34 @@ bool parse_config_libconfig(options_t *opt, const char *config_file) {
goto out;
}
// --inactive-opacity-override
lcfg_lookup_bool(&cfg, "inactive-opacity-override", &opt->inactive_opacity_override);
if (lcfg_lookup_bool(&cfg, "inactive-opacity-override", &opt->inactive_opacity_override) &&
opt->rules != NULL) {
log_warn_both_style_of_rules("inactive-opacity-override");
opt->has_both_style_of_rules = true;
}
// --inactive-dim
config_lookup_float(&cfg, "inactive-dim", &opt->inactive_dim);
if (config_lookup_float(&cfg, "inactive-dim", &opt->inactive_dim) && opt->rules != NULL) {
log_warn_both_style_of_rules("inactive-dim");
opt->has_both_style_of_rules = true;
}
// --mark-wmwin-focused
lcfg_lookup_bool(&cfg, "mark-wmwin-focused", &opt->mark_wmwin_focused);
if (lcfg_lookup_bool(&cfg, "mark-wmwin-focused", &opt->mark_wmwin_focused) &&
opt->rules != NULL) {
log_warn_both_style_of_rules("mark-wmwin-focused");
opt->has_both_style_of_rules = true;
}
// --mark-ovredir-focused
lcfg_lookup_bool(&cfg, "mark-ovredir-focused", &opt->mark_ovredir_focused);
if (lcfg_lookup_bool(&cfg, "mark-ovredir-focused", &opt->mark_ovredir_focused) &&
opt->rules != NULL) {
log_warn_both_style_of_rules("mark-ovredir-focused");
opt->has_both_style_of_rules = true;
}
// --shadow-ignore-shaped
lcfg_lookup_bool(&cfg, "shadow-ignore-shaped", &opt->shadow_ignore_shaped);
if (lcfg_lookup_bool(&cfg, "shadow-ignore-shaped", &opt->shadow_ignore_shaped) &&
opt->rules != NULL) {
log_warn_both_style_of_rules("shadow-ignore-shaped");
opt->has_both_style_of_rules = true;
}
// --detect-rounded-corners
lcfg_lookup_bool(&cfg, "detect-rounded-corners", &opt->detect_rounded_corners);
// --crop-shadow-to-monitor
@ -933,24 +965,50 @@ bool parse_config_libconfig(options_t *opt, const char *config_file) {
// --dithered_present
lcfg_lookup_bool(&cfg, "dithered-present", &opt->dithered_present);
if (!parse_cfg_condlst(&cfg, &opt->transparent_clipping_blacklist,
"transparent-clipping-exclude") ||
!parse_cfg_condlst(&cfg, &opt->shadow_blacklist, "shadow-exclude") ||
!parse_cfg_condlst(&cfg, &opt->shadow_clip_list, "clip-shadow-above") ||
!parse_cfg_condlst(&cfg, &opt->fade_blacklist, "fade-exclude") ||
!parse_cfg_condlst(&cfg, &opt->focus_blacklist, "focus-exclude") ||
!parse_cfg_condlst(&cfg, &opt->invert_color_list, "invert-color-include") ||
!parse_cfg_condlst(&cfg, &opt->blur_background_blacklist, "blur-background-exclude") ||
!parse_cfg_condlst(&cfg, &opt->unredir_if_possible_blacklist,
"unredir-if-possible-exclude") ||
!parse_cfg_condlst(&cfg, &opt->rounded_corners_blacklist, "rounded-corners-exclude") ||
!parse_cfg_condlst_with_prefix(&opt->corner_radius_rules, &cfg, "corner-radius-rules",
parse_numeric_prefix, NULL, (int[]){0, INT_MAX}) ||
!parse_cfg_condlst_with_prefix(&opt->opacity_rules, &cfg, "opacity-rule",
parse_numeric_prefix, NULL, (int[]){0, 100}) ||
!parse_cfg_condlst_with_prefix(
&opt->window_shader_fg_rules, &cfg, "window-shader-fg-rule",
parse_window_shader_prefix, free, (void *)config_get_include_dir(&cfg))) {
if (opt->rules != NULL) {
static const char *rule_list[] = {
"transparent-clipping-exclude",
"shadow-exclude",
"clip-shadow-above",
"fade-exclude",
"focus-exclude",
"invert-color-include",
"blur-background-exclude",
"unredir-if-possible-exclude",
"rounded-corners-exclude",
"corner-radius-rules",
"opacity-rule",
"window-shader-fg-rule",
"wintypes",
};
for (size_t i = 0; i < sizeof(rule_list) / sizeof(rule_list[0]); i++) {
if (config_lookup(&cfg, rule_list[i])) {
log_warn_both_style_of_rules(rule_list[i]);
opt->has_both_style_of_rules = true;
}
}
} else if (!parse_cfg_condlst(&cfg, &opt->transparent_clipping_blacklist,
"transparent-clipping-exclude") ||
!parse_cfg_condlst(&cfg, &opt->shadow_blacklist, "shadow-exclude") ||
!parse_cfg_condlst(&cfg, &opt->shadow_clip_list, "clip-shadow-above") ||
!parse_cfg_condlst(&cfg, &opt->fade_blacklist, "fade-exclude") ||
!parse_cfg_condlst(&cfg, &opt->focus_blacklist, "focus-exclude") ||
!parse_cfg_condlst(&cfg, &opt->invert_color_list, "invert-color-include") ||
!parse_cfg_condlst(&cfg, &opt->blur_background_blacklist,
"blur-background-exclude") ||
!parse_cfg_condlst(&cfg, &opt->unredir_if_possible_blacklist,
"unredir-if-possible-exclude") ||
!parse_cfg_condlst(&cfg, &opt->rounded_corners_blacklist,
"rounded-corners-exclude") ||
!parse_cfg_condlst_with_prefix(
&opt->corner_radius_rules, &cfg, "corner-radius-rules",
parse_numeric_prefix, NULL, (int[]){0, INT_MAX}) ||
!parse_cfg_condlst_with_prefix(&opt->opacity_rules, &cfg, "opacity-rule",
parse_numeric_prefix, NULL, (int[]){0, 100}) ||
!parse_cfg_condlst_with_prefix(&opt->window_shader_fg_rules, &cfg,
"window-shader-fg-rule",
parse_window_shader_prefix, free,
(void *)config_get_include_dir(&cfg))) {
goto out;
}
@ -1081,25 +1139,22 @@ bool parse_config_libconfig(options_t *opt, const char *config_file) {
// Wintype settings
// XXX ! Refactor all the wintype_* arrays into a struct
for (wintype_t i = 0; i < NUM_WINTYPES; ++i) {
parse_wintype_config(&cfg, WINTYPES[i].name, &opt->wintype_option[i],
&opt->wintype_option_mask[i]);
if (opt->rules == NULL) {
for (wintype_t i = 0; i < NUM_WINTYPES; ++i) {
parse_wintype_config(&cfg, WINTYPES[i].name, &opt->wintype_option[i],
&opt->wintype_option_mask[i]);
}
// Compatibility with the old name for notification windows.
parse_wintype_config(&cfg, "notify",
&opt->wintype_option[WINTYPE_NOTIFICATION],
&opt->wintype_option_mask[WINTYPE_NOTIFICATION]);
}
// Compatibility with the old name for notification windows.
parse_wintype_config(&cfg, "notify", &opt->wintype_option[WINTYPE_NOTIFICATION],
&opt->wintype_option_mask[WINTYPE_NOTIFICATION]);
config_setting_t *animations = config_lookup(&cfg, "animations");
if (animations) {
parse_animations(opt->animations, animations, &opt->all_scripts);
}
config_setting_t *rules = config_lookup(&cfg, "rules");
if (rules) {
parse_rules(rules, &opt->rules);
}
opt->config_file_path = path;
path = NULL;
succeeded = true;

View file

@ -67,6 +67,17 @@ static bool set_flag(const struct picom_option * /*opt*/, const struct picom_arg
return true;
}
static bool set_rule_flag(const struct picom_option *arg_opt, const struct picom_arg *arg,
const char * /*arg_str*/, void *output) {
auto opt = (struct options *)output;
if (opt->rules != NULL) {
log_warn_both_style_of_rules(arg_opt->long_name);
opt->has_both_style_of_rules = true;
return true;
}
*(bool *)(output + arg->offset) = true;
return true;
}
static bool unset_flag(const struct picom_option * /*opt*/, const struct picom_arg *arg,
const char * /*arg_str*/, void *output) {
*(bool *)(output + arg->offset) = false;
@ -100,6 +111,17 @@ static bool store_float(const struct picom_option *opt, const struct picom_arg *
return true;
}
static bool store_rule_float(const struct picom_option *arg_opt, const struct picom_arg *arg,
const char *arg_str, void *output) {
auto opt = (struct options *)output;
if (opt->rules != NULL) {
log_warn_both_style_of_rules(arg_opt->long_name);
opt->has_both_style_of_rules = true;
return true;
}
return store_float(arg_opt, arg, arg_str, output);
}
static bool store_int(const struct picom_option *opt, const struct picom_arg *arg,
const char *arg_str, void *output) {
const int *minmax = (const int *)arg->user_data;
@ -121,9 +143,15 @@ static bool store_string(const struct picom_option * /*opt*/, const struct picom
return true;
}
static bool store_rules(const struct picom_option * /*opt*/, const struct picom_arg *arg,
static bool store_rules(const struct picom_option *arg_opt, const struct picom_arg *arg,
const char *arg_str, void *output) {
const struct picom_rules_parser *parser = arg->user_data;
struct options *opt = (struct options *)output;
if (opt->rules != NULL) {
log_warn_both_style_of_rules(arg_opt->long_name);
opt->has_both_style_of_rules = true;
return true;
}
auto rules = (c2_lptr_t **)(output + arg->offset);
if (!parser->parse_prefix) {
return c2_parse(rules, arg_str, NULL) != NULL;
@ -166,6 +194,13 @@ static bool say_deprecated(const struct picom_option *opt, const struct picom_ar
.offset = OFFSET(member), .handler = set_flag, \
}
/// A true or false option that functions like a window rule. Which is superseded by the
/// `rules` option.
#define ENABLE_RULE(member) \
no_argument, { \
.offset = OFFSET(member), .handler = set_rule_flag, \
}
#define DISABLE(member) \
no_argument, { \
.offset = OFFSET(member), .handler = unset_flag, \
@ -201,6 +236,14 @@ static bool say_deprecated(const struct picom_option *opt, const struct picom_ar
.user_data = (double[]){min, max}, \
}
/// A float option that functions like a window rule. Which is superseded by the `rules`
/// option.
#define FLOAT_RULE(member, min, max) \
required_argument, { \
.offset = OFFSET(member), .handler = store_rule_float, \
.user_data = (double[]){min, max}, \
}
#define INTEGER(member, min, max) \
required_argument, { \
.offset = OFFSET(member), .handler = store_int, \
@ -313,7 +356,7 @@ static bool store_backend(const struct picom_option * /*opt*/, const struct pico
}
#define WINDOW_SHADER_RULE \
{ .parse_prefix = parse_window_shader_prefix_with_cwd, .free_value = free, }
{.parse_prefix = parse_window_shader_prefix_with_cwd, .free_value = free}
#ifdef CONFIG_OPENGL
#define BACKENDS "xrender, glx"
@ -336,16 +379,22 @@ static const struct picom_option picom_options[] = {
[256] = {"config" , IGNORE(required_argument), "Path to the configuration file."},
[307] = {"plugins" , IGNORE(required_argument), "Plugins to load. Can be specified multiple times, each time with a single plugin."},
// "Rule-like" options
[262] = {"mark-wmwin-focused" , ENABLE_RULE(mark_wmwin_focused) , "Try to detect WM windows and mark them as active."},
[264] = {"mark-ovredir-focused" , ENABLE_RULE(mark_ovredir_focused) , "Mark windows that have no WM frame as active."},
[266] = {"shadow-ignore-shaped" , ENABLE_RULE(shadow_ignore_shaped) , "Do not paint shadows on shaped windows. (Deprecated, use --shadow-exclude "
"\'bounding_shaped\' or --shadow-exclude \'bounding_shaped && "
"!rounded_corners\' instead.)"},
[260] = {"inactive-opacity-override", ENABLE_RULE(inactive_opacity_override), "Inactive opacity set by -i overrides value of _NET_WM_WINDOW_OPACITY."},
[297] = {"active-opacity" , FLOAT_RULE(active_opacity, 0, 1) , "Default opacity for active windows. (0.0 - 1.0)"},
[261] = {"inactive-dim" , FLOAT_RULE(inactive_dim, 0, 1) , "Dim inactive windows. (0.0 - 1.0, defaults to 0)"},
['i'] = {"inactive-opacity" , FLOAT_RULE(inactive_opacity, 0, 1) , "Opacity of inactive windows. (0.0 - 1.0)"},
// Simple flags
['c'] = {"shadow" , ENABLE(shadow_enable) , "Enabled client-side shadows on windows."},
['f'] = {"fading" , ENABLE(fading_enable) , "Fade windows in/out when opening/closing and when opacity changes, "
"unless --no-fading-openclose is used."},
[262] = {"mark-wmwin-focused" , ENABLE(mark_wmwin_focused) , "Try to detect WM windows and mark them as active."},
[264] = {"mark-ovredir-focused" , ENABLE(mark_ovredir_focused) , "Mark windows that have no WM frame as active."},
[265] = {"no-fading-openclose" , ENABLE(no_fading_openclose) , "Do not fade on window open/close."},
[266] = {"shadow-ignore-shaped" , ENABLE(shadow_ignore_shaped) , "Do not paint shadows on shaped windows. (Deprecated, use --shadow-exclude "
"\'bounding_shaped\' or --shadow-exclude \'bounding_shaped && "
"!rounded_corners\' instead.)"},
[268] = {"detect-client-opacity" , ENABLE(detect_client_opacity) , "Detect _NET_WM_WINDOW_OPACITY on client windows, useful for window "
"managers not passing _NET_WM_WINDOW_OPACITY of client windows to frame"},
[270] = {"vsync" , ENABLE(vsync) , "Enable VSync"},
@ -381,7 +430,6 @@ static const struct picom_option picom_options[] = {
[324] = {"no-use-damage" , DISABLE(use_damage) , "Disable the use of damage information. This cause the whole screen to be"
"redrawn every time, instead of the part of the screen that has actually "
"changed. Potentially degrades the performance, but might fix some artifacts."},
[260] = {"inactive-opacity-override", ENABLE(inactive_opacity_override), "Inactive opacity set by -i overrides value of _NET_WM_WINDOW_OPACITY."},
[267] = {"detect-rounded-corners" , ENABLE(detect_rounded_corners) , "Try to detect windows with rounded corners and don't consider them shaped "
"windows. Affects --shadow-ignore-shaped, --unredir-if-possible, and "
"possibly others. You need to turn this on manually if you want to match "
@ -413,16 +461,13 @@ static const struct picom_option picom_options[] = {
['I'] = {"fade-in-step" , FLOAT(fade_in_step, 0, 1) , "Opacity change between steps while fading in. (default 0.028)"},
['O'] = {"fade-out-step" , FLOAT(fade_out_step, 0, 1) , "Opacity change between steps while fading out. (default 0.03)"},
['D'] = {"fade-delta" , INTEGER(fade_delta, 1, INT_MAX) , "The time between steps in a fade in milliseconds. (default 10)"},
['i'] = {"inactive-opacity" , FLOAT(inactive_opacity, 0, 1) , "Opacity of inactive windows. (0.0 - 1.0)"},
['e'] = {"frame-opacity" , FLOAT(frame_opacity, 0, 1) , "Opacity of window titlebars and borders. (0.0 - 1.0)"},
[257] = {"shadow-red" , FLOAT(shadow_red, 0, 1) , "Red color value of shadow (0.0 - 1.0, defaults to 0)."},
[258] = {"shadow-green" , FLOAT(shadow_green, 0, 1) , "Green color value of shadow (0.0 - 1.0, defaults to 0)."},
[259] = {"shadow-blue" , FLOAT(shadow_blue, 0, 1) , "Blue color value of shadow (0.0 - 1.0, defaults to 0)."},
[261] = {"inactive-dim" , FLOAT(inactive_dim, 0, 1) , "Dim inactive windows. (0.0 - 1.0, defaults to 0)"},
[283] = {"blur-background" , FIXED(blur_method, BLUR_METHOD_KERNEL) , "Blur background of semi-transparent / ARGB windows. May impact performance"},
[290] = {"backend" , DO(store_backend) , "Backend. Possible values are: " BACKENDS},
[293] = {"benchmark" , INTEGER(benchmark, 0, INT_MAX) , "Benchmark mode. Repeatedly paint until reaching the specified cycles."},
[297] = {"active-opacity" , FLOAT(active_opacity, 0, 1) , "Default opacity for active windows. (0.0 - 1.0)"},
[302] = {"resize-damage" , INTEGER(resize_damage, INT_MIN, INT_MAX)}, // only used by legacy backends
[309] = {"unredir-if-possible-delay" , INTEGER(unredir_if_possible_delay, 0, INT_MAX) , "Delay before unredirecting the window, in milliseconds. Defaults to 0."},
[310] = {"write-pid-path" , NAMED_STRING(write_pid_path, "PATH") , "Write process ID to a file."},
@ -879,6 +924,15 @@ static bool sanitize_options(struct options *opt) {
log_warn("Negative --resize-damage will not work correctly.");
}
if (opt->has_both_style_of_rules) {
log_warn("You have set both \"rules\", as well as old-style rule options "
"in your configuration. The old-style rule options will have no "
"effect. It is recommended that you remove the old-style rule "
"options, and use only \"rules\" for all your window rules. If "
"you do genuinely need to use the old-style rule options, you "
"must not set \"rules\".");
}
return true;
}