Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support updating setting in zen mode #200158

Merged
merged 1 commit into from Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/vs/platform/actions/common/actions.ts
Expand Up @@ -70,6 +70,7 @@ export class MenuId {
static readonly EmptyEditorGroupContext = new MenuId('EmptyEditorGroupContext');
static readonly EditorTabsBarContext = new MenuId('EditorTabsBarContext');
static readonly EditorTabsBarShowTabsSubmenu = new MenuId('EditorTabsBarShowTabsSubmenu');
static readonly EditorTabsBarShowTabsZenModeSubmenu = new MenuId('EditorTabsBarShowTabsZenModeSubmenu');
static readonly EditorActionsPositionSubmenu = new MenuId('EditorActionsPositionSubmenu');
static readonly ExplorerContext = new MenuId('ExplorerContext');
static readonly ExplorerContextShare = new MenuId('ExplorerContextShare');
Expand Down
119 changes: 76 additions & 43 deletions src/vs/workbench/browser/actions/layoutActions.ts
Expand Up @@ -7,7 +7,7 @@ import { localize } from 'vs/nls';
import { MenuId, MenuRegistry, registerAction2, Action2 } from 'vs/platform/actions/common/actions';
import { Categories } from 'vs/platform/action/common/actionCommonCategories';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkbenchLayoutService, Parts, Position, positionToString } from 'vs/workbench/services/layout/browser/layoutService';
import { EditorTabsMode, IWorkbenchLayoutService, LayoutSettings, Parts, Position, ZenModeSettings, positionToString } from 'vs/workbench/services/layout/browser/layoutService';
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes';
import { isWindows, isLinux, isWeb, isMacintosh, isNative } from 'vs/base/common/platform';
Expand Down Expand Up @@ -449,83 +449,108 @@ export class ToggleStatusbarVisibilityAction extends Action2 {

registerAction2(ToggleStatusbarVisibilityAction);

// --- Hide Editor Tabs

export class HideEditorTabsAction extends Action2 {
// ------------------- Editor Tabs Layout --------------------------------

static readonly ID = 'workbench.action.hideEditorTabs';
abstract class AbstractSetShowTabsAction extends Action2 {

constructor() {
constructor(private readonly settingName: string, private readonly value: string, title: ICommandActionTitle, id: string, precondition: ContextKeyExpression) {
super({
id: HideEditorTabsAction.ID,
title: {
value: localize('hideEditorTabs', "Hide Editor Tabs"),
original: 'Hide Editor Tabs'
},
id,
title,
category: Categories.View,
precondition: ContextKeyExpr.and(ContextKeyExpr.equals('config.workbench.editor.showTabs', 'none').negate(), InEditorZenModeContext.negate()),
precondition,
f1: true
});
}

run(accessor: ServicesAccessor): Promise<void> {
const configurationService = accessor.get(IConfigurationService);
return configurationService.updateValue('workbench.editor.showTabs', 'none');
return configurationService.updateValue(this.settingName, this.value);
}
}

// --- Hide Editor Tabs

export class HideEditorTabsAction extends AbstractSetShowTabsAction {

static readonly ID = 'workbench.action.hideEditorTabs';

constructor() {
const precondition = ContextKeyExpr.and(ContextKeyExpr.equals(`config.${LayoutSettings.EDITOR_TABS_MODE}`, EditorTabsMode.NONE).negate(), InEditorZenModeContext.negate())!;
const title = { value: localize('hideEditorTabs', "Hide Editor Tabs"), original: 'Hide Editor Tabs' };
super(LayoutSettings.EDITOR_TABS_MODE, EditorTabsMode.NONE, title, HideEditorTabsAction.ID, precondition);
}
}

export class ZenHideEditorTabsAction extends AbstractSetShowTabsAction {

static readonly ID = 'workbench.action.zenHideEditorTabs';

constructor() {
const precondition = ContextKeyExpr.and(ContextKeyExpr.equals(`config.${ZenModeSettings.SHOW_TABS}`, EditorTabsMode.NONE).negate(), InEditorZenModeContext)!;
const title = { value: localize('hideEditorTabsZenMode', "Hide Editor Tabs in Zen Mode"), original: 'Hide Editor Tabs in Zen Mode' };
super(ZenModeSettings.SHOW_TABS, EditorTabsMode.NONE, title, ZenHideEditorTabsAction.ID, precondition);
}
}
registerAction2(HideEditorTabsAction);

// --- Show Multiple Editor Tabs

export class ShowMultipleEditorTabsAction extends Action2 {
export class ShowMultipleEditorTabsAction extends AbstractSetShowTabsAction {

static readonly ID = 'workbench.action.showMultipleEditorTabs';

constructor() {
super({
id: ShowMultipleEditorTabsAction.ID,
title: {
value: localize('showMultipleEditorTabs', "Show Multiple Editor Tabs"),
original: 'Show Multiple Editor Tabs'
},
category: Categories.View,
precondition: ContextKeyExpr.and(ContextKeyExpr.equals('config.workbench.editor.showTabs', 'multiple').negate(), InEditorZenModeContext.negate()),
f1: true
});
const precondition = ContextKeyExpr.and(ContextKeyExpr.equals(`config.${LayoutSettings.EDITOR_TABS_MODE}`, EditorTabsMode.MULTIPLE).negate(), InEditorZenModeContext.negate())!;
const title = { value: localize('showMultipleEditorTabs', "Show Multiple Editor Tabs"), original: 'Show Multiple Editor Tabs' };

super(LayoutSettings.EDITOR_TABS_MODE, EditorTabsMode.MULTIPLE, title, ShowMultipleEditorTabsAction.ID, precondition);
}
}

run(accessor: ServicesAccessor): Promise<void> {
const configurationService = accessor.get(IConfigurationService);
return configurationService.updateValue('workbench.editor.showTabs', 'multiple');
export class ZenShowMultipleEditorTabsAction extends AbstractSetShowTabsAction {

static readonly ID = 'workbench.action.zenShowMultipleEditorTabs';

constructor() {
const precondition = ContextKeyExpr.and(ContextKeyExpr.equals(`config.${ZenModeSettings.SHOW_TABS}`, EditorTabsMode.MULTIPLE).negate(), InEditorZenModeContext)!;
const title = { value: localize('showMultipleEditorTabsZenMode', "Show Multiple Editor Tabs in Zen Mode"), original: 'Show Multiple Editor Tabs in Zen Mode' };

super(ZenModeSettings.SHOW_TABS, EditorTabsMode.MULTIPLE, title, ZenShowMultipleEditorTabsAction.ID, precondition);
}
}
registerAction2(ShowMultipleEditorTabsAction);

// --- Show Single Editor Tab

export class ShowSingleEditorTabAction extends Action2 {
export class ShowSingleEditorTabAction extends AbstractSetShowTabsAction {

static readonly ID = 'workbench.action.showEditorTab';

constructor() {
super({
id: ShowSingleEditorTabAction.ID,
title: {
value: localize('showSingleEditorTab', "Show Single Editor Tab"),
original: 'Show Single Editor Tab'
},
category: Categories.View,
precondition: ContextKeyExpr.and(ContextKeyExpr.equals('config.workbench.editor.showTabs', 'single').negate(), InEditorZenModeContext.negate()),
f1: true
});
const precondition = ContextKeyExpr.and(ContextKeyExpr.equals(`config.${LayoutSettings.EDITOR_TABS_MODE}`, EditorTabsMode.SINGLE).negate(), InEditorZenModeContext.negate())!;
const title = { value: localize('showSingleEditorTab', "Show Single Editor Tab"), original: 'Show Single Editor Tab' };

super(LayoutSettings.EDITOR_TABS_MODE, EditorTabsMode.SINGLE, title, ShowSingleEditorTabAction.ID, precondition);
}
}

run(accessor: ServicesAccessor): Promise<void> {
const configurationService = accessor.get(IConfigurationService);
return configurationService.updateValue('workbench.editor.showTabs', 'single');
export class ZenShowSingleEditorTabAction extends AbstractSetShowTabsAction {

static readonly ID = 'workbench.action.zenShowEditorTab';

constructor() {
const precondition = ContextKeyExpr.and(ContextKeyExpr.equals(`config.${ZenModeSettings.SHOW_TABS}`, EditorTabsMode.SINGLE).negate(), InEditorZenModeContext)!;
const title = { value: localize('showSingleEditorTabZenMode', "Show Single Editor Tab in Zen Mode"), original: 'Show Single Editor Tab in Zen Mode' };

super(ZenModeSettings.SHOW_TABS, EditorTabsMode.SINGLE, title, ZenShowSingleEditorTabAction.ID, precondition);
}
}

registerAction2(HideEditorTabsAction);
registerAction2(ZenHideEditorTabsAction);
registerAction2(ShowMultipleEditorTabsAction);
registerAction2(ZenShowMultipleEditorTabsAction);
registerAction2(ShowSingleEditorTabAction);
registerAction2(ZenShowSingleEditorTabAction);

// --- Tab Bar Submenu in View Appearance Menu

Expand All @@ -537,6 +562,14 @@ MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
when: InEditorZenModeContext.negate()
});

MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
submenu: MenuId.EditorTabsBarShowTabsZenModeSubmenu,
title: localize('tabBar', "Tab Bar"),
group: '3_workbench_layout_move',
order: 10,
when: InEditorZenModeContext
});

// --- Show Editor Actions in Title Bar

export class EditorActionsTitleBarAction extends Action2 {
Expand Down
76 changes: 49 additions & 27 deletions src/vs/workbench/browser/layout.ts
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, DisposableMap, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event';
import { EventType, addDisposableListener, getClientArea, position, size, IDimension, isAncestorUsingFlowTo, computeScreenAwareSize, getActiveDocument, getWindows, getActiveWindow, focusWindow, isActiveDocument, getWindow, getWindowId, getActiveElement } from 'vs/base/browser/dom';
import { onDidChangeFullscreen, isFullscreen, isWCOEnabled } from 'vs/base/browser/browser';
Expand All @@ -12,7 +12,7 @@ import { isWindows, isLinux, isMacintosh, isWeb, isNative, isIOS } from 'vs/base
import { EditorInputCapabilities, GroupIdentifier, isResourceEditorInput, IUntypedEditorInput, pathsToEditors } from 'vs/workbench/common/editor';
import { SidebarPart } from 'vs/workbench/browser/parts/sidebar/sidebarPart';
import { PanelPart } from 'vs/workbench/browser/parts/panel/panelPart';
import { Position, Parts, PanelOpensMaximizedOptions, IWorkbenchLayoutService, positionFromString, positionToString, panelOpensMaximizedFromString, PanelAlignment, ActivityBarPosition, LayoutSettings, MULTI_WINDOW_PARTS, SINGLE_WINDOW_PARTS } from 'vs/workbench/services/layout/browser/layoutService';
import { Position, Parts, PanelOpensMaximizedOptions, IWorkbenchLayoutService, positionFromString, positionToString, panelOpensMaximizedFromString, PanelAlignment, ActivityBarPosition, LayoutSettings, MULTI_WINDOW_PARTS, SINGLE_WINDOW_PARTS, ZenModeSettings, EditorTabsMode } from 'vs/workbench/services/layout/browser/layoutService';
import { isTemporaryWorkspace, IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IStorageService, StorageScope, StorageTarget, WillSaveStateReason } from 'vs/platform/storage/common/storage';
import { IConfigurationChangeEvent, IConfigurationService } from 'vs/platform/configuration/common/configuration';
Expand All @@ -21,7 +21,6 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation
import { StartupKind, ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { getTitleBarStyle, getMenuBarVisibility, IPath } from 'vs/platform/window/common/window';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IEditor } from 'vs/editor/common/editorCommon';
import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { EditorGroupLayout, GroupsOrder, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
Expand Down Expand Up @@ -62,7 +61,7 @@ interface ILayoutRuntimeState {
toggled: boolean;
};
readonly zenMode: {
readonly transitionDisposables: DisposableStore;
readonly transitionDisposables: DisposableMap<string, IDisposable>;
};
}

Expand Down Expand Up @@ -637,7 +636,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
toggled: false,
},
zenMode: {
transitionDisposables: new DisposableStore(),
transitionDisposables: new DisposableMap(),
}
};

Expand Down Expand Up @@ -1307,10 +1306,10 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi

toggleZenMode(skipLayout?: boolean, restoring = false): void {
this.stateModel.setRuntimeValue(LayoutStateKeys.ZEN_MODE_ACTIVE, !this.stateModel.getRuntimeValue(LayoutStateKeys.ZEN_MODE_ACTIVE));
this.state.runtime.zenMode.transitionDisposables.clear();
this.state.runtime.zenMode.transitionDisposables.clearAndDisposeAll();

const setLineNumbers = (lineNumbers?: LineNumbersType) => {
const setEditorLineNumbers = (editor: IEditor) => {
for (const editor of this.mainPartEditorService.visibleTextEditorControls) {

// To properly reset line numbers we need to read the configuration for each editor respecting it's uri.
if (!lineNumbers && isCodeEditor(editor) && editor.hasModel()) {
Expand All @@ -1322,16 +1321,6 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
}

editor.updateOptions({ lineNumbers });
};

if (!lineNumbers) {
for (const editorControl of this.mainPartEditorService.visibleTextEditorControls) {
setEditorLineNumbers(editorControl);
}
} else {
for (const editorControl of this.mainPartEditorService.visibleTextEditorControls) {
setEditorLineNumbers(editorControl);
}
}
};

Expand Down Expand Up @@ -1370,28 +1359,62 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi

if (config.hideLineNumbers) {
setLineNumbers('off');
this.state.runtime.zenMode.transitionDisposables.add(this.mainPartEditorService.onDidVisibleEditorsChange(() => setLineNumbers('off')));
this.state.runtime.zenMode.transitionDisposables.set(ZenModeSettings.HIDE_LINENUMBERS, this.mainPartEditorService.onDidVisibleEditorsChange(() => setLineNumbers('off')));
}

if (config.showTabs !== this.editorGroupService.partOptions.showTabs) {
this.state.runtime.zenMode.transitionDisposables.add(this.editorGroupService.mainPart.enforcePartOptions({ showTabs: config.showTabs }));
this.state.runtime.zenMode.transitionDisposables.set(ZenModeSettings.SHOW_TABS, this.editorGroupService.mainPart.enforcePartOptions({ showTabs: config.showTabs }));
}

if (config.silentNotifications && zenModeExitInfo.handleNotificationsDoNotDisturbMode) {
this.notificationService.doNotDisturbMode = true;
}
this.state.runtime.zenMode.transitionDisposables.add(this.configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(WorkbenchLayoutSettings.ZEN_MODE_SILENT_NOTIFICATIONS)) {
const zenModeSilentNotifications = !!this.configurationService.getValue(WorkbenchLayoutSettings.ZEN_MODE_SILENT_NOTIFICATIONS);

if (config.centerLayout) {
this.centerMainEditorLayout(true, true);
}

// Zen Mode Configuration Changes
this.state.runtime.zenMode.transitionDisposables.set('configurationChange', this.configurationService.onDidChangeConfiguration(e => {
// Activity Bar
if (e.affectsConfiguration(ZenModeSettings.HIDE_ACTIVITYBAR)) {
const zenModeHideActivityBar = this.configurationService.getValue<boolean>(ZenModeSettings.HIDE_ACTIVITYBAR);
this.setActivityBarHidden(zenModeHideActivityBar, true);
}

// Status Bar
if (e.affectsConfiguration(ZenModeSettings.HIDE_STATUSBAR)) {
const zenModeHideStatusBar = this.configurationService.getValue<boolean>(ZenModeSettings.HIDE_STATUSBAR);
this.setStatusBarHidden(zenModeHideStatusBar, true);
}

// Center Layout
if (e.affectsConfiguration(ZenModeSettings.CENTER_LAYOUT)) {
const zenModeCenterLayout = this.configurationService.getValue<boolean>(ZenModeSettings.CENTER_LAYOUT);
this.centerMainEditorLayout(zenModeCenterLayout, true);
}

// Show Tabs
if (e.affectsConfiguration(ZenModeSettings.SHOW_TABS)) {
const zenModeShowTabs = this.configurationService.getValue<EditorTabsMode | undefined>(ZenModeSettings.SHOW_TABS) ?? 'multiple';
this.state.runtime.zenMode.transitionDisposables.set(ZenModeSettings.SHOW_TABS, this.editorGroupService.mainPart.enforcePartOptions({ showTabs: zenModeShowTabs }));
}

// Notifications
if (e.affectsConfiguration(ZenModeSettings.SILENT_NOTIFICATIONS)) {
const zenModeSilentNotifications = !!this.configurationService.getValue(ZenModeSettings.SILENT_NOTIFICATIONS);
if (zenModeExitInfo.handleNotificationsDoNotDisturbMode) {
this.notificationService.doNotDisturbMode = zenModeSilentNotifications;
}
}
}));

if (config.centerLayout) {
this.centerMainEditorLayout(true, true);
}
// Center Layout
if (e.affectsConfiguration(ZenModeSettings.HIDE_LINENUMBERS)) {
const lineNumbersType = this.configurationService.getValue<boolean>(ZenModeSettings.HIDE_LINENUMBERS) ? 'off' : undefined;
setLineNumbers(lineNumbersType);
this.state.runtime.zenMode.transitionDisposables.set(ZenModeSettings.HIDE_LINENUMBERS, this.mainPartEditorService.onDidVisibleEditorsChange(() => setLineNumbers(lineNumbersType)));
}
}));
}

// Zen Mode Inactive
Expand Down Expand Up @@ -2540,7 +2563,6 @@ enum WorkbenchLayoutSettings {
PANEL_POSITION = 'workbench.panel.defaultLocation',
PANEL_OPENS_MAXIMIZED = 'workbench.panel.opensMaximized',
ZEN_MODE_CONFIG = 'zenMode',
ZEN_MODE_SILENT_NOTIFICATIONS = 'zenMode.silentNotifications',
EDITOR_CENTERED_LAYOUT_AUTO_RESIZE = 'workbench.editor.centeredLayoutAutoResize',
}

Expand Down