diff --git a/apps/desktop/src/app/contrib/wiring.tsx b/apps/desktop/src/app/contrib/wiring.tsx index 0a4a519886..9a043a1c51 100644 --- a/apps/desktop/src/app/contrib/wiring.tsx +++ b/apps/desktop/src/app/contrib/wiring.tsx @@ -1200,12 +1200,14 @@ export function ContribWiring({ children }: { children: ReactNode }) { } const titlebarToolsRight = titlebarToolsRightCss(nativeOverlayWidth, titlebarChrome) - // App controls live on the left; flip and the right toggle share the right. - const titlebarToolsWidth = titlebarToolsWidthCss(2) + // Right cluster: settings, layout, HUD, flip, right-sidebar toggle. + const SYSTEM_TOOL_COUNT = 5 + const paneToolCount = rightTitlebarTools.filter(tool => !tool.hidden).length + const systemToolsWidth = titlebarToolsWidthCss(SYSTEM_TOOL_COUNT) + const titlebarToolsWidth = + paneToolCount > 0 ? `calc(${systemToolsWidth} + ${titlebarToolsWidthCss(paneToolCount)})` : systemToolsWidth - const leftToolsWidth = titlebarToolsWidthCss( - 4 + [...leftTitlebarTools, ...rightTitlebarTools].filter(tool => !tool.hidden).length - ) + const leftToolsWidth = titlebarToolsWidthCss(1 + leftTitlebarTools.filter(tool => !tool.hidden).length) return ( @@ -1218,7 +1220,8 @@ export function ContribWiring({ children }: { children: ReactNode }) { '--titlebar-controls-width': leftToolsWidth, '--titlebar-controls-y-nudge': titlebarControlsYNudge(titlebarChrome), '--titlebar-tools-right': titlebarToolsRight, - '--titlebar-tools-width': titlebarToolsWidth + '--titlebar-tools-width': titlebarToolsWidth, + '--shell-preview-toolbar-gap': systemToolsWidth } as CSSProperties } > diff --git a/apps/desktop/src/app/shell/titlebar-controls.test.tsx b/apps/desktop/src/app/shell/titlebar-controls.test.tsx index 7f07695d73..df89595f31 100644 --- a/apps/desktop/src/app/shell/titlebar-controls.test.tsx +++ b/apps/desktop/src/app/shell/titlebar-controls.test.tsx @@ -1,5 +1,5 @@ // @vitest-environment jsdom -import { act, cleanup, render, screen } from '@testing-library/react' +import { act, cleanup, render, screen, within } from '@testing-library/react' import { MemoryRouter } from 'react-router' import { afterEach, beforeEach, describe, expect, it } from 'vitest' @@ -132,3 +132,21 @@ describe('TitlebarControls fixed clusters', () => { }) }) }) + +describe('titlebar app-action cluster', () => { + it('keeps settings, layout, and HUD on the right so the left titlebar stays free for tabs', () => { + renderControls('/') + + const left = screen.getByLabelText('Window controls') + const right = screen.getByLabelText('App controls') + + expect(within(right).getByLabelText('Open settings')).toBeTruthy() + expect(within(right).getByLabelText('Layout editor')).toBeTruthy() + expect(within(right).getByLabelText('HUD mode')).toBeTruthy() + + expect(within(left).queryByLabelText('Open settings')).toBeNull() + expect(within(left).queryByLabelText('Layout editor')).toBeNull() + expect(within(left).queryByLabelText('HUD mode')).toBeNull() + expect(within(left).getByLabelText(/Hide sidebar|Show sidebar/)).toBeTruthy() + }) +}) diff --git a/apps/desktop/src/app/shell/titlebar-controls.tsx b/apps/desktop/src/app/shell/titlebar-controls.tsx index df52dfd4b7..416ae7c674 100644 --- a/apps/desktop/src/app/shell/titlebar-controls.tsx +++ b/apps/desktop/src/app/shell/titlebar-controls.tsx @@ -196,7 +196,8 @@ export function TitlebarControls({ leftTools = [], tools = [], onOpenSettings }: tour: 'right-pane-toggle' } - // App actions stay visible beside the left sidebar toggle. + // Static system tools — always pinned to the screen's right edge so the + // left titlebar stays free for tabs (#107351). const systemTools: TitlebarTool[] = [ { actionId: 'nav.settings', @@ -285,7 +286,9 @@ export function TitlebarControls({ leftTools = [], tools = [], onOpenSettings }: ) } - const visibleLeftTools = [sidebarTool, ...systemTools, ...leftTools, ...tools].filter(tool => !tool.hidden) + const visibleLeftTools = [sidebarTool, ...leftTools].filter(tool => !tool.hidden) + const visibleSystemTools = systemTools.filter(tool => !tool.hidden) + const visiblePaneTools = tools.filter(tool => !tool.hidden) return ( <> @@ -293,16 +296,35 @@ export function TitlebarControls({ leftTools = [], tools = [], onOpenSettings }: {visibleLeftTools.map(tool => ( ))} - {titlebarSlots} + + + {visiblePaneTools.length > 0 && ( +
+ {visiblePaneTools.map(tool => ( + + ))} +
+ )} +
+ {visibleSystemTools.map(tool => ( + + ))} +
)