Skip to content

Rotating the device destroys the current page (no configChanges; tab state isn't retained) #8

Description

@meinharrd

Symptom

Any orientation change loses the page. The tab does not merely reload — it resets to the home state with an empty address bar.

Reproduction (x86_64 emulator, v0.4.0)

Verified on a neutral page so this isn't site-specific:

  1. Load https://example.com/.
  2. In WebView DevTools: window.__m = 'alive' (document.titleExample Domain).
  3. Rotate: adb shell settings put system user_rotation 1.
  4. Re-evaluate: String(window.__m)undefined, document.title"", location.hrefabout:blank.

On screen afterwards: the Freedom home screen, empty address bar, page gone.

Cause

Two things compound:

  • app/src/main/AndroidManifest.xml declares no android:configChanges on .MainActivity, so Android destroys and recreates the Activity on rotation (and on other config changes — locale, uiMode, keyboard).
  • Tab state (TabsState / BrowserState) is held in plain Compose remember, with no ViewModel or rememberSaveable, so recreation starts from a fresh home tab. The WebView instances go with it.

Impact

Affects every site, not just content-addressed ones: scroll position, form input, video playback position, SPA state, and any in-page session are lost whenever the user turns the phone. It also interacts badly with pages that request landscape themselves (see #9): a successful screen.orientation.lock('landscape') would trigger this same teardown, so fullscreen support must not land before this is fixed.

Found while investigating why an ENS-hosted WebGL game (mythosgame.eth, which calls screen.orientation.lock("landscape") when a run starts) returned users to a menu on mobile.

Fix sketch

  1. Add android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize|keyboardHidden|uiMode" to .MainActivity so rotation no longer recreates it. Compose handles the config change fine; the WebViews survive.
  2. Independently, make tab state survive process death / genuine recreation — hoist it into a ViewModel, and persist the per-tab URL list so a cold restore reopens the same tabs. WebView.saveState/restoreState can carry per-tab history.

(1) alone fixes the reported symptom; (2) is the durable version and also covers low-memory kills.

Acceptance

  • Rotating with a page open keeps the page, its scroll position, and its JS state (the window.__m marker above survives).
  • Rotating with several tabs open preserves the tab set and the active tab.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions