From 0e2750c3bd0300922d7bef4fd6519217878c074b Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Fri, 17 May 2024 13:09:41 +0100 Subject: [PATCH] win: add animation suppressions setting This can be used to prevent another animation from interrupting the current running animation. Signed-off-by: Yuxuan Shui --- src/config.h | 3 ++ src/config_libconfig.c | 65 ++++++++++++++++++++++++++++++++++++------ src/win.c | 8 ++++++ src/win.h | 1 + 4 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/config.h b/src/config.h index 9fd0d5d20e..2297428ae4 100644 --- a/src/config.h +++ b/src/config.h @@ -110,6 +110,9 @@ static const char *animation_trigger_names[] attr_unused = { struct script; struct win_script { int output_indices[NUM_OF_WIN_SCRIPT_OUTPUTS]; + /// A running animation can be configured to prevent other animations from + /// starting. + uint64_t suppressions; struct script *script; }; diff --git a/src/config_libconfig.c b/src/config_libconfig.c index 1250c6c772..8867635a71 100644 --- a/src/config_libconfig.c +++ b/src/config_libconfig.c @@ -250,9 +250,10 @@ compile_win_script(config_setting_t *setting, int *output_indices, char **err) { return script; } -static bool set_animation(struct win_script *animations, - const enum animation_trigger *triggers, int number_of_triggers, - struct script *script, const int *output_indices, unsigned line) { +static bool +set_animation(struct win_script *animations, const enum animation_trigger *triggers, + int number_of_triggers, struct script *script, const int *output_indices, + uint64_t suppressions, unsigned line) { bool needed = false; for (int i = 0; i < number_of_triggers; i++) { if (triggers[i] == ANIMATION_TRIGGER_INVALID) { @@ -268,6 +269,7 @@ static bool set_animation(struct win_script *animations, memcpy(animations[triggers[i]].output_indices, output_indices, sizeof(int[NUM_OF_WIN_SCRIPT_OUTPUTS])); animations[triggers[i]].script = script; + animations[triggers[i]].suppressions = suppressions; needed = true; } return needed; @@ -317,6 +319,52 @@ parse_animation_one(struct win_script *animations, config_setting_t *setting) { // script parser shouldn't see this. config_setting_remove(setting, "triggers"); + uint64_t suppressions = 0; + auto suppressions_setting = config_setting_lookup(setting, "suppressions"); + if (suppressions_setting != NULL) { + auto single_suppression = config_setting_get_string(suppressions_setting); + if (!config_setting_is_list(suppressions_setting) && + !config_setting_is_array(suppressions_setting) && + single_suppression == NULL) { + log_error("The \"suppressions\" option must either be a string, " + "a list, or an array, but is none of those at line %d", + config_setting_source_line(suppressions_setting)); + return NULL; + } + if (single_suppression != NULL) { + auto suppression = parse_animation_trigger(single_suppression); + if (suppression == ANIMATION_TRIGGER_INVALID) { + log_error("Invalid suppression defined at line %d", + config_setting_source_line(suppressions_setting)); + return NULL; + } + suppressions = 1 << suppression; + } else { + auto len = config_setting_length(suppressions_setting); + for (int i = 0; i < len; i++) { + auto suppression_str = + config_setting_get_string_elem(suppressions_setting, i); + if (suppression_str == NULL) { + log_error( + "The \"suppressions\" option must only " + "contain strings, but one of them is not at " + "line %d", + config_setting_source_line(suppressions_setting)); + return NULL; + } + auto suppression = parse_animation_trigger(suppression_str); + if (suppression == ANIMATION_TRIGGER_INVALID) { + log_error( + "Invalid suppression defined at line %d", + config_setting_source_line(suppressions_setting)); + return NULL; + } + suppressions |= 1 << suppression; + } + } + config_setting_remove(setting, "suppressions"); + } + int output_indices[NUM_OF_WIN_SCRIPT_OUTPUTS]; char *err; auto script = compile_win_script(setting, output_indices, &err); @@ -328,7 +376,8 @@ parse_animation_one(struct win_script *animations, config_setting_t *setting) { } bool needed = set_animation(animations, trigger_types, number_of_triggers, script, - output_indices, config_setting_source_line(setting)); + output_indices, suppressions, + config_setting_source_line(setting)); if (!needed) { script_free(script); script = NULL; @@ -409,7 +458,7 @@ void generate_fading_config(struct options *opt) { trigger[number_of_triggers++] = ANIMATION_TRIGGER_SHOW; } if (set_animation(opt->animations, trigger, number_of_triggers, fade_in1, - output_indices, 0)) { + output_indices, 0, 0)) { scripts[number_of_scripts++] = fade_in1; } else { script_free(fade_in1); @@ -423,7 +472,7 @@ void generate_fading_config(struct options *opt) { trigger[number_of_triggers++] = ANIMATION_TRIGGER_INCREASE_OPACITY; } if (set_animation(opt->animations, trigger, number_of_triggers, fade_in2, - output_indices, 0)) { + output_indices, 0, 0)) { scripts[number_of_scripts++] = fade_in2; } else { script_free(fade_in2); @@ -443,7 +492,7 @@ void generate_fading_config(struct options *opt) { trigger[number_of_triggers++] = ANIMATION_TRIGGER_HIDE; } if (set_animation(opt->animations, trigger, number_of_triggers, fade_out1, - output_indices, 0)) { + output_indices, 0, 0)) { scripts[number_of_scripts++] = fade_out1; } else { script_free(fade_out1); @@ -457,7 +506,7 @@ void generate_fading_config(struct options *opt) { trigger[number_of_triggers++] = ANIMATION_TRIGGER_DECREASE_OPACITY; } if (set_animation(opt->animations, trigger, number_of_triggers, fade_out2, - output_indices, 0)) { + output_indices, 0, 0)) { scripts[number_of_scripts++] = fade_out2; } else { script_free(fade_out2); diff --git a/src/win.c b/src/win.c index 5af892f3bc..83544182da 100644 --- a/src/win.c +++ b/src/win.c @@ -2342,6 +2342,13 @@ void win_process_animation_and_state_change(struct session *ps, struct managed_w return; } + if (w->running_animation && (w->running_animation_suppressions & (1 << trigger)) != 0) { + log_debug("Not starting animation %s for window %#010x (%s) because it " + "is being suppressed.", + animation_trigger_names[trigger], w->base.id, w->name); + return; + } + log_debug("Starting animation %s for window %#010x (%s)", animation_trigger_names[trigger], w->base.id, w->name); @@ -2352,6 +2359,7 @@ void win_process_animation_and_state_change(struct session *ps, struct managed_w } w->running_animation = new_animation; w->running_animation_outputs = ps->o.animations[trigger].output_indices; + w->running_animation_suppressions = ps->o.animations[trigger].suppressions; script_instance_evaluate(w->running_animation, &win_ctx); } diff --git a/src/win.h b/src/win.h index cc0c3be614..231efed1a3 100644 --- a/src/win.h +++ b/src/win.h @@ -311,6 +311,7 @@ struct managed_win { struct win_state_change previous; struct script_instance *running_animation; const int *running_animation_outputs; + uint64_t running_animation_suppressions; }; struct win_script_context {