Keep workspace focus mode scoped and easy to exit (#2151)

* fix(workspace): keep focus mode scoped and easy to exit

Route focus mode through the active workspace so persisted state cannot hide chrome on settings or other screens. Add a visible exit control and keep desktop window chrome aligned and visually quiet.

* fix(app): clarify muted chrome semantics
This commit is contained in:
Mohamed Boudra
2026-07-16 23:46:24 +02:00
committed by GitHub
parent d2308f4835
commit a622860a3e
25 changed files with 261 additions and 30 deletions
@@ -266,6 +266,9 @@ const ThemedDynamicProviderIcon = withUnistyles(DynamicProviderIcon);
const foregroundColorMapping = (theme: Theme) => ({ color: theme.colors.foreground });
const mutedColorMapping = (theme: Theme) => ({ color: theme.colors.foregroundMuted });
const extraMutedColorMapping = (theme: Theme) => ({
color: theme.colors.foregroundExtraMuted,
});
const sourceControlPanelStrokeWidth15 = { strokeWidth: 1.5 };
@@ -1712,6 +1715,7 @@ function WorkspaceScreenContent({
const toast = useToast();
const isMobile = useIsCompactFormFactor();
const isFocusModeEnabled = usePanelStore((state) => state.desktop.focusModeEnabled);
const toggleFocusMode = usePanelStore((state) => state.toggleFocusMode);
const normalizedServerId = useMemo(() => trimNonEmpty(decodeSegment(serverId)) ?? "", [serverId]);
@@ -2966,6 +2970,11 @@ function WorkspaceScreenContent({
const handleWorkspacePaneAction = useCallback(
(action: KeyboardActionDefinition): boolean => {
if (action.id === "workspace.focus.toggle") {
toggleFocusMode();
return true;
}
if (!persistenceKey || !workspaceLayout) {
return true;
}
@@ -3039,6 +3048,7 @@ function WorkspaceScreenContent({
persistenceKey,
focusedPaneTabState.activeTabId,
focusedPaneTabState.pane,
toggleFocusMode,
workspaceLayout,
],
);
@@ -3072,6 +3082,7 @@ function WorkspaceScreenContent({
"workspace.pane.move-tab.up",
"workspace.pane.move-tab.down",
"workspace.pane.close",
"workspace.focus.toggle",
] as const,
enabled: Boolean(isRouteFocused && normalizedServerId && normalizedWorkspaceId),
priority: 100,
@@ -3366,8 +3377,8 @@ function WorkspaceScreenContent({
style={explorerToggleStyle}
>
{({ hovered, pressed }) => {
const active = isExplorerOpen || hovered || pressed;
const colorMapping = active ? foregroundColorMapping : mutedColorMapping;
const active = hovered || pressed;
const colorMapping = active ? foregroundColorMapping : extraMutedColorMapping;
return (
<>
<ThemedSourceControlPanelIcon size={16} uniProps={colorMapping} />
@@ -3412,9 +3423,9 @@ function WorkspaceScreenContent({
accessibilityLabel={explorerToggleLabel}
accessibilityState={explorerToggleAccessibilityState}
>
{({ hovered }) => {
{({ hovered, pressed }) => {
const colorMapping =
isExplorerOpen || hovered ? foregroundColorMapping : mutedColorMapping;
hovered || pressed ? foregroundColorMapping : extraMutedColorMapping;
return <ThemedPanelRight size={16} uniProps={colorMapping} />;
}}
</HeaderToggleButton>
@@ -3502,6 +3513,7 @@ function WorkspaceScreenContent({
<SplitContainer
layout={workspaceLayout}
focusModeEnabled={desktopFocusModeEnabled}
onExitFocusMode={toggleFocusMode}
workspaceKey={persistenceKey}
normalizedServerId={normalizedServerId}
normalizedWorkspaceId={normalizedWorkspaceId}
@@ -3539,6 +3551,7 @@ function WorkspaceScreenContent({
workspaceLayout,
persistenceKey,
desktopFocusModeEnabled,
toggleFocusMode,
normalizedServerId,
normalizedWorkspaceId,
isRouteFocused,
@@ -3668,6 +3681,8 @@ function WorkspaceScreenContent({
onSplitRight={noop}
onSplitDown={noop}
showPaneSplitActions={false}
focusModeEnabled={desktopFocusModeEnabled}
onExitFocusMode={toggleFocusMode}
/>
) : null}