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:
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;
|
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) {
|
||||||
bool needed = false;
|
return -1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
if (animations[triggers[i]].script != NULL) {
|
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;
|
||||||
|
while (triggers != 0) {
|
||||||
|
int trigger = next_bit(&triggers);
|
||||||
|
if (trigger >= ANIMATION_TRIGGER_INVALID) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
Loading…
Reference in a new issue