Repository navigation
Conversation
|
@edwintuan this is cool! Do you have some screenshots? Also curious on perf hit for the theme 🤔 |
hi, I will upload later, now im doing some fix |
I just upload some screenshots for both light and dark mode with glass effect
|
|
This looks... really nice |
|
Will try to have folks here test it on a few things And see what the behavior is like on Windows / Linux |
|
Going to rebase + test this out now |
…s-dark Foundation for the macOS 26 Liquid Glass theme. Type-only change. Renderer and main process changes follow. Expected narrowing-site fallout (to be addressed in later tasks): - src/renderer/src/components/settings/AppearancePane.tsx:212 (Task 9) - src/renderer/src/lib/terminal-theme.ts:63-64 (narrow internal mode/sourceTheme) - src/main/index.ts:1017 (Electron nativeTheme.themeSource) - src/main/ipc/settings.ts:47 (Electron nativeTheme.themeSource)
Task 1 widened GlobalSettings.theme to include glass-light/glass-dark. At three sinks the value flows into a 3-value 'system | dark | light' sink: - terminal-theme.ts (EffectiveTerminalAppearance mode/sourceTheme) - main/index.ts (Electron nativeTheme.themeSource) - main/ipc/settings.ts (Electron nativeTheme.themeSource) Clamp glass-light to light and glass-dark to dark at each site. The actual translucency comes from window vibrancy + the .glass-surface CSS utility, not from the OS theme source. The AppearancePane.tsx:212 narrowing site is intentionally left for Task 9, which widens the applyTheme prop type.
When the user picks a glass theme on macOS, toggle the matching glass-* root class so the new CSS selectors in main.css take effect. On non-macOS hosts, silently apply the corresponding non-glass variant — the underlying vibrancy is macOS-only and translucent surfaces without it render broken.
Electron's vibrancy + transparent: true are window-creation-only options. When the persisted theme is glass-light or glass-dark on macOS, inject them automatically so the renderer's translucent surfaces have a transparent backdrop to blur.
…ackdrop Adds --glass-blur / --glass-saturate / --glass-inner-glow / --glass-shadow controls (default to no-op), .glass-light and .glass-dark selectors that re-map role tokens to semi-transparent values, the .glass-surface utility that consumes the controls via backdrop-filter, a prefers-reduced-transparency fallback that flattens to opaque tints, and backdrop-filter on .titlebar / .titlebar-left so the titlebar picks up the active glass blur.
Adds the no-op-outside-glass utility class to popover, dropdown, hovercard, tooltip, dialog, sheet, card, command palette, and context menu content. Under glass themes these surfaces pick up the active blur and saturation via backdrop-filter; outside glass themes the class compiles to blur(0) which the browser short-circuits.
The .glass-surface utility added in 29350f9a was defined unlayered. Per CSS spec, unlayered rules beat layered ones regardless of source order, so on the dropdown-menu / context-menu / command-palette content (which carry Tailwind's backdrop-blur-2xl alongside glass-surface), .glass-surface won and resolved to blur(0) under non-glass themes — erasing the existing 40px frost. Strategy: A (variant). The four menu surfaces ship explicit semi-transparent RGBA backgrounds and a hand-tuned backdrop-blur-2xl (40px > glass's 28px) that must rule on every theme. WorktreeJumpPalette layers backdrop-blur-xl over an essentially opaque bg-background/96. backdrop-filter rules replace rather than compose, so the right fix is one blur source per surface: remove .glass-surface from the four menu sites (keeping their bespoke 40px frost) and remove backdrop-blur-xl from WorktreeJumpPalette's CommandDialog contentClassName (letting the base CommandDialog's .glass-surface own glass-theme blur on a near-opaque default-theme surface). Drops glass-surface from DropdownMenuContent, DropdownMenuSubContent, ContextMenuContent, ContextMenuSubContent (kept their backdrop-blur-2xl); drops backdrop-blur-xl from WorktreeJumpPalette contentClassName (kept the inherited glass-surface on CommandDialog). Inline why-comments explain the single-source rule at each site so the conflict can't be re-introduced. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The sidebar is a large vertical surface that benefits most from the glass backdrop. Class is no-op outside glass themes.
…dark Monaco paints its own background canvas. Without a transparent-background theme, the editor stays opaque under glass themes. Defines two Orca-specific Monaco themes inheriting vs / vs-dark with editor.background set to fully transparent and syntax colors tuned for the warm cream / cool midnight backdrops.
… viewers Task 7 wired glass-light/glass-dark Monaco themes only in the file editor. Under glass themes, diff views and ipynb cells were still painting opaque white/black rectangles instead of the transparent canvas the glass surface needs. Extracts a resolveMonacoThemeName helper and applies it consistently across all 5 Monaco consumers.
When the user hasn't set terminalBackgroundOpacity, glass themes lower the default so the terminal participates in the window vibrancy. Explicit user values still take precedence — anyone who set 1.0 keeps it.
…restart banner Adds the two glass values to the Theme segmented control on macOS, and surfaces a Restart required banner with a relaunch button when the user's selection has crossed the glass boundary since boot. Mirrors the windowBackgroundBlur restart pattern. Hidden entirely on Windows and Linux. Also widens the applyTheme prop on AppearancePane (and its caller in Settings.tsx) from the narrow 'system' | 'dark' | 'light' union to the full GlobalSettings['theme'] type, closing the deferred typecheck error from Task 1.
Extends the onboarding theme picker from 3 to 5 tiles on macOS. ChromePreview gains a glass variant that mocks a colorful wallpaper bleeding through translucent chrome so users see what they're choosing. Non-macOS users see the original 3 tiles.
Glass themes force vibrancy on at window creation, so the standalone Window Blur switch is redundant. Disable it visually and surface an italic helper explaining why.
Documents the .glass-surface utility, the --glass-* tokens, the no-nesting rule, the prefers-reduced-transparency fallback, and the dropdown/context menu exception (those keep bespoke backdrop-blur-2xl to avoid the unlayered .glass-surface beating the layered Tailwind utility).
The Glass surfaces section claimed .glass-surface reads three CSS vars and that all four --glass-* controls are 'listed above'. Reality: .glass-surface reads only --glass-blur and --glass-saturate; the other two (--glass-inner-glow, --glass-shadow) are declared for future per-surface refinements but unused today. Updated both paragraphs to match the implementation honestly.
App.tsx's theme effect explicitly branched on 'dark'/'light' and fell
through to applyDocumentTheme('system') for everything else — including
glass-light and glass-dark. The entire .glass-light/.glass-dark CSS block
was dead on arrival for users who picked a glass theme.
applyDocumentTheme already handles all 5 theme values and the non-macOS
fallback. Pass settings.theme through directly; keep the matchMedia
listener only for 'system' mode where the resolved theme depends on
OS preference.
…ancy The opaque #0a0a0a / #ffffff backgroundColor was painted behind the renderer even when vibrancy + transparent: true were set. Result: backdrop-filter blurred an opaque fallback fill (no-op visually), and rgba surfaces composited over solid white/black instead of the macOS vibrancy layer. Glass themes showed correct tint colors but zero visible blur or wallpaper bleed-through. Set backgroundColor to '#00000000' (transparent) whenever blur is true (either because a glass theme is active or because the user explicitly enabled windowBackgroundBlur). Keep the opaque fallback otherwise to avoid flash-of-unstyled-content on launch. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two bugs surfaced during user-driven visual verification: 1. CSS cascade: .glass-light / .glass-dark were placed before .dark in main.css. Since both selectors had equal single-class specificity, .dark won by being later. Result: <html class='dark glass-dark'> resolved --background to .dark's #0a0a0a hex instead of glass-dark's rgba — the renderer painted opaque dark over the (correctly transparent) BrowserWindow, hiding all vibrancy. Fixed by prefixing with :root (one extra class, higher specificity than plain .dark). 2. Token alphas were too opaque: --background at 0.70-0.74 and --sidebar at 0.55-0.62 left so little room for the wallpaper that vibrancy was barely perceptible. Tuned to macOS Liquid Glass range — sidebar at 0.35-0.40, background at 0.45-0.50, popover/card at 0.40-0.55. Bumps --muted-foreground alpha to 0.80-0.85 to preserve readability on the more translucent surfaces.
…ed-through User feedback: glass was visible but too smeared. Tuned for clarity: - --glass-blur reduced from 28px to 12px so wallpaper and lower windows read sharply through the surface instead of as a soft wash - --glass-saturate raised from 150% to 180% to keep colors lively under the lighter blur - surface alphas pushed to 0.08-0.25 range (sidebar 0.08-0.10, background 0.10-0.12, card 0.12-0.14, popover 0.22-0.25, editor 0.40) - text / foreground tokens kept at 1.0 alpha for readability
Task 8 used 0.92 which is essentially opaque — defeats the glass aesthetic the user is opting into. 0.45 lets the window vibrancy + lower-layer content visibly composite through the terminal pane while keeping syntax-highlighted text readable. Note: existing terminal panes only pick up the new default on next pane init / dev restart, because xterm options are set once at construction. Users who already have an explicit terminalBackgroundOpacity value keep it.
…rough User feedback: 12px still smeared the wallpaper / lower windows too much. 6px keeps just enough blur to feel like 'glass' (rather than naked transparency) while letting underlying content read almost sharply.
Dark --popover was rgba(15,18,32,0.78) — the same near-black as the chrome (background/sidebar/card), so dialogs / search / popovers blended into the dark blurred backdrop and read as "no frost" (only the sidebar looked frosted, since it sits over the colorful desktop). Lighten the panel fill to a distinct cool-grey rgba(34,40,60,0.82) so panels pop as frosted glass against the dark backdrop. Light mode unaffected. Local commit only — not pushed; PR update deferred per request.
Root cause of the packaged-vs-dev glass discrepancy: the renderer had no
browser target, so Vite's default ('modules', includes old Safari) made the
CSS minifier lower `backdrop-filter` to a `-webkit-backdrop-filter`-only
declaration. Electron 41's Chromium ignores `-webkit-backdrop-filter`, so the
rule resolved empty — every frosted surface lost its blur in packaged builds
(dev is unminified, so it never reproduced). Verified via CDP: computed
backdrop-filter was `none` before, `blur(18px)/blur(54px)` after.
- electron.vite.config.ts: set renderer `build.cssTarget: 'chrome120'` so CSS
is not lowered for legacy browsers the renderer never runs in.
- main.css: drop the hand-written `-webkit-backdrop-filter` lines (they made
the minifier collapse to webkit-only); the autoprefixer now emits the
standard property + prefix correctly.
- Dark panel fill held at 0.90 so panels read solid-frosted regardless.
tc:web + tc:node + lint clean. 957 test files / 9991 tests pass.
25c384e to
31275db
Compare
|
Coordinator evidence update: I took over this PR under the current non-team and newer-than-2026-05-01 scope. The macOS glass-theme direction is valid, but the branch needed a current-main merge plus scoped fixes for non-macOS isolation, settings search, accessible controls, and restart-banner lifetime. Pushed commit Evidence:
Residual validation gap: GitHub currently reports no status checks for head |
# Conflicts: # src/renderer/src/lib/document-theme.test.ts
|
Coordinator update: I rechecked this against current Reproduction before fix:
Resolution:
Evidence after fix:
No merge performed. |
# Conflicts: # src/renderer/src/components/sidebar/index.tsx
|
Second coordinator update: Fresh reproduction before this push:
Resolution:
Evidence after fix:
No merge performed. |
|
Thank you to @edwintuan for the original implementation, really nice feature. I've put up #3972 implementing the same glass effect with a much simpler, mostly-CSS approach and minimal file/code changes: it reuses the existing @nwparker - would you mind taking a look at #3972 as a lighter-weight alternative when you get a chance, thank you. |
Brovo! I'd like to try this |
|
Closing as superseded by #36580, which adds Opaque, Translucent and Blurred window materials on macOS, Windows and Linux (plus Reduce Visual Effects) and fixes the transparent-terminal flicker. Thank you for this PR, it shaped the design. |












Summary
Adds a native macOS glass/vibrancy visual layer to Orca, exposed as an
independent
glassEffectboolean that composes orthogonally with theexisting
themesetting. System + Glass tracks OS dark/light whilekeeping the frosted surfaces.
Settings model
theme: 'system' | 'dark' | 'light'— unchanged (3 values).glassEffect: boolean— new, defaultsfalse, effective on macOS only.follows OS dark/light AND keeps glass.
UX surface
"Glass effect" switch underneath. The switch is hidden on Linux/Windows.
Toggling glass requires a window recreate → restart banner appears.
Glass is opt-in later via Settings, not surfaced during first-run, so
new users don't have to make a 5-way decision about a visual layer
they haven't seen yet.
layers fighting each other).
Cross-platform behavior
Glass is macOS-only by design — it leans on
NSVisualEffectViewvibrancy, which has no equivalent on Linux/Windows.
BrowserWindowis created withvibrancy: 'under-window',transparent: true, andbackgroundColor: '#00000000'so the systemblur shows through. CSS layers
.glass-light/.glass-darkareapplied on top.
isGlassEffectActive(settings)short-circuits tofalseregardless of the storedglassEffectvalue. The Settingsswitch is hidden. No translucent window, no CSS glass classes, no
Monaco glass theme. Behavior is identical to
main.glassEffect: truevalue still persists on non-macOS hosts(e.g. user toggles it on macOS, then opens the same profile on Linux);
it just has no visual effect there. This keeps profiles portable
without surprising state loss.
prefers-reduced-transparencyis respected via existing media queryhooks — frosted surfaces fall back to opaque.
Migration
Older builds shipped a 5-value theme picker (
glass-light/glass-darkas discrete theme values).
persistence.tsmain-process load detects thelegacy values and rewrites them on disk:
themethemeglassEffect'glass-light''light'true'glass-dark''dark'trueloadNeedsSaveis stamped so the migration persists on first run.Implementation notes
isGlassEffectActive(settings, { isDarwin? })isthe only runtime check — accepts an optional
isDarwinoverride fortests. All call sites (window creation, terminal theme, Monaco
resolution, AppearancePane, etc.) read this, never the raw setting.
.glass-*classes use:root.glass-light/:root.glass-darkselectors so they win over.dark(samespecificity otherwise, source-order would lose).
right-rail, terminal pane) derives from a single RGB base under glass,
eliminating visible region seams.
bg-background-opaquefor popovers / dialogs/ sheets that need a guaranteed opaque surface while the app frame is
translucent.
clears caused flicker on scroll/Enter) and forces
`inactivePaneOpacity = 1.0` (rgba alpha × inactive multiplier was
flipping color on focus change). Scrollbar gutter is filled to remove
the transparent strip between terminal and right rail.
transparent backgrounds, wired through `resolveMonacoThemeName(settings, isDark)`
in DiffViewer, IpynbViewer, MonacoEditor, MonacoCodeExcerpt,
DiffSectionItem.
from `bg-black/50` → `rgba(0,0,0,0.12)` under glass (otherwise a 50%
black overlay on a translucent app reads as fully black). Frosted
panels use `bg-popover` + `.glass-surface-strong` (3× blur) for
readability.
Testing
tracking OS preference, non-macOS silently ignoring `glassEffect`,
class transitions when the flag flips.
`pane-webgl-renderer-glass.test.ts`, `createMainWindow.test.ts`,
`ThemeStep.test.tsx` all updated for the new signature.
Docs
`--glass-*` token consumption and when to reach for opaque vs frosted
vs strong-frosted tiers.
Risk assessment
Risk: HIGH
Historic risk metadata backfill based on the existing
risk:highlabel.Risk: high
Historic risk metadata backfill based on the existing
risk:highlabel.ELI5
Optional macOS-only glass/vibrancy effect as a separate setting from light/dark theme, so you can combine system theme with frosted glass.