Symptom
Element.requestFullscreen() can never succeed. Pages that go fullscreen — games, video players, map/canvas apps — silently stay windowed. Because Chrome only permits screen.orientation.lock() while fullscreen, orientation locking is unavailable too, so a mobile-aware site cannot put itself in landscape.
Cause
BrowserWebView.kt's WebChromeClient (around line 608) implements only onProgressChanged and onReceivedTitle. Android WebView routes fullscreen requests through WebChromeClient.onShowCustomView(View, CustomViewCallback) / onHideCustomView(); with neither overridden, the request is rejected and the page's promise falls into its .catch.
Impact
Discovered via mythosgame.eth, whose touch path does exactly this on starting a run:
el.requestFullscreen?.().catch(() => {});
screen.orientation.lock?.("landscape").catch(() => {});
Both no-op in Freedom, so the player gets a cramped portrait viewport for a first-person game. Well-behaved sites swallow the rejection (as this one does), so the failure is invisible — it just looks like the site is broken.
Fix sketch
- Override
onShowCustomView / onHideCustomView: add the supplied view to a full-screen container above the Compose tree, hide the browser chrome, and apply immersive mode via WindowInsetsControllerCompat. Restore on hide, and invoke the CustomViewCallback when the user backs out.
- Route the system back gesture to
onHideCustomView while a custom view is showing.
- Keep the WebView's
onPermissionRequest behaviour unchanged; this is display-only.
Ordering: depends on #8 (rotation destroys the page). Until that lands, a page that successfully locks landscape would rotate the device and — via the missing configChanges — tear its own page down. Fix #8 first, then this.
Acceptance
Symptom
Element.requestFullscreen()can never succeed. Pages that go fullscreen — games, video players, map/canvas apps — silently stay windowed. Because Chrome only permitsscreen.orientation.lock()while fullscreen, orientation locking is unavailable too, so a mobile-aware site cannot put itself in landscape.Cause
BrowserWebView.kt'sWebChromeClient(around line 608) implements onlyonProgressChangedandonReceivedTitle. Android WebView routes fullscreen requests throughWebChromeClient.onShowCustomView(View, CustomViewCallback)/onHideCustomView(); with neither overridden, the request is rejected and the page's promise falls into its.catch.Impact
Discovered via
mythosgame.eth, whose touch path does exactly this on starting a run:Both no-op in Freedom, so the player gets a cramped portrait viewport for a first-person game. Well-behaved sites swallow the rejection (as this one does), so the failure is invisible — it just looks like the site is broken.
Fix sketch
onShowCustomView/onHideCustomView: add the supplied view to a full-screen container above the Compose tree, hide the browser chrome, and apply immersive mode viaWindowInsetsControllerCompat. Restore on hide, and invoke theCustomViewCallbackwhen the user backs out.onHideCustomViewwhile a custom view is showing.onPermissionRequestbehaviour unchanged; this is display-only.Ordering: depends on #8 (rotation destroys the page). Until that lands, a page that successfully locks landscape would rotate the device and — via the missing
configChanges— tear its own page down. Fix #8 first, then this.Acceptance
requestFullscreen()fills the screen with browser chrome hidden; exiting restores the previous layout and scroll position.screen.orientation.lock('landscape')from a fullscreen page rotates without losing page state.<video>fullscreen works from a normal HTTPS page.