Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/renderer/src/app-shell/TitlebarLeftControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from '@/store/slices/worktree-nav-history'
import { useShortcutLabel } from '../hooks/useShortcutLabel'
import { useAppStore } from '../store'
import { macTrafficLightChromeForWindow } from '@/lib/desktop-window-chrome'
import { hasCustomTitleBar, isMac } from './app-window-chrome'
import type { AppChromeLayout } from './use-app-chrome-layout'

Expand Down Expand Up @@ -42,7 +43,10 @@ export function TitlebarLeftControls({ layout }: { layout: AppChromeLayout }): R
}`}
>
<div className="flex h-full items-center">
{isMac && !layout.isFullScreen ? (
{macTrafficLightChromeForWindow({
isMac,
isFullScreen: layout.isFullScreen
}).showPad ? (
<div className="titlebar-traffic-light-pad" />
) : hasCustomTitleBar ? (
/* Why: Windows/Linux remove the native title bar, so render the logo plus a ··· button that pops the application menu (as Alt does). */
Expand Down
7 changes: 6 additions & 1 deletion src/renderer/src/app-shell/app-window-chrome.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
isPairedWebClientWindow,
macTrafficLightChromeForWindow,
shouldRenderDesktopWindowChrome
} from '@/lib/desktop-window-chrome'

Expand All @@ -19,4 +20,8 @@ export const WINDOW_CONTROLS_HEIGHT = hasCustomTitleBar ? '36px' : '0px'

// Why: macOS paints traffic lights on the window's top-left edge. Windows and Linux paint their
// controls on the right, so only macOS needs a surface to keep the left edge uncovered.
export const MAC_TRAFFIC_LIGHTS_WIDTH = isMac ? '80px' : '0px'
// A paired web client on a Mac has no traffic lights (#19299).
export const MAC_TRAFFIC_LIGHTS_WIDTH = macTrafficLightChromeForWindow({
isMac,
isFullScreen: false
}).width
56 changes: 54 additions & 2 deletions src/renderer/src/lib/desktop-window-chrome.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { describe, expect, it } from 'vitest'
import { shouldRenderDesktopWindowChrome } from './desktop-window-chrome'
import { afterEach, describe, expect, it, vi } from 'vitest'
import {
macTrafficLightChromeForWindow,
macTrafficLightsWidth,
shouldRenderDesktopWindowChrome,
shouldShowMacTrafficLightPad
} from './desktop-window-chrome'

afterEach(() => {
vi.unstubAllGlobals()
})

describe('shouldRenderDesktopWindowChrome', () => {
it('renders custom chrome for frameless desktop Linux and Windows windows', () => {
Expand All @@ -16,3 +25,46 @@ describe('shouldRenderDesktopWindowChrome', () => {
expect(shouldRenderDesktopWindowChrome({ platform: 'win32', isWebClient: true })).toBe(false)
})
})

describe('mac traffic-light inset', () => {
it('reserves the inset on desktop macOS, including while fullscreen hides the pad', () => {
expect(macTrafficLightsWidth({ isMac: true, isWebClient: false })).toBe('80px')
expect(
shouldShowMacTrafficLightPad({ isMac: true, isWebClient: false, isFullScreen: false })
).toBe(true)
expect(
shouldShowMacTrafficLightPad({ isMac: true, isWebClient: false, isFullScreen: true })
).toBe(false)
})

it('does not reserve a traffic-light inset in the paired web client on a Mac', () => {
expect(macTrafficLightsWidth({ isMac: true, isWebClient: true })).toBe('0px')
expect(
shouldShowMacTrafficLightPad({ isMac: true, isWebClient: true, isFullScreen: false })
).toBe(false)
expect(
shouldShowMacTrafficLightPad({ isMac: true, isWebClient: true, isFullScreen: true })
).toBe(false)
})
Comment thread
innocarpe marked this conversation as resolved.

it('reads the paired web flag for both the inset width and the pad', () => {
vi.stubGlobal('__ORCA_WEB_CLIENT__', true)
expect(macTrafficLightChromeForWindow({ isMac: true, isFullScreen: false })).toEqual({
width: '0px',
showPad: false
})

vi.stubGlobal('__ORCA_WEB_CLIENT__', false)
expect(macTrafficLightChromeForWindow({ isMac: true, isFullScreen: false })).toEqual({
width: '80px',
showPad: true
})
})

it('does not reserve a traffic-light inset on Windows or Linux', () => {
expect(macTrafficLightsWidth({ isMac: false, isWebClient: false })).toBe('0px')
expect(
shouldShowMacTrafficLightPad({ isMac: false, isWebClient: false, isFullScreen: false })
).toBe(false)
})
})
36 changes: 36 additions & 0 deletions src/renderer/src/lib/desktop-window-chrome.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,39 @@ export function shouldRenderDesktopWindowChrome({
}: DesktopWindowChromeInput): boolean {
return !isWebClient && (platform === 'win32' || platform === 'linux')
}

/** Desktop macOS keeps the left inset for native traffic lights. A paired browser has none. */
export function macTrafficLightsWidth(input: {
isMac: boolean
isWebClient: boolean
}): '80px' | '0px' {
return input.isMac && !input.isWebClient ? '80px' : '0px'
}

/** The pad element is hidden in fullscreen; the width token above stays, matching desktop today. */
export function shouldShowMacTrafficLightPad(input: {
isMac: boolean
isWebClient: boolean
isFullScreen: boolean
}): boolean {
return input.isMac && !input.isWebClient && !input.isFullScreen
}

/**
* One read of the paired-web flag feeds both the width token and the pad.
* Call sites that pass `isWebClient` themselves can drift apart.
*/
export function macTrafficLightChromeForWindow(input: { isMac: boolean; isFullScreen: boolean }): {
width: '80px' | '0px'
showPad: boolean
} {
const isWebClient = isPairedWebClientWindow()
return {
width: macTrafficLightsWidth({ isMac: input.isMac, isWebClient }),
showPad: shouldShowMacTrafficLightPad({
isMac: input.isMac,
isWebClient,
isFullScreen: input.isFullScreen
})
}
}