From 2ab6592b0225bfa71f7e0130d04a53711492dc92 Mon Sep 17 00:00:00 2001 From: Nikolay Borodin Date: Sun, 8 Sep 2024 19:56:19 +0200 Subject: [PATCH] wm: split geometry trigger into geometry and position --- src/config.h | 3 +++ src/wm/win.c | 10 ++++++++-- src/wm/win.h | 15 ++++++++++++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/config.h b/src/config.h index 369579acb8..34876577ff 100644 --- a/src/config.h +++ b/src/config.h @@ -84,6 +84,8 @@ enum animation_trigger { ANIMATION_TRIGGER_CLOSE, /// When a window's geometry changes ANIMATION_TRIGGER_GEOMETRY, + /// When a window's position changes + ANIMATION_TRIGGER_POSITION, ANIMATION_TRIGGER_INVALID, ANIMATION_TRIGGER_COUNT = ANIMATION_TRIGGER_INVALID, @@ -97,6 +99,7 @@ static const char *animation_trigger_names[] attr_unused = { [ANIMATION_TRIGGER_OPEN] = "open", [ANIMATION_TRIGGER_CLOSE] = "close", [ANIMATION_TRIGGER_GEOMETRY] = "geometry", + [ANIMATION_TRIGGER_POSITION] = "position", }; struct script; diff --git a/src/wm/win.c b/src/wm/win.c index 16e10396fb..8b18be4576 100644 --- a/src/wm/win.c +++ b/src/wm/win.c @@ -1823,7 +1823,10 @@ bool win_process_animation_and_state_change(struct session *ps, struct win *w, d bool will_never_render = (!w->ever_damaged || w->win_image == NULL) && w->state != WSTATE_MAPPED; auto win_ctx = win_script_context_prepare(ps, w); - bool geometry_changed = !win_geometry_eq(w->previous.g, w->g); + + bool geometry_changed = win_geometry_changed(w->previous.g, w->g); + bool position_changed = win_position_changed(w->previous.g, w->g); + auto old_state = w->previous.state; w->previous.state = w->state; @@ -1834,7 +1837,7 @@ bool win_process_animation_and_state_change(struct session *ps, struct win *w, d // This window won't be rendered, so we don't need to run the animations. bool state_changed = old_state != w->state || win_ctx.opacity_before != win_ctx.opacity || - geometry_changed; + geometry_changed || position_changed; return state_changed || (w->running_animation_instance != NULL); } @@ -1894,6 +1897,9 @@ bool win_process_animation_and_state_change(struct session *ps, struct win *w, d assert(false); return true; } + } else if (position_changed) { + assert(w->state == WSTATE_MAPPED); + trigger = ANIMATION_TRIGGER_POSITION; } else if (geometry_changed) { assert(w->state == WSTATE_MAPPED); trigger = ANIMATION_TRIGGER_GEOMETRY; diff --git a/src/wm/win.h b/src/wm/win.h index d79fdf6e4e..536aa3c819 100644 --- a/src/wm/win.h +++ b/src/wm/win.h @@ -395,10 +395,19 @@ win_options(const struct win *w) { win_maybe_options_fold(w->options_override, w->options), *w->options_default); } -/// Check if win_geometry `a` and `b` have the same sizes and positions. Border width is +/// Check if the window has changed in size. Border width is /// not considered. -static inline bool win_geometry_eq(struct win_geometry a, struct win_geometry b) { - return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height; +static inline bool win_geometry_changed(struct win_geometry a, struct win_geometry b) { + return a.width != b.width || a.height != b.height; +} + +/// Check if the window position has changed. +static inline bool win_position_changed(struct win_geometry a, struct win_geometry b) { + if (win_geometry_changed(a, b)) { + return false; + } + + return a.x != b.x || a.y != b.y; } /// Process pending updates/images flags on a window. Has to be called in X critical