Skip to content

fix(ui): make the Run dropdown scrollable - #542

Merged
Ark0N merged 1 commit into
Ark0N:masterfrom
opticon454:fix/run-menu-scroll
Oct 9, 2026
Merged

Ark0N merged 1 commit into
Ark0N:masterfrom
opticon454:fix/run-menu-scroll

Conversation

@opticon454

@opticon454 opticon454 commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

What

The Run dropdown could not be scrolled on a phone. With the stock CLIs plus the generated custom-endpoint entries ("Claude Code (llama.cpp)" ...), Terminal and the saved URLs, it was taller than the screen and the entries at its top were unreachable.

Cause

.run-mode-menu opens upward from the toolbar (bottom: 100%) and had no max-height and no overflow. Once the content was taller than the room above the toolbar the menu's top ran off the top of the screen, and there was nothing to scroll. A second, quieter problem once it is made scrollable: the menu is a flex column and its children that have their own overflow (the history list, the saved-URL list) have min-height: 0, so they would be squashed to nothing as the menu fills instead of the menu scrolling.

Fix (one CSS rule block)

  • max-height = the space between the header and the toolbar (100dvh, with a 100vh fallback line for browsers without dvh, so an on-screen keyboard or a collapsing browser bar shrinks it too).
  • overflow-y: auto, overscroll-behavior: contain (the page behind does not scroll when the end is reached), -webkit-overflow-scrolling: touch, touch-action: pan-y.
  • .run-mode-menu > * { flex-shrink: 0 } so the sub-lists keep their height.

Short menus are unchanged (no scrollbar when it all fits).

Tests

  • test/run-mode-menu-scroll.test.ts (CI gate): pins the rule (overflow, the dvh/vh caps tied to the header and toolbar variables, the children not shrinking).
  • test/run-mode-menu-scroll.browser.test.ts (browser suite): a phone-sized viewport with touch, 30 generated custom entries: the menu stays between the top of the screen and the Run button, is scrollable, a real touch swipe (touchstart/move/end) scrolls it so the last entry is reachable and the page does not move, and a short menu has no overflow. Verified to fail without the CSS change.
  • test/run-mode-ui.test.ts, custom-model-run-menu-ui.test.ts, webview-menu-rows.test.ts still pass.

Reported from a phone (Edge on Android).

The menu opens upward (bottom: 100%) with no max-height or overflow, so with the stock CLIs plus custom endpoint entries it was taller than the room above the toolbar and its top was off-screen and unreachable, worst on phones. Cap it to the space between the header and the toolbar (dvh, vh fallback), scroll inside it with overscroll containment, and stop its overflow:auto children (history, saved URLs) being squashed.

Tests: a CI-gate source guard and a real mobile-browser test (touch swipe reaches the last entry), which fails without the CSS.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrzFKEdBLwVfu6ev2ZscJS
@Ark0N
Ark0N merged commit e541731 into Ark0N:master Oct 9, 2026
2 checks passed
Ark0N pushed a commit that referenced this pull request Oct 9, 2026
Follow the keyboard: the menu's cap now uses var(--app-height, 100dvh)
instead of 100dvh. The viewport meta has no interactive-widget, so dvh does
not shrink for an on-screen keyboard, while MobileDetection always sets
--app-height to the visual viewport height and KeyboardHandler keeps it there
while the keyboard is up (body and .app already size the same way).

Subtract both safe areas from the cap: in the iPhone home-screen app the
phone header grows by the top inset and the toolbar sits above the bottom
inset, so without them the top of a full menu slid under the fixed header.

Add overflow-x: hidden. overflow-y: auto computes overflow-x to auto, so a
long nowrap custom-endpoint label showed a horizontal scrollbar that
touch-action: pan-y cannot pan (the same trap the file documents for
.run-mode-history).

Raise the toolbar while the Run menu is open, by adding
.toolbar:has(.run-mode-menu.active) to the existing popover raise rule. The
menu is trapped in the toolbar's stacking context, so on a touch device the
keyboard accessory bar (z 51) and the visible CJK input (z 52) covered its
last rows even when scrolled to the end. This follows the rule the case
settings popover and case combobox already use.

Reword the rule's comment: it claimed dvh follows the keyboard and that the
vh line is a fallback, and neither is true (a declaration carrying var() is
never dropped at parse time). The new text has no braces and no max-height
text, which the gate test's rule() slicer depends on.

Pin the fixes in the gate test (the --app-height and safe-area terms,
overflow-x: hidden, the toolbar raise) and retitle the cap test so it no
longer names dvh as the mechanism. The test now strips CSS comments before
reading the rule, since the rule's own comment names overflow-y: auto and
touch-action: pan-y and would otherwise keep those assertions green after the
declarations were deleted (checked by deleting them: the test now fails).

Drop .changeset/run-menu-scroll.md: it repeated the false dvh claim, and the
release writes one consolidated changeset at COM.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ark0N pushed a commit that referenced this pull request Oct 9, 2026
The Run dropdown scroll browser test built WebServer on the fixed port 3290,
which the static port guard (test/test-ports-guard.test.ts, from #556) rejects
for any file outside its shrink-only legacy list, so the CI gate failed on the
landing branch. The test now binds an ephemeral port with new WebServer(0, ...)
and navigates to server.boundPort, and its header records the new convention.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ark0N pushed a commit that referenced this pull request Oct 9, 2026
Thirteen contributor PRs, each re-checked against its GitHub head, merged
with its own merge commit and landing fixes, reviewed, and gated together
(524 test files, 10194 tests): #559, #552, #550, #556, #551, #546, #542,
#540, #555, #543, #541, #502, #432.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Ark0N

Ark0N commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Merged in 1.40.0, thanks @opticon454! Applied on the way in (ce6e4cc, fe1acd6): the menu's cap uses --app-height so it follows the on-screen keyboard (dvh does not, since the viewport meta has no interactive-widget), it subtracts both iPhone safe areas, overflow-x: hidden stops a long custom-endpoint label from adding a scrollbar nobody can pan, the toolbar is raised while the menu is open so the keyboard accessory bar cannot cover its last rows, and the browser test binds an ephemeral port for #556's new guard.

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