Skip to content

check-overlay-glass: hover card bodies draw only on the one glass window (stacked on #23801) - #24022

Merged
teamleaderleo merged 10 commits into
feat-cmux-nextfrom
glass-regressions/glass-previews
Oct 22, 2026
Merged

teamleaderleo merged 10 commits into
feat-cmux-nextfrom
glass-regressions/glass-previews

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Native hover cards can't turn solid again. The new lint rules apply to every hover card body.

Leo-ask: ask-d547ac77f0

Stacked on #23801, which adds scripts/cmux-next/check-overlay-glass.py. This branch starts from #23801's head (433dfb0), so review only the top commit (2df1ca0). After #23801 squash-merges, a base merge reduces the diff to that commit.

Audit (native). Every native hover card already shows in the app's one hover card window, HoverCardPanel, which is plain themed glass (#23740; #23801 made the card fill opt-in). None needed a fix:

  • tab and tab group cards (TabHoverCardView, GroupHoverCardView)
  • link chip preview in Home (HomeLinkPreviewCardView)
  • sidebar workspace and group cards (WorkspaceHoverCard)
  • sidebar pull request card (SidebarPullRequestCard)
  • What's New highlights (SidebarUpdateCardView+Popover)

The only fills inside them are Palette.hoverFill (thumbnail placeholder, row hover), clear, and a pill tint at 14%.

Change. check-overlay-glass.py now treats any file that hands a body to that window (HoverCardBody() or reports a card's lines (HoverCardTextReporting) as a hover card body, and flags:

  • hover-own-window: the body builds its own window or material (NSPanel, NSPopover, NSWindow, NSVisualEffectView, OverlaySurfaceView, makeOverlayPanel).
  • hover-body-fill: a backgroundColor, fillColor or .background(...) that isn't Palette.hoverFill, clear, nil, or a color under 0.6 alpha. Each branch of a ternary is checked.

The panel and its definitions are exempt (HoverCardPanel.swift, HoverCardSource.swift, HoverCardRow.swift). The glass-opaque-allow: escape and the ALLOWED table work as before. check-overlay-glass.test.sh adds fixtures that should fail (popover, own glass, solid fill, solid ternary branch) and ones that should pass (hover fill, clear, 14% pill, escaped dot, the same fill outside a body).

The web hover cards are covered by #23997.

Verification (huge-blue):

  • python3 -I scripts/cmux-next/check-overlay-glass.py . → ok.
  • bash scripts/cmux-next/tests/check-overlay-glass.test.sh → ok.
  • Mutation check: adding layer?.backgroundColor = Palette.background.cgColor to TabHoverCardView.swift gives [hover-body-fill] at that line. Reverted afterwards.

This commit changes no Swift; the only Swift in the diff comes from #23801.

No capture: lint only, nothing on screen changes.

Agent session: cosmic-gray

🤖 Generated with Claude Code


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


Summary by cubic

Adds hover card body rules to check-overlay-glass.py so native hover cards can't turn solid again. With #23801 merged into base, this branch carries only the lint and its tests. Hover card bodies must draw only on the app's one glass hover card window (HoverCardPanel).

  • hover-own-window flags a body that builds its own window or material (NSPanel, NSPopover, NSWindow, NSVisualEffectView, OverlaySurfaceView, makeOverlayPanel).
  • hover-body-fill flags a backgroundColor / fillColor / .background(...) that isn't Palette.hoverFill, clear, nil, or under 0.6 alpha; each ternary branch is checked.
  • Existing glass-opaque-allow: comments and the ALLOWED table still apply, and stale allowances fail.
  • check-overlay-glass.test.sh adds failing and passing fixtures for each rule form.

Written for commit 73583d3. Summary will update on new commits.

View guided diff Turn on auto-fix

teamleaderleo and others added 6 commits October 21, 2026 14:04
…t a solid card

Leo 2026-10-21 on his nightly: "WHY IS THIS SOLID COLOR AGAIN". The app's one
hover card window (session and tab hover cards, and the Update Ready card's
What's New highlights popover) was themed Liquid Glass after #21785; ccde782
then laid the mostly opaque CardMaterial fill (at least 90%) over every
theme-tone overlay, this window included, so these cards read as solid again.

Glass.makeOverlayPanel takes cardFill (default true, so the palette, popovers
and bars keep the card fill); HoverCardPanel and the hover card gallery host
pass false and draw the shared themed overlay glass alone. Reduce Transparency
stays solid.

FloatingSurfacesStayGlassTests fails when a fill between the hover card's or
the Update Ready card's material and its content is denser than the shared
glass (FloatingGlassStyle veils, the themed overlay tint), on Liquid Glass and
on the pre-26 blur, and proves the check catches the card fill.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16027-a80b-79c0-ab31-500e58883d27&host=cosmic-gray
…t so

Leo 2026-10-21: "STOP DOING SOLID. WE HAVE GLASS, SO JUST USE GLASS."

- Glass.makeOverlayPanel's card fill is opt-in (cardFill defaults to false):
  the palette, popovers, menus, find and prompt bars, browser bubbles and
  page info draw the shared themed glass alone. Takes back ccde782 (no
  PR), which laid the mostly opaque CardMaterial fill (90% or more) on every
  overlay. Reduce Transparency stays solid.
- The notifications panel and New Message's recipient suggestions sit on the
  shared overlay glass instead of the elevated / popup surface.
- Home's import cards are real glass with the dialogs' neutral veil and rim,
  not ReduceTransparency.alwaysOpaque.
- The sidebar's edit bar draws the sidebar cards' veil, solid only under
  Reduce Transparency.
- check-overlay-glass.py (cmux-next checks job, the prepush gate, and its
  own test) names every solid surface fill in CmuxNext: the popup surface,
  elevated fills, solid system colors, alwaysOpaque, cardFill: true and
  solid SwiftUI backgrounds. A hit passes only with a listed reason or a
  `glass-opaque-allow:` comment, and a stale allowance fails.
- FloatingSurfacesStayGlassTests: every default overlay is glass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16027-a80b-79c0-ab31-500e58883d27&host=cosmic-gray
…ssions/glass-sweep

# Conflicts:
#	Packages/macOS/CmuxNext/Sources/CmuxNextDesign/CardMaterial.swift
#	Packages/macOS/CmuxNext/Sources/CmuxNextDesign/Glass.swift
#	Packages/macOS/CmuxNext/Sources/CmuxNextDesign/OverlaySurface.swift
#	Packages/macOS/CmuxNext/Sources/CmuxNextDesign/Tunables/ChromeTunables.swift
#	Packages/macOS/CmuxNext/Tests/CmuxNextDesignTests/FloatingSurfacesStayGlassTests.swift
…ssions/glass-sweep

# Conflicts:
#	Packages/macOS/CmuxNext/Sources/CmuxNextImportCards/ImportCardsStripView.swift
…er card window

Every native hover card (tab, link chip, sidebar workspace and group,
pull request, What's New) shows in HoverCardPanel, the bare themed glass
(#23740, #23801). Each body is glass today, but nothing stopped one from
building its own window or material or laying a solid fill over the
panel's glass.

The lint now finds hover card bodies (files with HoverCardBody(...) or
HoverCardTextReporting) and flags:
  hover-own-window  NSPanel / NSPopover / NSWindow / NSVisualEffectView /
                    OverlaySurfaceView / makeOverlayPanel in a body;
  hover-body-fill   a backgroundColor / fillColor / .background(...) that
                    isn't Palette.hoverFill, clear, nil or a color under 0.6
                    alpha (each ternary branch is checked).
The existing glass-opaque-allow escape and ALLOWED table apply. The
shell test adds fixtures for each form and the passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by glass-regressions on cosmic-gray · session

@teamleaderleo teamleaderleo added the risk:low Risk tier (docs/ci/risk-tiers.md) label Oct 22, 2026
@github-actions github-actions Bot removed the risk:low Risk tier (docs/ci/risk-tiers.md) label Oct 22, 2026
@blacksmith-sh

blacksmith-sh Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Found 11 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp0gf2auq1/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmplet8_pmw/summary-fail.json (live):/summary-fail.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs
convention violations found (ERROR lines above)./
convention violations found (ERROR lines above).
View Logs
nightly cmux-tui resolve/nightly cmux-tui resolve View Logs
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules)/
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules)
View Logs
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules) (job='web-bundles')/
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules) (job='web-bundles')
View Logs

...and 1 more test failures. View all on Blacksmith

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

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 73583d3: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr24022 -f ref=glass-regressions/glass-previews -f platform=macos -f backend_mode=local

red: cmux-next checks (god files, concurrency, crash safety, l10n); NEW: red check: Checks job structure (+1 more) is not red on the base b5a78a8; do not merge until green; see lane-rules

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 22, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-y2xcb created for this PR by the cmux coordinator.

#23801 squash-merged as 0b71d5e; base wins for all of its content. The only
change left on this branch is 2df1ca0 (hover card body lint and its test),
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent, correctness first): SHIP at 4836628

The new head is a base merge (feat-cmux-next at df74f47; #23801's content comes from base unchanged as 0b71d5e) plus the reviewed commit 2df1ca0, also unchanged: git diff feat-cmux-next 4836628f is exactly 2df1ca0's +/- lines in scripts/cmux-next/check-overlay-glass.py and scripts/cmux-next/tests/check-overlay-glass.test.sh, and nothing else. No Swift in the diff. check-overlay-glass.py passes on the merged tree, and so does check-overlay-glass.test.sh.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next guards / nightly-guards / workflow-guard-tests / release-notary is red on 12 of 18 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (Codex xhigh via acpmux, correctness first): SHIP at 73583d3
BLOCKING: none
NON-BLOCKING: The hover checks are line-oriented regexes; multiline fill expressions and some multi-argument .background(...) forms are not covered by the new fixtures.
CHECKED: Diffed merge-base b5a78a8 to the exact head; only the lint and its shell fixture test changed. Ran the lint on the full extracted PR tree (ok), the fixture test (ok), bash -n, and a base-script/head-fixtures red-before check. Injecting Palette.background into the real TabHoverCardView was caught as [hover-body-fill]. Inspected the real HoverCardBody/HoverCardTextReporting callers, HoverCardPanel's cardFill: false glass construction and existing Reduce Transparency path, theme-derived fills, and the absence of hard-coded orange or new Swift per-frame/layout work. Verified CI and the prepush gate invoke both the lint and fixture test. No native Swift build/tests were run, per the explicit review restriction.

@teamleaderleo
teamleaderleo merged commit ae7da5f into feat-cmux-next Oct 22, 2026
@teamleaderleo
teamleaderleo deleted the glass-regressions/glass-previews branch October 22, 2026 08:34
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant