From 4f9d3459560e0fc14d882c06d0111743c677862a Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Mon, 10 Aug 2026 05:45:29 -0500 Subject: [PATCH 1/2] fix(desktop): skip titlebar Y nudge on Tahoe and macOS fullscreen Tahoe already aligns traffic lights without the optical translate. In fullscreen, drop windowButtonPosition in the main process and clear the right-cluster inset so traffic-light dodge chrome goes away on both sides. --- apps/desktop/electron/main.ts | 13 +++++-- apps/desktop/src/app/contrib/wiring.tsx | 11 ++++-- apps/desktop/src/app/shell/titlebar.test.ts | 34 ++++++++++++++--- apps/desktop/src/app/shell/titlebar.ts | 41 ++++++++++++++++++--- apps/desktop/src/global.d.ts | 2 + 5 files changed, 84 insertions(+), 17 deletions(-) diff --git a/apps/desktop/electron/main.ts b/apps/desktop/electron/main.ts index 467108228551e..7ff462e9980e4 100644 --- a/apps/desktop/electron/main.ts +++ b/apps/desktop/electron/main.ts @@ -5251,12 +5251,18 @@ async function waitForHermes(baseUrl, token, signal?, authMode?) { }) } -function getWindowButtonPosition() { +function getWindowButtonPosition(win = mainWindow) { if (!IS_MAC) { return null } - return mainWindow?.getWindowButtonPosition?.() || WINDOW_BUTTON_POSITION + // Fullscreen hides the traffic lights — treat as no left-side controls so the + // renderer drops the traffic-light dodge inset and Y nudge. + if (Boolean(win?.isFullScreen?.())) { + return null + } + + return win?.getWindowButtonPosition?.() || WINDOW_BUTTON_POSITION } function getNativeOverlayWidth() { @@ -5269,7 +5275,8 @@ function getWindowState(win = mainWindow) { isMinimized: Boolean(win?.isMinimized?.()), isVisible: Boolean(win?.isVisible?.()), nativeOverlayWidth: getNativeOverlayWidth(), - windowButtonPosition: getWindowButtonPosition() + windowButtonPosition: getWindowButtonPosition(win), + darwinMajor: IS_MAC ? DARWIN_MAJOR : 0 } } diff --git a/apps/desktop/src/app/contrib/wiring.tsx b/apps/desktop/src/app/contrib/wiring.tsx index 8825d8e8adf02..1b218f387d9ea 100644 --- a/apps/desktop/src/app/contrib/wiring.tsx +++ b/apps/desktop/src/app/contrib/wiring.tsx @@ -112,7 +112,7 @@ import { useSessionStateCache } from '../session/hooks/use-session-state-cache' import { startWorkspaceSession } from '../session/workspace-session-target' import { useOverlayRouting } from '../shell/hooks/use-overlay-routing' import { useWindowControlsOverlayWidth } from '../shell/hooks/use-window-controls-overlay-width' -import { titlebarControlsPosition, titlebarControlsYNudge, titlebarToolsWidthCss } from '../shell/titlebar' +import { titlebarControlsPosition, titlebarControlsYNudge, titlebarToolsRightCss, titlebarToolsWidthCss } from '../shell/titlebar' import { TitlebarControls } from '../shell/titlebar-controls' import { UpdatesOverlay } from '../updates-overlay' @@ -971,7 +971,12 @@ export function ContribWiring({ children }: { children: ReactNode }) { // prefer the live WCO measurement, fall back to the static reservation). const measuredOverlayWidth = useWindowControlsOverlayWidth() const nativeOverlayWidth = measuredOverlayWidth ?? connection?.nativeOverlayWidth ?? 0 - const titlebarToolsRight = nativeOverlayWidth > 0 ? `${nativeOverlayWidth}px` : '0.75rem' + const titlebarChrome = { + darwinMajor: connection?.darwinMajor ?? 0, + isFullscreen: Boolean(connection?.isFullscreen), + windowButtonPosition: connection?.windowButtonPosition + } + const titlebarToolsRight = titlebarToolsRightCss(nativeOverlayWidth, titlebarChrome) // Pane-registered tools (preview's monitor/devtools cluster) anchor flush // against the static system cluster — in the tree layout the titlebar band // sits ABOVE the grid, so AppShell's pane-width anchoring doesn't apply. @@ -990,7 +995,7 @@ export function ContribWiring({ children }: { children: ReactNode }) { { '--titlebar-controls-left': `${controlsPos.left}px`, '--titlebar-controls-top': `${controlsPos.top}px`, - '--titlebar-controls-y-nudge': titlebarControlsYNudge(connection?.windowButtonPosition), + '--titlebar-controls-y-nudge': titlebarControlsYNudge(titlebarChrome), '--titlebar-tools-right': titlebarToolsRight, '--titlebar-tools-width': titlebarToolsWidth, '--shell-preview-toolbar-gap': systemToolsWidth diff --git a/apps/desktop/src/app/shell/titlebar.test.ts b/apps/desktop/src/app/shell/titlebar.test.ts index 2b650ba9daf43..d15b3e3b5ec39 100644 --- a/apps/desktop/src/app/shell/titlebar.test.ts +++ b/apps/desktop/src/app/shell/titlebar.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest' import { + MACOS_TAHOE_DARWIN_MAJOR, TITLEBAR_CONTROL_OFFSET_X, TITLEBAR_CONTROL_SIZE, TITLEBAR_EDGE_INSET, @@ -10,6 +11,7 @@ import { titlebarControlsPosition, titlebarControlsYNudge, titlebarIconSizeCss, + titlebarToolsRightCss, titlebarToolsWidthCss } from './titlebar' @@ -44,15 +46,35 @@ describe('titlebarControlsPosition', () => { }) describe('titlebarControlsYNudge', () => { - it('nudges the left cluster on macOS when traffic lights are visible', () => { - expect(titlebarControlsYNudge({ x: 24, y: 10 })).toBe(TITLEBAR_MAC_TRAFFIC_LIGHTS_Y_NUDGE) + it('nudges pre-Tahoe macOS when traffic lights are visible', () => { + expect(titlebarControlsYNudge({ windowButtonPosition: { x: 24, y: 10 }, darwinMajor: 24 })).toBe( + TITLEBAR_MAC_TRAFFIC_LIGHTS_Y_NUDGE + ) }) - it('stays flat on Windows/Linux and macOS fullscreen', () => { - expect(titlebarControlsYNudge(null)).toBe('0px') + it('stays flat on Tahoe, Windows/Linux, and macOS fullscreen', () => { + expect(titlebarControlsYNudge({ windowButtonPosition: { x: 24, y: 10 }, darwinMajor: MACOS_TAHOE_DARWIN_MAJOR })).toBe( + '0px' + ) + expect(titlebarControlsYNudge({ windowButtonPosition: null })).toBe('0px') + expect(titlebarControlsYNudge({ windowButtonPosition: { x: 24, y: 10 }, isFullscreen: true })).toBe('0px') }) - it('nudges while macOS window-button position is still unknown', () => { - expect(titlebarControlsYNudge(undefined)).toBe(TITLEBAR_MAC_TRAFFIC_LIGHTS_Y_NUDGE) + it('nudges while macOS window-button position is still unknown on pre-Tahoe', () => { + expect(titlebarControlsYNudge({ darwinMajor: 24 })).toBe(TITLEBAR_MAC_TRAFFIC_LIGHTS_Y_NUDGE) + }) +}) + +describe('titlebarToolsRightCss', () => { + it('reserves the native overlay width when present', () => { + expect(titlebarToolsRightCss(144)).toBe('144px') + }) + + it('matches the left edge inset on macOS fullscreen', () => { + expect(titlebarToolsRightCss(0, { darwinMajor: 25, isFullscreen: true })).toBe(`${TITLEBAR_EDGE_INSET}px`) + }) + + it('keeps the default chrome inset otherwise', () => { + expect(titlebarToolsRightCss(0)).toBe('0.75rem') }) }) diff --git a/apps/desktop/src/app/shell/titlebar.ts b/apps/desktop/src/app/shell/titlebar.ts index 1099ad5eb91a4..e23ed4a3819da 100644 --- a/apps/desktop/src/app/shell/titlebar.ts +++ b/apps/desktop/src/app/shell/titlebar.ts @@ -22,15 +22,46 @@ export const TITLEBAR_FALLBACK_WINDOW_BUTTON_X = 24 // (traffic lights are hidden). Matches the right-cluster's 0.75rem padding. export const TITLEBAR_EDGE_INSET = 14 +// macOS Tahoe = Darwin 25+. Keep in sync with electron/titlebar-overlay-width.ts. +export const MACOS_TAHOE_DARWIN_MAJOR = 25 + // macOS traffic-light row only: nudge the left toolbar cluster down to sit on -// the same optical center as the native buttons. null windowButtonPosition means -// Windows/Linux (controls on the right) or macOS fullscreen (lights hidden). +// the same optical center as the native buttons on pre-Tahoe macOS. null +// windowButtonPosition means Windows/Linux, macOS fullscreen, or Tahoe. export const TITLEBAR_MAC_TRAFFIC_LIGHTS_Y_NUDGE = 'calc(var(--spacing) * 0.9)' -export function titlebarControlsYNudge( - windowButtonPosition: HermesConnection['windowButtonPosition'] | undefined +export interface TitlebarChromeContext { + darwinMajor?: number + isFullscreen?: boolean + windowButtonPosition?: HermesConnection['windowButtonPosition'] +} + +export function titlebarControlsYNudge({ + darwinMajor = 0, + isFullscreen = false, + windowButtonPosition +}: TitlebarChromeContext = {}): string { + if (isFullscreen || windowButtonPosition === null || darwinMajor >= MACOS_TAHOE_DARWIN_MAJOR) { + return '0px' + } + + return TITLEBAR_MAC_TRAFFIC_LIGHTS_Y_NUDGE +} + +/** Right-cluster inset — WCO width when present; macOS fullscreen matches left edge inset. */ +export function titlebarToolsRightCss( + nativeOverlayWidth: number, + { darwinMajor = 0, isFullscreen = false }: Pick = {} ): string { - return windowButtonPosition !== null ? TITLEBAR_MAC_TRAFFIC_LIGHTS_Y_NUDGE : '0px' + if (nativeOverlayWidth > 0) { + return `${nativeOverlayWidth}px` + } + + if (isFullscreen && darwinMajor > 0) { + return `${TITLEBAR_EDGE_INSET}px` + } + + return '0.75rem' } // Titlebar palette only. All sizing/radius/cursor/centering come from the diff --git a/apps/desktop/src/global.d.ts b/apps/desktop/src/global.d.ts index 661e7b36ceb3d..16351f112d31d 100644 --- a/apps/desktop/src/global.d.ts +++ b/apps/desktop/src/global.d.ts @@ -499,6 +499,7 @@ export interface DesktopUpdateProgress { export interface HermesConnection { baseUrl: string + darwinMajor?: number isFullscreen: boolean // The live, RESOLVED connection mode. Only ever 'local' or 'remote' — a // 'cloud' saved-config entry resolves to a 'remote' connection under the hood @@ -532,6 +533,7 @@ export interface HermesActiveWork { } export interface HermesWindowState { + darwinMajor?: number isFullscreen: boolean isMinimized?: boolean isVisible?: boolean From 4ed6f4f7f18b7b36de199e403b5f773417b92102 Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Mon, 10 Aug 2026 05:50:10 -0500 Subject: [PATCH 2/2] fix(desktop): satisfy no-extra-boolean-cast in fullscreen guard --- apps/desktop/electron/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/desktop/electron/main.ts b/apps/desktop/electron/main.ts index 7ff462e9980e4..a1d6073f0c278 100644 --- a/apps/desktop/electron/main.ts +++ b/apps/desktop/electron/main.ts @@ -5258,7 +5258,7 @@ function getWindowButtonPosition(win = mainWindow) { // Fullscreen hides the traffic lights — treat as no left-side controls so the // renderer drops the traffic-light dodge inset and Y nudge. - if (Boolean(win?.isFullScreen?.())) { + if (win?.isFullScreen?.()) { return null }