cmux-next iOS browser: new-tab links, long-press page menu, <select>, JS dialogs, Hard Reload, Open in Safari

Merged
AZ
6d ago
+1603-3

What

The cmux-next iPhone app now handles the page's own requests in a streamed browser tab the same way the Mac's viewer does (cmux#25834 parity, slice B):

  • P0: new-tab links. A target=_blank link, window.open, or the menu's Open Link in New Tab (rb.open_tab) opens a phone browser tab beside the page. It uses daemon new-browser-tab {url, pane}, so only http(s) and about:blank open. The tab is shown, unless the page asked for a background tab. The phone answers rb.open_tab.result {request, tab} or {refused}, as RemoteBrowserSession does. Before this change, the phone ignored these requests.
  • P0: long-press page menu. A long press sends a secondary click at that spot. The host's rb.menu.show (context) then shows as the system context menu.
    • Rows whose command runs on the Mac itself are left out: Copy Link Address, Save … As, Copy/Paste, Print, Inspect, Look Up. Showing them would be a control that does nothing on the phone.
    • The phone answers rb.menu.result with the pick, or with a cancel.
    • The page is asked only once the menu actually shows. Each press cancels only its own menu.
    • Save Image and Copy Image need image bytes on the phone. They are out of scope.
  • P1: JS dialogs. alert, confirm, prompt and beforeunload (rb.dialog.show) show as a system alert, with a text field for a prompt. The answer goes back as rb.dialog.result. rb.dialog.cancel (the page navigated away) closes the alert without an answer.
  • P1: <select>. rb.menu.show of kind select shows the options in a sheet. A swipe or Cancel sends a cancel. rb.menu.cancel closes the sheet.
  • P2: page menu rows. Hard Reload (rb.history reload_no_cache) and Open in Safari for the page's web address.

No hostd, relay or allowlist change. hostd already forwards rb.menu.result, rb.dialog.result and rb.open_tab.result (browser.rs VIEWER_MESSAGES). PROTOCOL.md documents this under browser, "Page asks".

Not done here: popup surfaces (rb.surface.show: date, color and datalist pickers). Those stream on their own rd stream and need a second decoder on the phone; PROTOCOL.md records them as not shown yet.

Tests

  • CmuxMobileBrowserStreamTests/PageEventsTests, new and covering every message above:
    • open_tab answered or refused
    • long press sends button-2 down/up
    • Mac-only rows filtered
    • one answer per menu
    • an invalid choice becomes a cancel
    • a late or unrequested menu is cancelled
    • select indices
    • dialogs: prompt text, confirm decline, beforeunload Reload, replacement, page cancel, a new session drops the open dialog
    • Hard Reload
  • CmuxMobileWorkspacesTests/aPageLinkOpensABrowserTabBesideIt: shown tab, background tab with toast, refusal toast, page-menu rows.
  • Fleet step b5b18cd72d8acab7d8a4bc3a (cmux-next-ios-sim.sh test at c1bb653): BUILD SUCCEEDED; CmuxMobileKit tests 1351 passed, 0 failed, 1 skipped.

Observed / Not run

  • Real link: the iOS app in one headless simulator and the tagged Mac app feat-cmux-next-ios-browser-events (hidden, open --env) both ran on mini-cmux11s. A small http test page is served there. Driver: cmux-next-ios/verify/parity/pq_browser_events.py. The proof report has before/after stills and videos per feature.
  • Not run: a physical iPhone; popup surfaces.

Changelog

  • Added: the cmux iPhone app opens a page's new-tab links as tabs, shows the page's long-press menu, <select> options and JavaScript dialogs, and adds Hard Reload and Open in Safari to the browser page menu.

šŸ¤– Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.