466 lines
14 KiB
Markdown
466 lines
14 KiB
Markdown
# Window Animations Manual Test Plan
|
|
|
|
This is the manual verification checklist for Wry's animation work. Use it after
|
|
building a test compositor and booting into a normal graphical session.
|
|
|
|
The goal is to catch visual, synchronization, damage, and retained-content
|
|
problems that unit tests cannot prove from geometry alone.
|
|
|
|
## Setup
|
|
|
|
- Build and install the `codex-anims-next` branch.
|
|
- Start with animations enabled and a deliberately slow duration, around
|
|
`400-700ms`, so phase ordering and damage artifacts are visible.
|
|
- Test at least one normal Wayland/XDG app, one Xwayland app if available, and
|
|
one fast-updating app such as a terminal running output, a browser animation,
|
|
a video, or a GL/Vulkan demo.
|
|
- Use visible gaps, borders, titlebars, and rounding. These make clipping and
|
|
damage mistakes much easier to see.
|
|
- If available, test on both a single-output setup and a multi-output setup.
|
|
- If logging is convenient, run with debug logging and keep any multiphase
|
|
fallback messages. A fallback is useful evidence, not automatically a bug.
|
|
|
|
Relevant internal config hooks:
|
|
|
|
- `SetAnimationsEnabled`
|
|
- `SetAnimationDurationMs`
|
|
- `SetAnimationCurve`
|
|
- `SetAnimationCubicBezier`
|
|
|
|
Current curve IDs in code:
|
|
|
|
- `0`: linear
|
|
- `1`: CSS `ease`
|
|
- `2`: CSS `ease-in`
|
|
- `3` or any other unrecognized value: CSS `ease-out`
|
|
- `4`: CSS `ease-in-out`
|
|
|
|
## Enabling Multiphase Tests
|
|
|
|
There is currently no separate user-facing multiphase toggle. To exercise the
|
|
multiphase planner:
|
|
|
|
1. Enable animations with `SetAnimationsEnabled`.
|
|
2. Set a slow duration with `SetAnimationDurationMs`, around `400-700ms`.
|
|
3. Use tiled layout commands that are wired through `State::with_layout_animations`.
|
|
4. Use layouts where at least two tiled windows change geometry in the same
|
|
container layout batch.
|
|
|
|
The compositor then attempts multiphase planning automatically when the batched
|
|
layout pass completes. If the planner proves a legal no-overlap sequence, that
|
|
group uses phased animation. If it cannot prove one, only that motion group falls
|
|
back to ordinary linear animation.
|
|
|
|
Good command families for multiphase testing:
|
|
|
|
- seat/window move in a tiled direction
|
|
- split changes
|
|
- tab/group operations
|
|
- group-opposite changes
|
|
- equalize
|
|
- move-tab
|
|
- mono enter/exit
|
|
- command-driven window resize
|
|
|
|
These paths should not be used as evidence of multiphase behavior:
|
|
|
|
- tile-to-float and float-to-tile, which deliberately use linear animation
|
|
- command-driven floating move/resize, which may animate but can overlap
|
|
- pointer or tablet drag/resize, which should not animate
|
|
- spawn-in and spawn-out, which are always linear
|
|
- cross-output or cross-scale movement, which should snap
|
|
- layer-shell, overlay, override-redirect, and fullscreen map/unmap paths
|
|
|
|
Useful debug signal:
|
|
|
|
- `falling back to linear layout animation for group ...` means the group entered
|
|
the multiphase gate but the planner rejected it. That is acceptable for
|
|
unsupported patterns, but unexpected for the supported swap/extraction cases
|
|
below.
|
|
|
|
## Pass Criteria
|
|
|
|
A test passes when:
|
|
|
|
- layout, focus, hit testing, and configure behavior use the final logical
|
|
geometry immediately
|
|
- visible presentation motion is smooth and bounded by the animated frame
|
|
- no old pixels, trails, black strips, transparent holes, or stale titlebar
|
|
fragments remain after motion
|
|
- tiled multiphase movement never overlaps and never moves a single window
|
|
diagonally during a phase
|
|
- interruption starts changed windows from their current visual rect without
|
|
restarting unaffected windows
|
|
- drag-driven pointer movement remains direct and does not lag behind the cursor
|
|
- cross-output or cross-scale movements snap instead of animating
|
|
|
|
Record a failure with:
|
|
|
|
- the layout before and after
|
|
- whether the window was tiled, floating, mono, XDG, Xwayland, or layer-shell
|
|
- whether the app was GPU/dmabuf-backed or likely SHM, if known
|
|
- animation duration and curve
|
|
- whether the failure was visual overlap, diagonal motion, debris, clipping,
|
|
stale content, a missing retained frame, or an incorrect animation trigger
|
|
|
|
## Known Current Limits
|
|
|
|
These are acceptable unless they produce worse behavior than described:
|
|
|
|
- Spawn-out is retained-content-only. If the surface cannot be retained safely,
|
|
it should snap out rather than animate an empty frame.
|
|
- Async SHM surfaces are not retained yet. GPU/dmabuf-backed app windows are the
|
|
primary retained-content path for this phase.
|
|
- A dedicated retained-tree scaling/offscreen fallback is deferred. Retained
|
|
records currently render through the normal texture and stretch/clamp paths.
|
|
- Floats may overlap. The no-overlap invariant is for tiled multiphase motion.
|
|
- Linear fallback may overlap. This should be rare for valid tiled layouts, and
|
|
the fallback should be scoped to the affected motion group.
|
|
- Cross-output and cross-scale movements should not animate yet.
|
|
|
|
## 1. Basic Enable/Disable
|
|
|
|
1. Disable animations.
|
|
2. Move, resize, spawn, close, and toggle floating on a few windows.
|
|
3. Confirm all affected windows snap with no delayed presentation state.
|
|
4. Enable animations at a slow duration.
|
|
5. Repeat the same operations and confirm only eligible paths animate.
|
|
6. Disable animations while an animation is in flight.
|
|
|
|
Expected:
|
|
|
|
- disabling animations clears any in-flight visual state
|
|
- no stale damage remains after disabling
|
|
- newly enabled animations use the configured duration and curve
|
|
|
|
## 2. Spawn-In
|
|
|
|
Test newly mapped windows:
|
|
|
|
- tiled XDG window
|
|
- floating XDG window
|
|
- Xwayland window, if available
|
|
- fullscreen window
|
|
- layer-shell or overlay surface, such as a bar, launcher, menu, notification,
|
|
or lock/overlay component, if available
|
|
|
|
Expected:
|
|
|
|
- newly mapped tiled and floating app windows animate in
|
|
- layer-shell, overlay, override-redirect, and fullscreen surfaces do not use
|
|
the app-window spawn-in path
|
|
- contents stay clipped to the animated frame
|
|
- if contents are smaller than the frame during the animation, no empty strips
|
|
are visible
|
|
|
|
## 3. Spawn-Out
|
|
|
|
Close windows from these states:
|
|
|
|
- tiled app window
|
|
- floating app window
|
|
- Xwayland app window
|
|
- fast-updating app window
|
|
- a likely SHM/simple app, if available
|
|
|
|
Expected:
|
|
|
|
- retained app content shrinks out after the live node is gone
|
|
- there is no black, transparent, or unfilled moving rectangle
|
|
- if content cannot be retained, the window snaps out cleanly
|
|
- neighboring tiled windows reflow without debris left in the old area
|
|
|
|
Hard failure:
|
|
|
|
- a destroyed window leaves a moving empty frame
|
|
- the last frame shows unrelated newer content
|
|
- screen debris remains after the animation completes
|
|
|
|
## 4. Linear Tiled Reflow
|
|
|
|
Use a slow duration and a non-linear curve, then repeat with linear.
|
|
|
|
Cases:
|
|
|
|
- open two tiled windows and change split ratio by command
|
|
- open three tiled windows and resize the active split repeatedly
|
|
- move focus and issue command-driven swaps
|
|
- interrupt a resize by issuing another resize before the first completes
|
|
- create a layout that forces a linear fallback if possible
|
|
|
|
Expected:
|
|
|
|
- final layout is usable immediately
|
|
- changed windows animate from their current visual rect on interruption
|
|
- unaffected windows keep their existing timeline
|
|
- linear fallback is visually smooth, even if overlap occurs
|
|
- no pointer drag path becomes animated
|
|
|
|
## 5. Float Movement And Tile/Float Transitions
|
|
|
|
Cases:
|
|
|
|
- command-toggle a tiled window to floating
|
|
- command-toggle the same window back to tiled
|
|
- command-move and command-resize a floating window
|
|
- mouse-drag a floating window
|
|
- mouse-resize a floating window
|
|
- double-click/header pointer path if that is part of the local workflow
|
|
|
|
Expected:
|
|
|
|
- command-driven tile-to-float and float-to-tile transitions animate linearly
|
|
- command-driven floating move/resize animates
|
|
- mouse or tablet drag/resize remains direct and tracks the pointer
|
|
- pointer/header paths that are intentionally outside the command-animation gate
|
|
do not unexpectedly use delayed animation
|
|
- retained child content remains clipped during tile/float transitions
|
|
|
|
## 6. Multiphase Horizontal And Vertical Swaps
|
|
|
|
Horizontal:
|
|
|
|
1. Create two horizontally adjacent tiled windows.
|
|
2. Swap their positions.
|
|
3. Reverse the swap.
|
|
|
|
Vertical:
|
|
|
|
1. Create two vertically adjacent tiled windows.
|
|
2. Swap their positions.
|
|
3. Reverse the swap.
|
|
|
|
Expected:
|
|
|
|
- first phase shrinks into lanes on the orthogonal axis
|
|
- second phase moves only horizontally or only vertically
|
|
- third phase grows out of lanes
|
|
- no phase overlaps windows
|
|
- no window moves diagonally
|
|
- reverse direction uses the same visual logic in reverse
|
|
- titlebars, borders, gaps, and rounded corners remain respected
|
|
|
|
## 7. Stack Extraction And Return
|
|
|
|
Build this shape:
|
|
|
|
```text
|
|
[ A | [ B
|
|
C ] ]
|
|
```
|
|
|
|
Then move `B` out so the target is:
|
|
|
|
```text
|
|
[ A | B | C ]
|
|
```
|
|
|
|
Reverse the operation by putting `B` back into the stack.
|
|
|
|
Expected:
|
|
|
|
- peer/container space opens first
|
|
- `B` waits until there is a legal horizontal or vertical lane
|
|
- `B` moves on one axis only
|
|
- `B` and the affected peer grow together in the final phase when appropriate
|
|
- reversing the operation is visually equivalent in reverse
|
|
|
|
## 8. Nested Parent/Child Synchronization
|
|
|
|
Create nested split layouts where a parent changes one axis and children change
|
|
the other. Use both horizontal-parent/vertical-child and
|
|
vertical-parent/horizontal-child variants.
|
|
|
|
Expected:
|
|
|
|
- parent/container-space axis changes happen before child-axis changes when the
|
|
hierarchy metadata gives a deterministic order
|
|
- child windows do not visually compose parent and child transforms into
|
|
diagonal motion
|
|
- any unsupported group falls back as a group rather than partially violating the
|
|
one-axis rule
|
|
|
|
Hard failure:
|
|
|
|
- a child visibly changes width and height in the same phase
|
|
- a child moves diagonally because parent and child animation compound
|
|
- a child clips outside its animated frame
|
|
|
|
## 9. Mixed-Action Phases
|
|
|
|
This case is easiest to prove with the planner tests because Wry currently has
|
|
few user commands that create a same-batch move for one tiled window and an
|
|
independent resize for another. The canonical geometry is:
|
|
|
|
```text
|
|
start: A = (0,0)-(80,80) B = (200,0)-(280,80)
|
|
target: A = (40,0)-(120,80) B = (200,0)-(280,120)
|
|
```
|
|
|
|
`A` moves horizontally while `B` scales vertically. The windows are far enough
|
|
apart that the mixed phase is provably non-overlapping.
|
|
|
|
To exercise the current proof directly, run:
|
|
|
|
```sh
|
|
cargo test animation::multiphase::tests::mixed_single_phase_accepts_move_and_scale_when_proven
|
|
```
|
|
|
|
For visual/manual testing, use any command sequence that can produce the same
|
|
shape in one layout batch: one window changes only x-position, and a separate,
|
|
non-overlapping window changes only height.
|
|
|
|
Expected:
|
|
|
|
- mixed phases are allowed only when each individual window performs one legal
|
|
move or scale on one axis
|
|
- no individual window moves diagonally
|
|
- no overlap occurs at any point during the phase
|
|
|
|
A fallback here is acceptable if no normal user command can create this geometry;
|
|
the planner test above is the authority for the mixed-action rule.
|
|
|
|
## 10. Mono Mode
|
|
|
|
Cases:
|
|
|
|
- enter mono mode with several siblings
|
|
- exit mono mode
|
|
- switch active tabs/windows inside mono
|
|
- move a window into mono
|
|
- move a window out of mono
|
|
|
|
Expected:
|
|
|
|
- entering/exiting mono may animate where it clarifies hierarchy change
|
|
- active child animates to the mono geometry
|
|
- inactive siblings snap invisible
|
|
- ordinary tab switches inside mono do not animate
|
|
- no hidden inactive sibling leaves debris or stale retained content
|
|
|
|
## 11. Interruption And Retargeting
|
|
|
|
Use a long duration, then issue commands mid-animation:
|
|
|
|
- swap, then reverse before completion
|
|
- resize, then resize in the other direction before completion
|
|
- move a window out of a stack, then back before completion
|
|
- start a multiphase group, then change only one window's destination if a
|
|
command sequence allows it
|
|
|
|
Expected:
|
|
|
|
- affected windows restart from their current visual rect
|
|
- unaffected windows do not restart if their destination is unchanged
|
|
- a new valid multiphase plan replaces the old plan cleanly
|
|
- retained content remains the same frozen content during the retarget
|
|
- damage covers old, current, and new visual regions
|
|
|
|
## 12. Damage And Clipping Stress
|
|
|
|
Use a high-contrast wallpaper/background and high contrast window contents.
|
|
|
|
Cases:
|
|
|
|
- fast repeated swaps
|
|
- repeated spawn-in/spawn-out
|
|
- rounded corners with large gaps
|
|
- titlebar-heavy layouts
|
|
- resize while a terminal is rapidly updating
|
|
- move/resize over another window's old location
|
|
- run on different output scales if available
|
|
|
|
Expected:
|
|
|
|
- no trails remain in gaps, borders, or titlebar strips
|
|
- rounded corners do not reveal old pixels outside the frame
|
|
- contents never draw outside the animated bounds
|
|
- final frame exactly matches the steady layout
|
|
|
|
## 13. Texture Freezing
|
|
|
|
Use fast-updating contents so freezing is obvious.
|
|
|
|
Cases:
|
|
|
|
- tiled GPU/dmabuf-backed app during reflow
|
|
- floating GPU/dmabuf-backed app during command move/resize
|
|
- tile-to-float and float-to-tile with dynamic content
|
|
- spawn-out with dynamic content
|
|
- likely SHM/simple app, if available
|
|
|
|
Expected:
|
|
|
|
- retained GPU/dmabuf-backed windows freeze visually during animation
|
|
- spawn-out uses the last retained content, not a blank or unrelated frame
|
|
- undersized contents stretch/clamp to avoid unfilled frame regions
|
|
- SHM/unretained surfaces either render live safely or snap where retention is
|
|
required
|
|
|
|
Record separately:
|
|
|
|
- content continues updating during movement
|
|
- content freezes but samples the wrong source region
|
|
- edges show empty/black strips while scaling
|
|
- spawn-out skips because capture was unavailable
|
|
|
|
## 14. Cross-Output And Scale Boundaries
|
|
|
|
Cases:
|
|
|
|
- move a tiled window to another output
|
|
- move a floating window to another output
|
|
- move between outputs with different scale factors, if available
|
|
- move a workspace between outputs, if supported locally
|
|
|
|
Expected:
|
|
|
|
- movement snaps instead of animating
|
|
- no retained content is rendered at the wrong scale
|
|
- no stale damage remains on the source output
|
|
- destination output renders the final layout immediately
|
|
|
|
## 15. Regression Sweep
|
|
|
|
After visual tests, return to normal animation duration and curve.
|
|
|
|
Repeat:
|
|
|
|
- ordinary tiling navigation
|
|
- workspace switching
|
|
- fullscreen enter/exit
|
|
- focus changes
|
|
- app launch/close loops
|
|
- suspend/resume or VT switch if convenient
|
|
|
|
Expected:
|
|
|
|
- animation state does not survive across unrelated compositor state changes
|
|
- no stuck retained frames
|
|
- no persistent high CPU/GPU use after animations stop
|
|
- no obvious client throttling after many retained-content animations
|
|
|
|
## Summary Result Template
|
|
|
|
```text
|
|
Commit:
|
|
Build:
|
|
Outputs/scales:
|
|
GPU/session:
|
|
Animation config:
|
|
|
|
Passed:
|
|
-
|
|
|
|
Known-limit observations:
|
|
-
|
|
|
|
Failures:
|
|
- case:
|
|
app:
|
|
layout:
|
|
expected:
|
|
actual:
|
|
reproducible:
|
|
logs:
|
|
```
|