1
0
Fork 0
forked from wry/wry
wry/docs/window-animations-testing.md

404 lines
12 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`
## 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
Look for layouts where one window can move on one axis while another window
scales on a different axis in the same proven phase.
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
This is easier to confirm with debug fallback logs plus visual inspection. A
fallback here is acceptable if the planner cannot prove the sequence.
## 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:
```