diff --git a/src/config.h b/src/config.h
index 069a069d2e..73b68ec30c 100644
--- a/src/config.h
+++ b/src/config.h
@@ -525,5 +525,6 @@ static inline void log_warn_both_style_of_rules(const char *option_name) {
"precedence, and \"%s\" will have no effect.",
option_name, option_name);
}
+enum animation_trigger parse_animation_trigger(const char *trigger);
// vim: set noet sw=8 ts=8 :
diff --git a/src/config_libconfig.c b/src/config_libconfig.c
index d67846b869..a90a00a0c2 100644
--- a/src/config_libconfig.c
+++ b/src/config_libconfig.c
@@ -224,7 +224,7 @@ static inline void parse_wintype_config(const config_t *cfg, const char *member_
}
}
-static enum animation_trigger parse_animation_trigger(const char *trigger) {
+enum animation_trigger parse_animation_trigger(const char *trigger) {
for (unsigned i = 0; i < ANIMATION_TRIGGER_COUNT; i++) {
if (strcasecmp(trigger, animation_trigger_names[i]) == 0) {
return i;
diff --git a/src/dbus.c b/src/dbus.c
index 962f92af7d..e0770d4671 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -1123,9 +1123,7 @@ static DBusHandlerResult cdbus_process_introspect(DBusMessage *reply) {
}
///@}
-/**
- * Process an D-Bus Introspect request, for /windows.
- */
+/// Process an D-Bus Introspect request, for /windows.
static DBusHandlerResult
cdbus_process_windows_root_introspect(session_t *ps, DBusMessage *reply) {
static const char *str_introspect =
@@ -1207,6 +1205,11 @@ static bool cdbus_process_window_introspect(DBusMessage *reply) {
" \n"
" \n"
" \n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
" \n"
"\n";
// clang-format on
@@ -1422,6 +1425,39 @@ cdbus_process_windows(DBusConnection *conn, DBusMessage *msg, void *ud) {
"Unexpected member \"%s\" of dbus properties interface.", member);
dbus_set_error_const(&err, DBUS_ERROR_UNKNOWN_METHOD, NULL);
}
+ } else if (strcmp(interface, PICOM_WINDOW_INTERFACE) == 0 &&
+ strcmp(member, "BlockUnblockAnimation") == 0) {
+ bool block = false;
+ const char *trigger_str = NULL;
+ if (!cdbus_msg_get_arg(msg, 0, DBUS_TYPE_STRING, &trigger_str) ||
+ !cdbus_msg_get_arg(msg, 1, DBUS_TYPE_BOOLEAN, &block)) {
+ dbus_set_error_const(&err, DBUS_ERROR_INVALID_ARGS, NULL);
+ goto finished;
+ }
+ auto trigger = parse_animation_trigger(trigger_str);
+ if (trigger == ANIMATION_TRIGGER_INVALID) {
+ dbus_set_error(&err, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S,
+ trigger_str);
+ goto finished;
+ }
+ auto cursor = wm_find(ps->wm, wid);
+ if (cursor == NULL) {
+ dbus_set_error(&err, CDBUS_ERROR_BADWIN, CDBUS_ERROR_BADWIN_S, wid);
+ goto finished;
+ }
+ auto w = wm_ref_deref(cursor);
+ unsigned count = 0;
+ if (w != NULL) {
+ if (block) {
+ w->animation_block[trigger] += 1;
+ } else if (w->animation_block[trigger] > 0) {
+ w->animation_block[trigger] -= 1;
+ }
+ count = w->animation_block[trigger];
+ }
+ if (reply != NULL && !cdbus_append_uint32(reply, count)) {
+ ret = DBUS_HANDLER_RESULT_NEED_MEMORY;
+ }
} else {
log_debug("Illegal message of type \"%s\", path \"%s\" "
"interface \"%s\", member \"%s\"",
diff --git a/src/wm/win.c b/src/wm/win.c
index b14db0087e..d4ac798b97 100644
--- a/src/wm/win.c
+++ b/src/wm/win.c
@@ -1903,10 +1903,15 @@ bool win_process_animation_and_state_change(struct session *ps, struct win *w, d
"is being suppressed.",
animation_trigger_names[trigger], win_id(w), w->name);
return win_advance_animation(w, delta_t, &win_ctx);
+ } else if (w->animation_block[trigger] > 0) {
+ log_debug("Not starting animation %s for window %#010x (%s) because it "
+ "is blocked.",
+ animation_trigger_names[trigger], win_id(w), w->name);
+ return win_advance_animation(w, delta_t, &win_ctx);
}
auto wopts = win_options(w);
- if (trigger == ANIMATION_TRIGGER_INVALID || wopts.animations[trigger].script == NULL) {
+ if (wopts.animations[trigger].script == NULL) {
return true;
}
diff --git a/src/wm/win.h b/src/wm/win.h
index c23aad9a6e..b27242a95c 100644
--- a/src/wm/win.h
+++ b/src/wm/win.h
@@ -261,6 +261,9 @@ struct win {
struct win_state_change previous;
struct script_instance *running_animation_instance;
struct win_script running_animation;
+
+ /// Number of times each animation trigger is blocked
+ unsigned int animation_block[ANIMATION_TRIGGER_COUNT];
};
struct win_script_context {