Skip to content

Keep the pointer lock across app switches; build 6 - #25

Merged
mattonik merged 2 commits into
mainfrom
claude/project-thread-t8u1gh
Oct 27, 2026
Merged

mattonik merged 2 commits into
mainfrom
claude/project-thread-t8u1gh

Conversation

@mattonik

Copy link
Copy Markdown
Owner

Requested by Martin · project thread

Why

TestFlight feedback reported three problems: clicking sometimes moves the cursor across the screen, the plain iPadOS pointer comes back (including after leaving and returning to the app), and the lock often drops, leaving the game unusable.

All three come from the same place. Every time the scene deactivated (app switch, Control Center, Notification Center, a system alert or banner, a screenshot), the page was force-unlocked, and any drop of the system lock did the same. The game then sat on its "click to resume" screen with the iPadOS pointer showing. That click landed wherever the pointer had been frozen, so the game's cursor jumped there.

What changes

  • Leaving the foreground only pauses input. The new __pointerLocker.suspend() releases held buttons (with no click) and held keys, but keeps the lock. prefersPointerLocked stays true, so iPadOS locks the pointer again when the app becomes active.
  • The lock comes back on return. resume() takes the lock back for the same element if the page dropped it while the app was away, since pages may exit on blur. It does not take back a release the user asked for (Esc, ⌘., three-finger tap) or a lock that ended with the button (Figma's scrub).
  • Brief system drops keep the lock. If iPadOS drops the lock while the app is active and full screen, the page keeps its lock and the app asks UIKit for the pointer again. Leaving full screen (Slide Over, Split View, Stage Manager) still releases it.
  • Diagnostics now records lock-lost and lock-resume entries, so Copy diagnostics in the next report shows what happened.
  • Build number is now 6. The README is updated.

Testing

  • npm test passes, including five new polyfill tests for suspend and resume.
  • The Swift side has not been compiled here; CI builds it and runs the unit tests.
  • This needs a device check: switch apps mid-game, open Control Center, and come back. The lock should return without a click.

Generated by Claude Code

TestFlight feedback: clicking sometimes moved the cursor across the
screen, the plain iPadOS pointer came back after leaving and returning to
the app, and the lock often dropped leaving the game unusable.

Every scene deactivation (app switch, Control Center, Notification
Center, a system alert or banner, a screenshot) force-unlocked the page,
and any system lock drop did the same. The game then sat on its "click to
resume" screen with the iPadOS pointer showing, and that click moved the
game's cursor to wherever the pointer was.

- Leaving the foreground now only pauses input. The polyfill's new
  suspend() lets go of held buttons (no click) and keys but keeps the
  lock; prefersPointerLocked stays true, so iPadOS re-locks the pointer
  when the app is active again.
- On return, resume() takes the lock back for the same element if the
  page dropped it while away (pages may exit on blur). A release the user
  asked for (Esc, Cmd-., three-finger tap) or a lock that ended with the
  button (Figma's scrub) isn't taken back.
- A system lock drop while active and full screen keeps the page's lock
  and asks UIKit for the pointer again; leaving full screen (Slide Over,
  Split View, Stage Manager) still releases it.
- Diagnostics log lock-lost and lock-resume, so Copy diagnostics shows
  what happened in the next report.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014MACMbGBEjiVd3vDapSRQm
@mattonik mattonik self-assigned this Oct 27, 2026
@mattonik
mattonik merged commit 20fa1ec into main Oct 27, 2026
2 checks passed
@mattonik
mattonik deleted the claude/project-thread-t8u1gh branch October 27, 2026 21:28
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.

2 participants