Skip to content

Harden panel anchoring and grid layout against late rotation geometry - #430

Merged
lstein merged 1 commit into
masterfrom
lstein/fix/chrome-ios-rotation
Nov 10, 2026
Merged

lstein merged 1 commit into
masterfrom
lstein/fix/chrome-ios-rotation

Conversation

@lstein

@lstein lstein commented Nov 10, 2026

Copy link
Copy Markdown
Owner

Summary

Hardening found while investigating a Chrome-on-iPad rotation bug. This does not fix that bug, which turned out to be in Chrome itself (see below). The changes close real gaps in how the UI follows rotation and resize.

panel-anchor.js

  • A focused checkbox, radio, range slider or button no longer holds the keyboard correction. These never raise the software keyboard, and nothing moves focus off them afterwards, so the hold could outlive later rotations. Text inputs, textareas, contenteditable and <select> still hold. On iPhone a select's picker can take the keyboard's place.
  • Any focused form control that has been hidden is now blurred, not just text fields. events.js ignores shortcuts while an INPUT or SELECT has focus.
  • After a viewport event the layout is re-measured at 150, 400, 800 and 1500 ms instead of once at 300 ms, so a rotation that is still animating is picked up. It also resyncs when the (orientation: portrait) media query changes.

grid-view.js

  • The grid layout is re-checked 1.5 s after a resize, and when the orientation media query changes.
  • The resize timers live on the instance, so a handler re-created by a rebuild cancels the old handler's pending checks.
  • Checks are skipped while the grid container is hidden (during the fade-in it measures 0 wide).

The Chrome bug this does not fix

On Chrome for iPad (CriOS 157.0.8103.37, iPadOS 26.6), rotating landscape → portrait leaves documentElement.clientWidth, 100vw/100dvh and the (orientation: portrait) media query at the landscape values. innerWidth and screen.orientation do update. InvokeAI is affected in the same way, and Safari is fine.

None of the page-side workarounds helped:

  • shrink-to-fit=no
  • rewriting the viewport meta tag after rotation
  • an explicit width=<innerWidth>

Users should use Safari, or reload after rotating, until Chrome is fixed.

Test plan

  • npm test: 1044 passing. New tests cover the non-text-control holds, late settle resampling, the media-query resync and blurring a hidden select. 7 of the new tests fail without the change.
  • npm run lint, npm run format:check
  • Adversarial pre-push review; its findings are addressed in this PR (select kept as keyboard-capable, instance-level grid timers, hidden-grid guard, blur of any hidden form control)
  • Smoke test on iPad Safari: rotate in single and grid view, open and dismiss the album pulldown, run a text search and rotate

🤖 Generated with Claude Code

- panel-anchor: a focused checkbox, radio, range or button no longer holds
  the keyboard correction (it never raises a keyboard and nothing moves
  focus off it, so the hold could outlive later rotations). Any hidden
  focused form control is now blurred, not just text fields.
- panel-anchor: resample at 150/400/800/1500ms after a viewport event
  instead of once at 300ms, and also resync on the orientation media
  query flipping.
- grid-view: re-check geometry 1.5s after a resize and on orientation
  media query changes; keep the timers on the instance so a rebuilt
  handler cancels the previous one's; skip checks while the grid is hidden.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lstein
lstein enabled auto-merge (squash) November 10, 2026 04:34
@lstein
lstein merged commit 1ee3448 into master Nov 10, 2026
11 checks passed
@lstein
lstein deleted the lstein/fix/chrome-ios-rotation branch November 10, 2026 04:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant