cmux NEXT browser: Downloads popup under its toolbar button, draggable rows; Chromium's bubble off

Merged
AU
16d ago
+778-63

Summary

In cmux-next, Chromium's own download bubble opened by itself when a download finished. cmux never shows Chromium's toolbar, so the bubble had nothing to anchor to and appeared over the middle of the page, far from cmux's Downloads button. The Downloads button opened a plain NSMenu, and an NSMenu row cannot start a drag, so a finished download could not be dragged into a terminal.

  • Chromium's bubble is off. The CEF shim sets download_bubble.partial_view_enabled to false for every request context when it loads (shim_process.mm), incognito included. In Chromium 154, DownloadBubbleUIController::GetPartialView() returns no rows while this pref is false, and OnBubbleAnchorAssembled then shows nothing. The full bubble opens only from Chromium's toolbar button, which cmux does not show.
  • The Downloads button opens a native popup (BrowserDownloadsPopup, built on NativePopupHost like the bookmark bubble). It sits under the button, right-aligned, newest download first. Clicking a finished row opens the file; dragging it carries the file URL out, so a terminal pastes its path. A right-click gives the row's actions (Open, Show in Finder, pause/resume, retry, cancel, copy link). A hovered finished row shows a folder button for Show in Finder, and the footer has one-line Open Downloads Folder and Clear Finished Downloads rows.
  • A progress ring around the Downloads button while a download runs (Chrome's): running bytes over their sizes, from 12 o'clock clockwise, in whole-percent steps over a faint track. A download of unknown size shows a short arc. No animation; the arc follows the bytes.
  • A finished download opens the popup by itself under that tab's button, without key focus (typing stays where it was). It closes after 5 s (DemandTimer) unless the pointer goes into it. A tab whose toolbar is not on screen keeps the existing notice over the tab. The popup closes when its toolbar leaves the screen (tab switch or close).

Testing

  • python3 scripts/cmux-next/prepush-gate.py: no new violations at each pushed head.
  • Fleet app builds (cmux-ci build cmux, tag nx-downloads-popover-anchor): job 07a26c025e8d at 5634e0a5 failed to compile (.failed is failed(String)), fixed in e700d94c; jobs e4a85ddc01c1 (e700d94c) and 23f29d7fdda8 (39f3fec9) built.
  • A subagent correctness review of the diff found the compile error and five smaller issues (first-click on footer buttons, the popup outliving its toolbar, stacked row observers, file checks in body, a pointer already inside). All are fixed in 39f3fec9. Its Chromium 154 source check confirmed the pref path above.

Observed / Not run

  • Observed: on 39f3fec9 in the tagged app, Chromium downloads of a local test file and an image finished (downloads.json). The person dogfooding saw cmux's popup under the Downloads button and no Chromium bubble over the page. The footer wrap they saw there is what 3a1c4c67 fixes.
  • Not run: no capture of the 3a1c4c67 footer yet. No automated drag into a terminal (this host has no screen-capture or computer-use access). No new tests: this is native popup UI, and the proof is the tagged-app dogfood.

Changelog

Fixed: cmux NEXT's download dialog opens under the browser's Downloads button instead of over the middle of the page, finished downloads drag from it into a terminal, and the button shows a progress ring while a download runs

Proof

Visual review on the exact head is still to come (macOS captures of the popup at rest, with a hovered row, and auto-shown after a download).

Checklist

  • Behavior changes have added or updated tests, or Testing says why not
  • UI change: localization audited. One new string, browserHits.downloads.showFolder ("Open Downloads Folder"), copied with all 21 locales from the existing action.browser.downloads.showFolder entry; the other strings are existing ones.

🤖 Generated with Claude Code