Skip to content

Mobile: full-screen terminal, a Type box, and a Sessions screen - #1495

Merged
nedtwigg merged 6 commits into
mainfrom
mobile-refresh
Nov 1, 2026
Merged

nedtwigg merged 6 commits into
mainfrom
mobile-refresh

Conversation

@nedtwigg

@nedtwigg nedtwigg commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

Makes the mobile composition (Pocket, the one-time page, and the Pocket playground) full screen, with its controls in one bar at the bottom. The old layout had mode rows above and below the terminal, plus a Minimize button whose purpose wasn't clear.

  • Modes: Gestures, Select, Mouse, and Type, all in the bottom bar.
  • Type replaces live keystrokes. Soft-keyboard word prediction made those unreliable. Type opens a box at the top of the screen, with a Password checkbox, Cancel, and Send.
    • Send goes through the paste path, then Enter; a password is typed raw instead.
    • Cancel keeps the text for the next Type. Send clears it, and a password is never kept.
  • Physical keyboards still type straight into the terminal while the box is closed, and their Command+V still pastes.
  • Keyboard pan: while the box is open, the terminal is moved above the OS keyboard rather than resized, so the PTY size never changes.
  • Sessions screen: tapping the Session title opens a full-screen list, which replaces Minimize.
  • Settings: behind a labelled button on that screen.
    • Theme uses the desktop dropdown, showing the current theme.
    • Font size has a live sample underneath, in the terminal's font and colors.
    • The one-time page saves neither choice.
  • Top bars: 44px in every view, so the bar holds still between them and its controls are real touch targets.

Fixes that reach beyond mobile

  • Descenders: pane-header labels clipped the bottoms of letters like g and p, on desktop too. leading-none became leading-tight.
  • Controls inside the terminal area: Gestures and Mouse modes swallowed presses on header buttons. Any button or link there now takes its own press.
  • Playground height: the playground used 100vh, which on iOS Safari left the bottom bar under the toolbar. It now uses dvh, as Pocket and the one-time page already did.
  • Picker shrinking: ThemePicker and ShellPicker own their min-w-0, replacing the [&>div]:min-w-0 selector in the Settings dialog's rows. ThemePicker's settings-dialog variant is renamed row, since the phone uses it too.

onSessionMinimize on MobileWall is now onShowSessions, and xterm font size can be overridden through setTerminalFontSize.

Testing

  • Passing: lib, standalone, and website type-checks, the component, remote, and theme tests, and the spec, Markdown, e2e, and public-docs lints. This is on the tree merged with main, but I didn't re-check it in a browser after the merge.
  • Checked before the merge, in Storybook and the phone playground under iPhone emulation: the layout, the Type box, Sessions, Settings, and the bar and button sizes.
  • Argos: 9 changed, 5 added, and 3 removed snapshots await review, and 531 are unchanged. The changes are the mobile stories this PR reworks, plus NetworkSettings, whose only diff is the date on its "Paired" line, which this PR doesn't touch.
  • The bottom-bar height fix was confirmed by hand in the phone playground, where the bar had been missing.
  • Still to check:
    • The keyboard pan on a real iPhone. The fallback is to shrink the terminal instead.
    • Command+V from a physical keyboard on an iPad. The hidden field that used to receive it is gone, so this now relies on WebKit firing paste with nothing editable focused, which is only covered by synthetic events.
    • The docs navbar after the picker shrinking change. Argos shows no change to the Settings dialog stories.

🤖 Generated with Claude Code

nedtwigg and others added 5 commits October 29, 2026 18:09
The bottom input modes (Sessions, Recent, Type, Draft) and their fixed
keyboard reserve are gone. The terminal now fills the screen above one bar:
Gestures, Select, Mouse, and Type.

- Type opens a composer at the top: a text field, a Password checkbox,
  Cancel, and Send. Send writes the text through the paste path (bracketed
  when the app asks), then Enter; a password is written raw. Soft-keyboard
  keystrokes are never sent live, since autocorrect made them unreliable.
- While the composer is open the terminal pans up above the OS keyboard
  instead of resizing, so the PTY keeps its size.
- A physical keyboard types straight into the terminal while the composer
  is closed.
- Minimize opens a full-screen Sessions screen, with a Settings page for
  terminal font size and theme. The one-time page keeps nothing.
- MobileWall's header is pane chrome: in Gestures and Mouse modes the
  host's capture no longer swallows its Minimize, Kill, and TODO buttons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Any button or link inside the gesture host takes its own press, replacing
  the MobileWall-only data-mobile-pane-chrome opt-out.
- Composer owns its text and Password checkbox, so a keystroke re-renders
  only the box; the parent keeps just whether it is open.
- Keyboard pan subscribes through subscribeOverlayViewport and skips
  unchanged insets instead of re-rendering on every viewport event.
- Physical keys map through a table onto MOBILE_TERMINAL_KEY_SEQUENCES.
- useThemeChoice is shared by ThemePicker and MobileSettings.
- PocketWall takes one persist prop instead of restoreTheme plus
  persistSettings; usePocketTheme syncs browser chrome on any theme change.
- Font size persists through local-json-store; Cancel and Send use
  modalActionButton; one scroll container on the Sessions screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Settings: the desktop theme dropdown first (showing the picked theme),
  then font size over a live terminal-styled sample.
- The header's Session title opens the Sessions screen; Minimize is gone.
  The Settings button is labelled.
- Every top bar is 44px, its controls full-height touch targets.
- A cancelled Type draft comes back on the next Type; Send clears it, and a
  password is never kept.
- Pane-header labels no longer clip descenders (desktop and mobile).
- The playground fills the dynamic viewport, so iOS Safari's toolbar no
  longer hides the mode bar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Kill was 44x16: `HeaderActionButton`'s wrapper collapsed its `h-full`.
- The kept draft derives in one place, so a password can't slip through.
- `useThemeChoice` folds back into `ThemePicker`, its only user; the
  `settings-dialog` variant is now `row`, which the phone uses too.
- `MOBILE_BAR_HEIGHT_CLASS` replaces two heights kept in step by a comment.
- `ThemePicker` and `ShellPicker` own their `min-w-0`, so parents stop
  reaching into their markup.
- The header title renders once and reaches the right edge in Pocket.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	lib/src/components/MobileTerminalUi.tsx
#	scripts/spec-word-budgets.json
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: 07920f6
Status: ✅  Deploy successful!
Preview URL: https://41eed3a6.mouseterm.pages.dev
Branch Preview URL: https://mobile-refresh.mouseterm.pages.dev

View logs

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A physical keyboard's ⌘V no longer reaches the terminal outside the composer; see the inline comment.

Comment thread lib/src/components/MobileTerminalUi.tsx Resolved
Removing the hidden textarea removed the only receiver of a `paste` event, so
Command+V did nothing while the composer was closed. A window listener beside
the hardware-key one takes it, on the same targets and gates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nedtwigg
nedtwigg merged commit 0cd6111 into main Nov 1, 2026
19 checks passed
@nedtwigg
nedtwigg deleted the mobile-refresh branch November 1, 2026 20:40
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