From d8c686177b68c9f8663b84a8f6b46893f0f089d6 Mon Sep 17 00:00:00 2001 From: LukeGus Date: Tue, 20 Oct 2026 11:21:32 -0500 Subject: [PATCH] fix: draw the title bar in the sidebar color --- src/ui/shell/TitleBar.tsx | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/ui/shell/TitleBar.tsx b/src/ui/shell/TitleBar.tsx index 98e2fa627..9ada3c06b 100644 --- a/src/ui/shell/TitleBar.tsx +++ b/src/ui/shell/TitleBar.tsx @@ -85,7 +85,7 @@ export function TitleBar() { return (
{isMac && ( @@ -140,7 +140,8 @@ export function useTitleBarOverlayColors() { // Computed colors always come back as rgb(), whatever format the // theme uses (hex, oklch, ...). const styles = getComputedStyle(document.body); - const color = toHexColor(styles.backgroundColor); + const color = + toHexColor(sidebarColor()) || toHexColor(styles.backgroundColor); if (!color) return; api.setTitleBarOverlay({ color, @@ -158,8 +159,31 @@ export function useTitleBarOverlayColors() { }, []); } -/** Turns a computed rgb()/rgba() color into a hex string. */ +/** The sidebar color of the active theme, which the bar is drawn with. */ +function sidebarColor(): string { + const probe = document.createElement("div"); + probe.style.cssText = + "position:fixed;visibility:hidden;background-color:var(--sidebar)"; + document.body.appendChild(probe); + const color = getComputedStyle(probe).backgroundColor; + probe.remove(); + return color; +} + +/** Browsers keep oklch() and similar as written, so let a canvas convert. */ +function canvasRgb(color: string): string { + const context = document.createElement("canvas").getContext?.("2d"); + if (!context) return ""; + context.clearRect(0, 0, 1, 1); + context.fillStyle = color; + context.fillRect(0, 0, 1, 1); + const [r, g, b, a] = context.getImageData(0, 0, 1, 1).data; + return a === 0 ? "" : `rgb(${r}, ${g}, ${b})`; +} + +/** Turns a computed color into a hex string. */ function toHexColor(color: string): string { + if (/^(oklch|oklab|lab|lch|color)\(/.test(color)) color = canvasRgb(color); const match = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?/); // A fully transparent color has nothing to show; keep the last one. if (!match || match[4] === "0") return "";