Skip to content

Close mobile layers with the phone's Back - #433

Merged
powerfooI merged 2 commits into
powerfooI:mainfrom
IvoryHeart:mobile-system-back
Oct 17, 2026
Merged

powerfooI merged 2 commits into
powerfooI:mainfrom
IvoryHeart:mobile-system-back

Conversation

@IvoryHeart

Copy link
Copy Markdown
Contributor

Summary

On phones, the system Back gesture or button currently leaves Roamgate, even when the tab sheet, the input dock or a mobile view such as Files is open. This PR makes Back close the open layer first, the way native apps behave.

  • New hook web/src/systemBack.ts: useSystemBack(open, close, level). It is active only in the mobile layout.
  • Wired to three layers:
    • the tab sheet (popup)
    • the input dock (panel, active pane only)
    • any mobile view other than the session, such as Workspaces, Files, Changes or Ranger (panel). Back returns to the session through activateTerminalSurface.
  • How it works:
    • While any layer is open, the current history entry is one guard entry at the same URL.
    • Back pops the guard and closes the topmost layer: the higher level first, newest first within a level. The guard returns while layers remain.
    • When the last layer closes with its on-screen control, the guard is removed once, even if several layers closed in the same React commit. The next Back leaves the page in one press.
    • A layer opened while that removal is pending (for example, a tab chosen from the sheet that opens a view) keeps its entry.
    • Unmounting leaves history alone. Desktop is unchanged.
  • FEATURES.md: one line under Mobile and PWA.
  • scripts/check-web-assets.mjs: the initial JS budget goes from 802 to 804 KiB. main measures 802.0/802 KiB; with the hook it is 803.0 KiB, and gzip is 245.6/256 KiB.

Tests

  • web/src/systemBack.test.ts. It uses happy-dom in an isolated runtime, following TerminalView.inputMode.test.ts, and renders real React commits under StrictMode. It covers:
    • layers closed together
    • on-screen closes mixed with system Back
    • two layers registering in one commit across a layout change (stacking must not depend on React effect order)
    • a layer opened while a Back is pending
    • unmount
  • TerminalView.inputMode.test.ts: its layoutPreferences mock gains useLayoutPreferences, because TerminalView now calls the hook.

Validation

  • bun run format:check, bun run lint, bun run typecheck and bun run typecheck:bun pass. bun run test:quick: 3720 pass, 0 fail.
  • The same design ships in a downstream derivative (Herdr World). There it was exercised by headless-Chrome browser tests and on a physical phone.
  • Tried by hand on a physical phone against a real Herdr backend: Back closed the tab sheet, the input dock and mobile views as expected. The device and browser weren't recorded.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AWodzpMyqdBcX25EE9HhDG

On phones, Back left Roamgate even with the tab sheet, the input dock or a
mobile view such as Files open. A small hook, useSystemBack, now gives
open layers one history entry: Back closes the topmost layer (the tab
sheet above the dock and mobile views; equal levels newest first) and
the entry returns while layers remain. When the last layer closes on
screen, the entry is removed once, even if several closed in the same
commit, so the next Back leaves the page in one press. A layer opened
while that removal is pending keeps its entry, and unmounting leaves
history alone. Desktop is unchanged.

The initial JS budget rises from 802 to 804 KiB for the hook.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AWodzpMyqdBcX25EE9HhDG
Coordinate dropdown and panel Back handling, ignore hidden Composer layers, and clean up guards on remount and reload. Preserve navigation through obsolete guards in both directions and add regression coverage.
@powerfooI
powerfooI merged commit ab0866f into powerfooI:main Oct 17, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants