Skip to content

Commit df7037d

Browse files
Monsterovichyshui
authored andcommitted
wm: split geometry trigger into size and position
And keep geometry as an alias for setting both size and position. Changelog: NewFeature: Separate the "geometry" animation trigger into "size" and "position" to allow finer-grained control. "geometry" is kept as an alias for setting both "size" and "position". Co-authored-by: Monsterovich <[email protected]> Signed-off-by: Yuxuan Shui <[email protected]>
1 parent 82f5578 commit df7037d

File tree

5 files changed

+51
-14
lines changed

5 files changed

+51
-14
lines changed

man/picom.1.adoc

+4-2
Original file line numberDiff line numberDiff line change
@@ -509,9 +509,11 @@ animations = ({
509509

510510
_decrease-opacity_:: When the opacity of a window is decreased.
511511

512-
[[trigger-geometry]]_geometry_:: When the geometry of a window is changed. (EXPERIMENTAL)
512+
_size_, _position_:: When the size or position of a window is changed. If both changed, the position trigger has priority. (EXPERIMENTAL)
513+
514+
[[trigger-geometry]]_geometry_:: Alias of size + position.
513515
+
514-
WARNING: The _geometry_ trigger is experimental. Using this means you accept the caveat that geometry animations will also trigger when you manually resize or move a window, like when you drag the window around with your mouse.
516+
WARNING: The _size_ and _position_ triggers are experimental. Using this means you accept the caveat that these animations will also trigger when you manually resize or move a window, like when you drag the window around with your mouse.
515517

516518
_suppressions_:::
517519
Which other animations should be suppressed when this animation is running. Normally, if another trigger is activated while an animation is already running, the animation in progress will be interrupted and the new animation will start. If you want to prevent this, you can set the `suppressions` option to a list of triggers that should be suppressed. This is optional, the default value for this is an empty list.

src/config.h

+12-3
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,18 @@ enum animation_trigger {
7373
ANIMATION_TRIGGER_OPEN,
7474
/// When a window is closed
7575
ANIMATION_TRIGGER_CLOSE,
76-
/// When a window's geometry changes
77-
ANIMATION_TRIGGER_GEOMETRY,
76+
/// When a window's size changes
77+
ANIMATION_TRIGGER_SIZE,
78+
/// When a window's position changes
79+
ANIMATION_TRIGGER_POSITION,
7880

7981
ANIMATION_TRIGGER_INVALID,
8082
ANIMATION_TRIGGER_COUNT = ANIMATION_TRIGGER_INVALID,
83+
84+
// Aliases are not included in the count
85+
86+
/// Alias of size + position
87+
ANIMATION_TRIGGER_ALIAS_GEOMETRY,
8188
};
8289

8390
static const char *animation_trigger_names[] attr_unused = {
@@ -87,7 +94,9 @@ static const char *animation_trigger_names[] attr_unused = {
8794
[ANIMATION_TRIGGER_DECREASE_OPACITY] = "decrease-opacity",
8895
[ANIMATION_TRIGGER_OPEN] = "open",
8996
[ANIMATION_TRIGGER_CLOSE] = "close",
90-
[ANIMATION_TRIGGER_GEOMETRY] = "geometry",
97+
[ANIMATION_TRIGGER_SIZE] = "size",
98+
[ANIMATION_TRIGGER_POSITION] = "position",
99+
[ANIMATION_TRIGGER_ALIAS_GEOMETRY] = "geometry",
91100
};
92101

93102
struct script;

src/config_libconfig.c

+11
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,17 @@ static bool parse_animation_one(struct win_script *animations,
363363
log_error("Invalid trigger defined at line %d",
364364
config_setting_source_line(triggers));
365365
}
366+
if ((trigger_types & (1 << ANIMATION_TRIGGER_ALIAS_GEOMETRY)) != 0) {
367+
const uint64_t to_set =
368+
(1 << ANIMATION_TRIGGER_SIZE) | (1 << ANIMATION_TRIGGER_POSITION);
369+
if ((trigger_types & to_set) != 0) {
370+
log_warn("Trigger \"geometry\" is an alias of \"size\" and "
371+
"\"position\", but one or both of them are also set at "
372+
"line %d",
373+
config_setting_source_line(triggers));
374+
}
375+
trigger_types |= to_set;
376+
}
366377

367378
// script parser shouldn't see this.
368379
config_setting_remove(setting, "triggers");

src/wm/win.c

+12-6
Original file line numberDiff line numberDiff line change
@@ -1715,7 +1715,10 @@ bool win_process_animation_and_state_change(struct session *ps, struct win *w, d
17151715
bool will_never_render =
17161716
(!w->ever_damaged || w->win_image == NULL) && w->state != WSTATE_MAPPED;
17171717
auto win_ctx = win_script_context_prepare(ps, w);
1718-
bool geometry_changed = !win_geometry_eq(w->previous.g, w->g);
1718+
1719+
bool size_changed = win_size_changed(w->previous.g, w->g);
1720+
bool position_changed = win_position_changed(w->previous.g, w->g);
1721+
17191722
auto old_state = w->previous.state;
17201723

17211724
w->previous.state = w->state;
@@ -1726,7 +1729,7 @@ bool win_process_animation_and_state_change(struct session *ps, struct win *w, d
17261729
// This window won't be rendered, so we don't need to run the animations.
17271730
bool state_changed = old_state != w->state ||
17281731
win_ctx.opacity_before != win_ctx.opacity ||
1729-
geometry_changed;
1732+
size_changed || position_changed;
17301733
return state_changed || (w->running_animation_instance != NULL);
17311734
}
17321735

@@ -1741,7 +1744,7 @@ bool win_process_animation_and_state_change(struct session *ps, struct win *w, d
17411744
enum animation_trigger trigger = ANIMATION_TRIGGER_INVALID;
17421745

17431746
// Animation trigger priority:
1744-
// state > geometry > opacity
1747+
// state > position > size > opacity
17451748
if (old_state != w->state) {
17461749
// Send D-Bus signal
17471750
if (ps->o.dbus) {
@@ -1786,9 +1789,12 @@ bool win_process_animation_and_state_change(struct session *ps, struct win *w, d
17861789
assert(false);
17871790
return true;
17881791
}
1789-
} else if (geometry_changed) {
1792+
} else if (position_changed) {
1793+
assert(w->state == WSTATE_MAPPED);
1794+
trigger = ANIMATION_TRIGGER_POSITION;
1795+
} else if (size_changed) {
17901796
assert(w->state == WSTATE_MAPPED);
1791-
trigger = ANIMATION_TRIGGER_GEOMETRY;
1797+
trigger = ANIMATION_TRIGGER_SIZE;
17921798
} else if (win_ctx.opacity_before != win_ctx.opacity) {
17931799
assert(w->state == WSTATE_MAPPED);
17941800
trigger = win_ctx.opacity > win_ctx.opacity_before
@@ -1877,7 +1883,7 @@ bool win_process_animation_and_state_change(struct session *ps, struct win *w, d
18771883
memory[output_indices[WIN_SCRIPT_SAVED_IMAGE_BLEND]] =
18781884
1 - memory[output_indices[WIN_SCRIPT_SAVED_IMAGE_BLEND]];
18791885
}
1880-
if (geometry_changed) {
1886+
if (size_changed || position_changed) {
18811887
// If the window has moved, we need to adjust scripts
18821888
// outputs so that the window will stay in the same position and
18831889
// size after applying the animation. This way the window's size

src/wm/win.h

+12-3
Original file line numberDiff line numberDiff line change
@@ -353,10 +353,19 @@ win_options(const struct win *w) {
353353
win_maybe_options_fold(w->options_override, w->options), *w->options_default);
354354
}
355355

356-
/// Check if win_geometry `a` and `b` have the same sizes and positions. Border width is
356+
/// Check if the window has changed in size. Border width is
357357
/// not considered.
358-
static inline bool win_geometry_eq(struct win_geometry a, struct win_geometry b) {
359-
return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
358+
static inline bool win_size_changed(struct win_geometry a, struct win_geometry b) {
359+
return a.width != b.width || a.height != b.height;
360+
}
361+
362+
/// Check if the window position has changed.
363+
static inline bool win_position_changed(struct win_geometry a, struct win_geometry b) {
364+
if (win_size_changed(a, b)) {
365+
return false;
366+
}
367+
368+
return a.x != b.x || a.y != b.y;
360369
}
361370

362371
/// Process pending updates/images flags on a window. Has to be called in X critical

0 commit comments

Comments
 (0)