fix(android): lower MIN_WINDOW floor so phone viewports lay out correctly

`compute_layout` runs `window.max(MIN_WINDOW)`, which acts as a
component-wise floor: any window smaller than MIN_WINDOW on either
axis gets clamped up. The previous floor of 800x600 was set with
desktop in mind, but on Android the OS-provided window size is the
device resolution (~360 dp wide on a typical phone) and the clamp
silently re-laid the board for an 800 dp width.

Side effect: total grid width (9 * card_width) became ~800 px on a
360 dp viewport, so the leftmost foundation x-position fell past
-180 and the rightmost tableau pile past +180 — both clipped at
the visible edges, matching the v0.22.3 hardware screenshot.

Lowered MIN_WINDOW to 320x400, below the smallest reasonable phone
(~360x640), so every real device flows through compute_layout
unclamped. The floor is preserved as a sentinel against degenerate
windows (Bevy can briefly report 0-size during startup or after
minimisation on some compositors). Desktop's "minimum supported
playable size" is enforced separately via WindowResizeConstraints
in solitaire_app.

Updates `layout_below_minimum_clamps_to_minimum` to use values
below the new floor, and adds a new regression test
`phone_portrait_layout_fits_horizontally` that asserts all 13
piles fit inside a 360 x 800 dp viewport.

Closes P0 #4 of docs/android/PLAYABILITY_TODO.md. 855 engine tests
pass; clippy clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-05-10 20:48:56 -07:00
parent 89a21c0587
commit 92a5ebb15e
2 changed files with 57 additions and 8 deletions
+9 -4
View File
@@ -54,10 +54,15 @@ rewrites required.
failed silently. The face-down branch then fell through to the
`card_back_colour(0)` solid-red brick fallback. Gated the
override behind `#[cfg(not(target_os = "android"))]`.
- [ ] **Viewport overflow.** Leftmost foundation and rightmost tableau
pile clipped. `LayoutResource` must recompute on Android using
actual surface size (post-inset) instead of any desktop default
width assumption.
- [x] **Viewport overflow.** *Closed 2026-05-10.* `compute_layout`
was clamping the input window up to `MIN_WINDOW = 800 × 600`,
so a 360 dp phone got laid out as if it were 800-wide and the
outer piles fell outside the actual viewport. Lowered the floor
to 320 × 400 (below the smallest reasonable phone) so real
Android resolutions flow through without clamping, while keeping
a sentinel to guard against degenerate / startup-zero windows.
New regression test `phone_portrait_layout_fits_horizontally`
asserts all 13 piles fit a 360 × 800 viewport.
## P1 — Touch UX