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 {