Skip to content

On iOS, hide the play page's own content once you tap to play - #893

Open
CanyonTurtle wants to merge 1 commit into
aduros:mainfrom
CanyonTurtle:mobile-inplace-fullscreen
Open

CanyonTurtle wants to merge 1 commit into
aduros:mainfrom
CanyonTurtle:mobile-inplace-fullscreen

Conversation

@CanyonTurtle

@CanyonTurtle CanyonTurtle commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

Problem

#860

Embedding iframes on iOS is tricky. The touch events that are supposed to only go to the fullscreen game still sometimes actually scroll the page behind the game.

This causes touches to sporadically scroll the game during play on iOS. The problem is worse on games with long descriptions, where there is more background content to scroll. This makes many games frustrating and unplayable.

Solution

This PR adds an overlay div (IOSTapOverlay.js) which catches the first tap, covers the rest of the page, and forwards that tap into the iframe (forwardTapToIframe.js) so it counts as a real press there too. The forwarded tap then triggers the runtime's own existing fullscreen-on-touch handling immediately.

PlayCart.js and NetplayCart.js both need this identically, so the state (useIOSTapToPlay.js) and the overlay element are shared.

This change lives entirely in the wasm4.org site-side code. The embed runtime is untouched.

I tested this manually on iOS (Chrome / Safari), Android, and desktop (Chrome).

Works around aduros#860 (iOS/WebKit
touch/scroll bugs for an interactive iframe in a scrollable page) the way
itch.io does: never keep a playable game embedded inline on iOS. An
overlay div (IOSTapOverlay.js) catches the first tap, hides the rest of
the page, and forwards that tap into the iframe (forwardTapToIframe.js)
so it counts as a real press there too, triggering the runtime's own
existing fullscreen-on-touch handling (app.ts, unmodified) immediately.
One-way; refresh to reset.

PlayCart.js and NetplayCart.js both need this identically, so the state
(useIOSTapToPlay.js) and the overlay element are shared.

Entirely a wasm4.org site-side change -- the embed runtime is untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ev1m5U8CexXTzdiMFdpY7b
@CanyonTurtle
CanyonTurtle marked this pull request as ready for review September 11, 2026 23:27
@haykam821

Copy link
Copy Markdown
Contributor

This pull request doesn't feel like the right solution.

@CanyonTurtle

Copy link
Copy Markdown
Contributor Author

This pull request doesn't feel like the right solution.

Thanks for the feedback, but would you please elaborate?

@CanyonTurtle

Copy link
Copy Markdown
Contributor Author

@haykam821 I want to provide a justification for why I think this PR is a worthwhile solution. Feel free to push back, as I am grateful to have your insights and critiques.

Here are the things I think make this a good change:

  1. The solution does not change the actual cartridge web bundles, or the embed code. It only changes the wasm4 game pages which contain the embeds. This makes it less likely to cause problems across the various places people deploy wasm4 web bundles.
  2. The change only alters the behavior of wasm4's game pages on mobile iOS user agents. It improves things for iOS to make it playable. Other user agents are already fine without this change, so it scopes them out.

Of course, I can see how this solution is hacky. It arguably is. it would be better if there were a simpler way to just make iOS full-screen iframes actually capture all gestures without letting touches propagate to the containing page, but I have tried various ways of doing that in isolation and haven't had any success. If you know of a way, I'm open to simplifying this approach.

This branch has not been deployed

No deployments
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