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

12 KiB

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:

[ A | [ B
        C ] ]

Then move B out so the target is:

[ 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

Commit:
Build:
Outputs/scales:
GPU/session:
Animation config:

Passed:
- 

Known-limit observations:
- 

Failures:
- case:
  app:
  layout:
  expected:
  actual:
  reproducible:
  logs: