mirror of
https://github.com/yshui/picom.git
synced 2024-11-18 13:55:36 -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:
parent
1932635b08
commit
82f5578088
1 changed files with 72 additions and 33 deletions
|
@ -261,22 +261,54 @@ compile_win_script(struct win_script *result, config_setting_t *setting, char **
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_animation(struct win_script *animations, const enum animation_trigger *triggers,
|
||||
int number_of_triggers, struct win_script animation, unsigned line) {
|
||||
/// Return the index of the lowest bit set in `bitflags`, and clear that bit.
|
||||
static int next_bit(uint64_t *bitflags) {
|
||||
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;
|
||||
for (int i = 0; i < number_of_triggers; i++) {
|
||||
if (triggers[i] == ANIMATION_TRIGGER_INVALID) {
|
||||
log_error("Invalid trigger defined at line %d", line);
|
||||
continue;
|
||||
while (triggers != 0) {
|
||||
int trigger = next_bit(&triggers);
|
||||
if (trigger >= ANIMATION_TRIGGER_INVALID) {
|
||||
break;
|
||||
}
|
||||
if (animations[triggers[i]].script != NULL) {
|
||||
if (animations[trigger].script != NULL) {
|
||||
log_error("Duplicate animation defined for trigger %s at line "
|
||||
"%d, it will be ignored.",
|
||||
animation_trigger_names[triggers[i]], line);
|
||||
animation_trigger_names[trigger], line);
|
||||
continue;
|
||||
}
|
||||
animations[triggers[i]] = animation;
|
||||
animations[trigger] = animation;
|
||||
needed = true;
|
||||
}
|
||||
return needed;
|
||||
|
@ -310,18 +342,26 @@ static bool parse_animation_one(struct win_script *animations,
|
|||
config_setting_source_line(triggers));
|
||||
return false;
|
||||
}
|
||||
enum animation_trigger *trigger_types =
|
||||
alloca(sizeof(enum animation_trigger[number_of_triggers]));
|
||||
uint64_t trigger_types = 0;
|
||||
const char *trigger0 = config_setting_get_string(triggers);
|
||||
if (trigger0 == NULL) {
|
||||
for (int i = 0; i < number_of_triggers; i++) {
|
||||
auto trigger_i = config_setting_get_string_elem(triggers, i);
|
||||
trigger_types[i] = trigger_i == NULL
|
||||
? ANIMATION_TRIGGER_INVALID
|
||||
: parse_animation_trigger(trigger_i);
|
||||
auto trigger_i_str = config_setting_get_string_elem(triggers, i);
|
||||
auto trigger_i = trigger_i_str == NULL
|
||||
? ANIMATION_TRIGGER_INVALID
|
||||
: 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 {
|
||||
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.
|
||||
|
@ -380,7 +420,7 @@ static bool parse_animation_one(struct win_script *animations,
|
|||
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));
|
||||
if (!needed) {
|
||||
script_free(result.script);
|
||||
|
@ -435,14 +475,13 @@ void generate_fading_config(struct options *opt) {
|
|||
// overwritten
|
||||
scoped_charp str = NULL;
|
||||
size_t len = 0;
|
||||
enum animation_trigger trigger[2];
|
||||
struct script *scripts[4];
|
||||
unsigned number_of_scripts = 0;
|
||||
int number_of_triggers = 0;
|
||||
|
||||
double duration = 1.0 / opt->fade_in_step * opt->fade_delta / 1000.0;
|
||||
if (!safe_isinf(duration) && !safe_isnan(duration) && duration > 0) {
|
||||
scoped_charp duration_str = NULL;
|
||||
uint64_t triggers = 0;
|
||||
dtostr(duration, &duration_str);
|
||||
|
||||
// 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));
|
||||
if (opt->animations[ANIMATION_TRIGGER_OPEN].script == NULL &&
|
||||
!opt->no_fading_openclose) {
|
||||
trigger[number_of_triggers++] = ANIMATION_TRIGGER_OPEN;
|
||||
triggers |= 1 << ANIMATION_TRIGGER_OPEN;
|
||||
}
|
||||
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;
|
||||
} else {
|
||||
script_free(fade_in1.script);
|
||||
|
@ -468,11 +507,11 @@ void generate_fading_config(struct options *opt) {
|
|||
asnprintf(&str, &len, FADING_TEMPLATE_1, duration_str);
|
||||
struct win_script fade_in2 = {.is_generated = true};
|
||||
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) {
|
||||
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;
|
||||
} else {
|
||||
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;
|
||||
if (!safe_isinf(duration) && !safe_isnan(duration) && duration > 0) {
|
||||
scoped_charp duration_str = NULL;
|
||||
uint64_t triggers = 0;
|
||||
dtostr(duration, &duration_str);
|
||||
|
||||
// Fading out to nothing, i.e. `hide` and `close`
|
||||
|
@ -492,15 +532,14 @@ void generate_fading_config(struct options *opt) {
|
|||
duration_str, 1, 0);
|
||||
struct win_script fade_out1 = {.is_generated = true};
|
||||
BUG_ON(!compile_win_script_from_string(&fade_out1, str));
|
||||
number_of_triggers = 0;
|
||||
if (opt->animations[ANIMATION_TRIGGER_CLOSE].script == NULL &&
|
||||
!opt->no_fading_openclose) {
|
||||
trigger[number_of_triggers++] = ANIMATION_TRIGGER_CLOSE;
|
||||
triggers |= 1 << ANIMATION_TRIGGER_CLOSE;
|
||||
}
|
||||
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;
|
||||
} else {
|
||||
script_free(fade_out1.script);
|
||||
|
@ -510,11 +549,11 @@ void generate_fading_config(struct options *opt) {
|
|||
asnprintf(&str, &len, FADING_TEMPLATE_1, duration_str);
|
||||
struct win_script fade_out2 = {.is_generated = true};
|
||||
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) {
|
||||
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;
|
||||
} else {
|
||||
script_free(fade_out2.script);
|
||||
|
|
Loading…
Reference in a new issue