1
0
Fork 0
mirror of https://github.com/yshui/picom.git synced 2024-11-25 14:06:08 -05:00

config: tweak animation trigger parsing

Use a bitflag internally to keep track of which triggers are set.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2024-11-14 12:17:36 +00:00
parent 1932635b08
commit 82f5578088
No known key found for this signature in database
GPG key ID: D3A4405BE6CC17F4

View file

@ -261,22 +261,54 @@ compile_win_script(struct win_script *result, config_setting_t *setting, char **
return true; return true;
} }
static bool /// Return the index of the lowest bit set in `bitflags`, and clear that bit.
set_animation(struct win_script *animations, const enum animation_trigger *triggers, static int next_bit(uint64_t *bitflags) {
int number_of_triggers, struct win_script animation, unsigned line) { if (!*bitflags) {
return -1;
}
auto lowbit = *bitflags & (~*bitflags + 1);
#if defined(__has_builtin) && __has_builtin(__builtin_ctzll)
int ret = __builtin_ctzll(lowbit);
#else
int ret = 63;
if (lowbit & 0x00000000FFFFFFFF) {
ret -= 32;
}
if (lowbit & 0x0000FFFF0000FFFF) {
ret -= 16;
}
if (lowbit & 0x00FF00FF00FF00FF) {
ret -= 8;
}
if (lowbit & 0x0F0F0F0F0F0F0F0F) {
ret -= 4;
}
if (lowbit & 0x3333333333333333) {
ret -= 2;
}
if (lowbit & 0x5555555555555555) {
ret -= 1;
}
#endif
*bitflags -= lowbit;
return ret;
}
static bool set_animation(struct win_script *animations, uint64_t triggers,
struct win_script animation, unsigned line) {
bool needed = false; bool needed = false;
for (int i = 0; i < number_of_triggers; i++) { while (triggers != 0) {
if (triggers[i] == ANIMATION_TRIGGER_INVALID) { int trigger = next_bit(&triggers);
log_error("Invalid trigger defined at line %d", line); if (trigger >= ANIMATION_TRIGGER_INVALID) {
continue; break;
} }
if (animations[triggers[i]].script != NULL) { if (animations[trigger].script != NULL) {
log_error("Duplicate animation defined for trigger %s at line " log_error("Duplicate animation defined for trigger %s at line "
"%d, it will be ignored.", "%d, it will be ignored.",
animation_trigger_names[triggers[i]], line); animation_trigger_names[trigger], line);
continue; continue;
} }
animations[triggers[i]] = animation; animations[trigger] = animation;
needed = true; needed = true;
} }
return needed; return needed;
@ -310,18 +342,26 @@ static bool parse_animation_one(struct win_script *animations,
config_setting_source_line(triggers)); config_setting_source_line(triggers));
return false; return false;
} }
enum animation_trigger *trigger_types = uint64_t trigger_types = 0;
alloca(sizeof(enum animation_trigger[number_of_triggers]));
const char *trigger0 = config_setting_get_string(triggers); const char *trigger0 = config_setting_get_string(triggers);
if (trigger0 == NULL) { if (trigger0 == NULL) {
for (int i = 0; i < number_of_triggers; i++) { for (int i = 0; i < number_of_triggers; i++) {
auto trigger_i = config_setting_get_string_elem(triggers, i); auto trigger_i_str = config_setting_get_string_elem(triggers, i);
trigger_types[i] = trigger_i == NULL auto trigger_i = trigger_i_str == NULL
? ANIMATION_TRIGGER_INVALID ? ANIMATION_TRIGGER_INVALID
: parse_animation_trigger(trigger_i); : parse_animation_trigger(trigger_i_str);
if (trigger_types & (1 << trigger_i)) {
log_warn("Duplicate trigger \"%s\" set at line %d",
trigger_i_str, config_setting_source_line(triggers));
}
trigger_types |= 1 << trigger_i;
} }
} else { } else {
trigger_types[0] = parse_animation_trigger(trigger0); trigger_types = 1 << parse_animation_trigger(trigger0);
}
if ((trigger_types & (1 << ANIMATION_TRIGGER_INVALID)) != 0) {
log_error("Invalid trigger defined at line %d",
config_setting_source_line(triggers));
} }
// script parser shouldn't see this. // script parser shouldn't see this.
@ -380,7 +420,7 @@ static bool parse_animation_one(struct win_script *animations,
return false; return false;
} }
bool needed = set_animation(animations, trigger_types, number_of_triggers, result, bool needed = set_animation(animations, trigger_types, result,
config_setting_source_line(setting)); config_setting_source_line(setting));
if (!needed) { if (!needed) {
script_free(result.script); script_free(result.script);
@ -435,14 +475,13 @@ void generate_fading_config(struct options *opt) {
// overwritten // overwritten
scoped_charp str = NULL; scoped_charp str = NULL;
size_t len = 0; size_t len = 0;
enum animation_trigger trigger[2];
struct script *scripts[4]; struct script *scripts[4];
unsigned number_of_scripts = 0; unsigned number_of_scripts = 0;
int number_of_triggers = 0;
double duration = 1.0 / opt->fade_in_step * opt->fade_delta / 1000.0; double duration = 1.0 / opt->fade_in_step * opt->fade_delta / 1000.0;
if (!safe_isinf(duration) && !safe_isnan(duration) && duration > 0) { if (!safe_isinf(duration) && !safe_isnan(duration) && duration > 0) {
scoped_charp duration_str = NULL; scoped_charp duration_str = NULL;
uint64_t triggers = 0;
dtostr(duration, &duration_str); dtostr(duration, &duration_str);
// Fading in from nothing, i.e. `open` and `show` // Fading in from nothing, i.e. `open` and `show`
@ -453,12 +492,12 @@ void generate_fading_config(struct options *opt) {
BUG_ON(!compile_win_script_from_string(&fade_in1, str)); BUG_ON(!compile_win_script_from_string(&fade_in1, str));
if (opt->animations[ANIMATION_TRIGGER_OPEN].script == NULL && if (opt->animations[ANIMATION_TRIGGER_OPEN].script == NULL &&
!opt->no_fading_openclose) { !opt->no_fading_openclose) {
trigger[number_of_triggers++] = ANIMATION_TRIGGER_OPEN; triggers |= 1 << ANIMATION_TRIGGER_OPEN;
} }
if (opt->animations[ANIMATION_TRIGGER_SHOW].script == NULL) { if (opt->animations[ANIMATION_TRIGGER_SHOW].script == NULL) {
trigger[number_of_triggers++] = ANIMATION_TRIGGER_SHOW; triggers |= 1 << ANIMATION_TRIGGER_SHOW;
} }
if (set_animation(opt->animations, trigger, number_of_triggers, fade_in1, 0)) { if (set_animation(opt->animations, triggers, fade_in1, 0)) {
scripts[number_of_scripts++] = fade_in1.script; scripts[number_of_scripts++] = fade_in1.script;
} else { } else {
script_free(fade_in1.script); script_free(fade_in1.script);
@ -468,11 +507,11 @@ void generate_fading_config(struct options *opt) {
asnprintf(&str, &len, FADING_TEMPLATE_1, duration_str); asnprintf(&str, &len, FADING_TEMPLATE_1, duration_str);
struct win_script fade_in2 = {.is_generated = true}; struct win_script fade_in2 = {.is_generated = true};
BUG_ON(!compile_win_script_from_string(&fade_in2, str)); BUG_ON(!compile_win_script_from_string(&fade_in2, str));
number_of_triggers = 0; triggers = 0;
if (opt->animations[ANIMATION_TRIGGER_INCREASE_OPACITY].script == NULL) { if (opt->animations[ANIMATION_TRIGGER_INCREASE_OPACITY].script == NULL) {
trigger[number_of_triggers++] = ANIMATION_TRIGGER_INCREASE_OPACITY; triggers |= 1 << ANIMATION_TRIGGER_INCREASE_OPACITY;
} }
if (set_animation(opt->animations, trigger, number_of_triggers, fade_in2, 0)) { if (set_animation(opt->animations, triggers, fade_in2, 0)) {
scripts[number_of_scripts++] = fade_in2.script; scripts[number_of_scripts++] = fade_in2.script;
} else { } else {
script_free(fade_in2.script); script_free(fade_in2.script);
@ -485,6 +524,7 @@ void generate_fading_config(struct options *opt) {
duration = 1.0 / opt->fade_out_step * opt->fade_delta / 1000.0; duration = 1.0 / opt->fade_out_step * opt->fade_delta / 1000.0;
if (!safe_isinf(duration) && !safe_isnan(duration) && duration > 0) { if (!safe_isinf(duration) && !safe_isnan(duration) && duration > 0) {
scoped_charp duration_str = NULL; scoped_charp duration_str = NULL;
uint64_t triggers = 0;
dtostr(duration, &duration_str); dtostr(duration, &duration_str);
// Fading out to nothing, i.e. `hide` and `close` // Fading out to nothing, i.e. `hide` and `close`
@ -492,15 +532,14 @@ void generate_fading_config(struct options *opt) {
duration_str, 1, 0); duration_str, 1, 0);
struct win_script fade_out1 = {.is_generated = true}; struct win_script fade_out1 = {.is_generated = true};
BUG_ON(!compile_win_script_from_string(&fade_out1, str)); BUG_ON(!compile_win_script_from_string(&fade_out1, str));
number_of_triggers = 0;
if (opt->animations[ANIMATION_TRIGGER_CLOSE].script == NULL && if (opt->animations[ANIMATION_TRIGGER_CLOSE].script == NULL &&
!opt->no_fading_openclose) { !opt->no_fading_openclose) {
trigger[number_of_triggers++] = ANIMATION_TRIGGER_CLOSE; triggers |= 1 << ANIMATION_TRIGGER_CLOSE;
} }
if (opt->animations[ANIMATION_TRIGGER_HIDE].script == NULL) { if (opt->animations[ANIMATION_TRIGGER_HIDE].script == NULL) {
trigger[number_of_triggers++] = ANIMATION_TRIGGER_HIDE; triggers |= 1 << ANIMATION_TRIGGER_HIDE;
} }
if (set_animation(opt->animations, trigger, number_of_triggers, fade_out1, 0)) { if (set_animation(opt->animations, triggers, fade_out1, 0)) {
scripts[number_of_scripts++] = fade_out1.script; scripts[number_of_scripts++] = fade_out1.script;
} else { } else {
script_free(fade_out1.script); script_free(fade_out1.script);
@ -510,11 +549,11 @@ void generate_fading_config(struct options *opt) {
asnprintf(&str, &len, FADING_TEMPLATE_1, duration_str); asnprintf(&str, &len, FADING_TEMPLATE_1, duration_str);
struct win_script fade_out2 = {.is_generated = true}; struct win_script fade_out2 = {.is_generated = true};
BUG_ON(!compile_win_script_from_string(&fade_out2, str)); BUG_ON(!compile_win_script_from_string(&fade_out2, str));
number_of_triggers = 0; triggers = 0;
if (opt->animations[ANIMATION_TRIGGER_DECREASE_OPACITY].script == NULL) { if (opt->animations[ANIMATION_TRIGGER_DECREASE_OPACITY].script == NULL) {
trigger[number_of_triggers++] = ANIMATION_TRIGGER_DECREASE_OPACITY; triggers = 1 << ANIMATION_TRIGGER_DECREASE_OPACITY;
} }
if (set_animation(opt->animations, trigger, number_of_triggers, fade_out2, 0)) { if (set_animation(opt->animations, triggers, fade_out2, 0)) {
scripts[number_of_scripts++] = fade_out2.script; scripts[number_of_scripts++] = fade_out2.script;
} else { } else {
script_free(fade_out2.script); script_free(fade_out2.script);