提交 ad104462 编写于 作者: B Benjamin Pasero

debt - fix the madness of context keys in workbench

上级 49e36ee3
...@@ -4,18 +4,6 @@ ...@@ -4,18 +4,6 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { isMacintosh, isLinux, isWindows } from 'vs/base/common/platform';
export const InputFocusedContextKey = 'inputFocus'; export const InputFocusedContextKey = 'inputFocus';
export const InputFocusedContext = new RawContextKey<boolean>(InputFocusedContextKey, false); export const InputFocusedContext = new RawContextKey<boolean>(InputFocusedContextKey, false);
export const IsMacContext = new RawContextKey<boolean>('isMac', isMacintosh);
export const IsLinuxContext = new RawContextKey<boolean>('isLinux', isLinux);
export const IsWindowsContext = new RawContextKey<boolean>('isWindows', isWindows);
export const HasMacNativeTabsContext = new RawContextKey<boolean>('hasMacNativeTabs', false);
export const SupportsWorkspacesContext = new RawContextKey<boolean>('supportsWorkspaces', true);
export const SupportsOpenFileFolderContext = new RawContextKey<boolean>('supportsOpenFileFolder', isMacintosh);
export const IsDevelopmentContext = new RawContextKey<boolean>('isDevelopment', false);
...@@ -19,7 +19,7 @@ import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes'; ...@@ -19,7 +19,7 @@ import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes';
import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { MenuBarVisibility } from 'vs/platform/windows/common/windows'; import { MenuBarVisibility } from 'vs/platform/windows/common/windows';
import { isWindows, isLinux } from 'vs/base/common/platform'; import { isWindows, isLinux } from 'vs/base/common/platform';
import { IsMacContext } from 'vs/platform/contextkey/common/contextkeys'; import { IsMacContext } from 'vs/workbench/common/contextkeys';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { InEditorZenModeContext } from 'vs/workbench/common/editor'; import { InEditorZenModeContext } from 'vs/workbench/common/editor';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { InputFocusedContext } from 'vs/platform/contextkey/common/contextkeys';
import { IWindowConfiguration, IWindowService } from 'vs/platform/windows/common/windows';
import { ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, TEXT_DIFF_EDITOR_ID, SplitEditorsVertically } from 'vs/workbench/common/editor';
import { IsMacContext, IsLinuxContext, IsWindowsContext, HasMacNativeTabsContext, IsDevelopmentContext, SupportsWorkspacesContext, SupportsOpenFileFolderContext, WorkbenchStateContext, WorkspaceFolderCountContext } from 'vs/workbench/common/contextkeys';
import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { EditorGroupsServiceImpl } from 'vs/workbench/browser/parts/editor/editor';
export class WorkbenchContextKeysHandler extends Disposable {
private inputFocusedContext: IContextKey<boolean>;
private activeEditorContext: IContextKey<string>;
private editorsVisibleContext: IContextKey<boolean>;
private textCompareEditorVisibleContext: IContextKey<boolean>;
private textCompareEditorActiveContext: IContextKey<boolean>;
private activeEditorGroupEmpty: IContextKey<boolean>;
private multipleEditorGroupsContext: IContextKey<boolean>;
private workbenchStateContext: IContextKey<string>;
private workspaceFolderCountContext: IContextKey<number>;
private splitEditorsVerticallyContext: IContextKey<boolean>;
constructor(
@IContextKeyService private contextKeyService: IContextKeyService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IConfigurationService private configurationService: IConfigurationService,
@IEnvironmentService private environmentService: IEnvironmentService,
@IWindowService private windowService: IWindowService,
@IEditorService private editorService: IEditorService,
@IEditorGroupsService private editorGroupService: EditorGroupsServiceImpl
) {
super();
this.initContextKeys();
this.registerListeners();
}
private registerListeners(): void {
this.editorGroupService.whenRestored.then(() => this.updateEditorContextKeys());
this._register(this.editorService.onDidActiveEditorChange(() => this.updateEditorContextKeys()));
this._register(this.editorService.onDidVisibleEditorsChange(() => this.updateEditorContextKeys()));
this._register(this.editorGroupService.onDidAddGroup(() => this.updateEditorContextKeys()));
this._register(this.editorGroupService.onDidRemoveGroup(() => this.updateEditorContextKeys()));
this._register(addDisposableListener(window, EventType.FOCUS_IN, () => this.updateInputContextKeys(), true));
this._register(this.contextService.onDidChangeWorkbenchState(() => this.updateWorkbenchStateContextKey()));
this._register(this.contextService.onDidChangeWorkspaceFolders(() => this.updateWorkspaceFolderCountContextKey()));
this._register(this.configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('workbench.editor.openSideBySideDirection')) {
this.updateSplitEditorsVerticallyContext();
}
}));
}
private initContextKeys(): void {
// Platform
IsMacContext.bindTo(this.contextKeyService);
IsLinuxContext.bindTo(this.contextKeyService);
IsWindowsContext.bindTo(this.contextKeyService);
// macOS Native Tabs
const windowConfig = this.configurationService.getValue<IWindowConfiguration>();
HasMacNativeTabsContext.bindTo(this.contextKeyService).set(windowConfig && windowConfig.window && windowConfig.window.nativeTabs);
// Development
IsDevelopmentContext.bindTo(this.contextKeyService).set(!this.environmentService.isBuilt || this.environmentService.isExtensionDevelopment);
// File Pickers
SupportsWorkspacesContext.bindTo(this.contextKeyService);
SupportsOpenFileFolderContext.bindTo(this.contextKeyService).set(!!this.windowService.getConfiguration().remoteAuthority);
// Editors
this.activeEditorContext = ActiveEditorContext.bindTo(this.contextKeyService);
this.editorsVisibleContext = EditorsVisibleContext.bindTo(this.contextKeyService);
this.textCompareEditorVisibleContext = TextCompareEditorVisibleContext.bindTo(this.contextKeyService);
this.textCompareEditorActiveContext = TextCompareEditorActiveContext.bindTo(this.contextKeyService);
this.activeEditorGroupEmpty = ActiveEditorGroupEmptyContext.bindTo(this.contextKeyService);
this.multipleEditorGroupsContext = MultipleEditorGroupsContext.bindTo(this.contextKeyService);
// Inputs
this.inputFocusedContext = InputFocusedContext.bindTo(this.contextKeyService);
// Workbench State
this.workbenchStateContext = WorkbenchStateContext.bindTo(this.contextKeyService);
this.updateWorkbenchStateContextKey();
// Workspace Folder Count
this.workspaceFolderCountContext = WorkspaceFolderCountContext.bindTo(this.contextKeyService);
this.updateWorkspaceFolderCountContextKey();
// Editor Layout
this.splitEditorsVerticallyContext = SplitEditorsVertically.bindTo(this.contextKeyService);
this.updateSplitEditorsVerticallyContext();
}
private updateEditorContextKeys(): void {
const activeControl = this.editorService.activeControl;
const visibleEditors = this.editorService.visibleControls;
this.textCompareEditorActiveContext.set(!!activeControl && activeControl.getId() === TEXT_DIFF_EDITOR_ID);
this.textCompareEditorVisibleContext.set(visibleEditors.some(control => control.getId() === TEXT_DIFF_EDITOR_ID));
if (visibleEditors.length > 0) {
this.editorsVisibleContext.set(true);
} else {
this.editorsVisibleContext.reset();
}
if (!this.editorService.activeEditor) {
this.activeEditorGroupEmpty.set(true);
} else {
this.activeEditorGroupEmpty.reset();
}
if (this.editorGroupService.count > 1) {
this.multipleEditorGroupsContext.set(true);
} else {
this.multipleEditorGroupsContext.reset();
}
if (activeControl) {
this.activeEditorContext.set(activeControl.getId());
} else {
this.activeEditorContext.reset();
}
}
private updateInputContextKeys(): void {
function activeElementIsInput(): boolean {
return !!document.activeElement && (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA');
}
const isInputFocused = activeElementIsInput();
this.inputFocusedContext.set(isInputFocused);
if (isInputFocused) {
const tracker = trackFocus(document.activeElement as HTMLElement);
Event.once(tracker.onDidBlur)(() => {
this.inputFocusedContext.set(activeElementIsInput());
tracker.dispose();
});
}
}
private updateWorkbenchStateContextKey(): void {
this.workbenchStateContext.set(this.getWorkbenchStateString());
}
private updateWorkspaceFolderCountContextKey(): void {
this.workspaceFolderCountContext.set(this.contextService.getWorkspace().folders.length);
}
private updateSplitEditorsVerticallyContext(): void {
const direction = preferredSideBySideGroupDirection(this.configurationService);
this.splitEditorsVerticallyContext.set(direction === GroupDirection.DOWN);
}
private getWorkbenchStateString(): string {
switch (this.contextService.getWorkbenchState()) {
case WorkbenchState.EMPTY: return 'empty';
case WorkbenchState.FOLDER: return 'folder';
case WorkbenchState.WORKSPACE: return 'workspace';
}
}
}
\ No newline at end of file
...@@ -32,14 +32,9 @@ export const TOGGLE_NOTIFICATION = 'notification.toggle'; ...@@ -32,14 +32,9 @@ export const TOGGLE_NOTIFICATION = 'notification.toggle';
export const CLEAR_NOTIFICATION = 'notification.clear'; export const CLEAR_NOTIFICATION = 'notification.clear';
export const CLEAR_ALL_NOTIFICATIONS = 'notifications.clearAll'; export const CLEAR_ALL_NOTIFICATIONS = 'notifications.clearAll';
const notificationFocusedId = 'notificationFocus'; export const NotificationFocusedContext = new RawContextKey<boolean>('notificationFocus', true);
export const NotificationFocusedContext = new RawContextKey<boolean>(notificationFocusedId, true); export const NotificationsCenterVisibleContext = new RawContextKey<boolean>('notificationCenterVisible', false);
export const NotificationsToastsVisibleContext = new RawContextKey<boolean>('notificationToastsVisible', false);
const notificationsCenterVisibleId = 'notificationCenterVisible';
export const NotificationsCenterVisibleContext = new RawContextKey<boolean>(notificationsCenterVisibleId, false);
const notificationsToastsVisibleId = 'notificationToastsVisible';
export const NotificationsToastsVisibleContext = new RawContextKey<boolean>(notificationsToastsVisibleId, false);
export interface INotificationsCenterController { export interface INotificationsCenterController {
readonly isVisible: boolean; readonly isVisible: boolean;
......
...@@ -32,7 +32,7 @@ import Severity from 'vs/base/common/severity'; ...@@ -32,7 +32,7 @@ import Severity from 'vs/base/common/severity';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { ICommandAndKeybindingRule, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { ICommandAndKeybindingRule, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { inQuickOpenContext } from 'vs/workbench/browser/parts/quickopen/quickopen'; import { inQuickOpenContext, InQuickOpenContextKey } from 'vs/workbench/browser/parts/quickopen/quickopen';
import { ActionBar, ActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { ActionBar, ActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action } from 'vs/base/common/actions'; import { Action } from 'vs/base/common/actions';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
...@@ -836,7 +836,7 @@ export class QuickInputService extends Component implements IQuickInputService { ...@@ -836,7 +836,7 @@ export class QuickInputService extends Component implements IQuickInputService {
@IAccessibilityService private readonly accessibilityService: IAccessibilityService @IAccessibilityService private readonly accessibilityService: IAccessibilityService
) { ) {
super(QuickInputService.ID, themeService, storageService); super(QuickInputService.ID, themeService, storageService);
this.inQuickOpenContext = new RawContextKey<boolean>('inQuickOpen', false).bindTo(contextKeyService); this.inQuickOpenContext = InQuickOpenContextKey.bindTo(contextKeyService);
this._register(this.quickOpenService.onShow(() => this.inQuickOpen('quickOpen', true))); this._register(this.quickOpenService.onShow(() => this.inQuickOpen('quickOpen', true)));
this._register(this.quickOpenService.onHide(() => this.inQuickOpen('quickOpen', false))); this._register(this.quickOpenService.onHide(() => this.inQuickOpen('quickOpen', false)));
this.registerKeyModsListeners(); this.registerKeyModsListeners();
......
...@@ -8,11 +8,13 @@ import { Action } from 'vs/base/common/actions'; ...@@ -8,11 +8,13 @@ import { Action } from 'vs/base/common/actions';
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands'; import { ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
export const inQuickOpenContext = ContextKeyExpr.has('inQuickOpen'); const inQuickOpenKey = 'inQuickOpen';
export const InQuickOpenContextKey = new RawContextKey<boolean>(inQuickOpenKey, false);
export const inQuickOpenContext = ContextKeyExpr.has(inQuickOpenKey);
export const defaultQuickOpenContextKey = 'inFilesPicker'; export const defaultQuickOpenContextKey = 'inFilesPicker';
export const defaultQuickOpenContext = ContextKeyExpr.and(inQuickOpenContext, ContextKeyExpr.has(defaultQuickOpenContextKey)); export const defaultQuickOpenContext = ContextKeyExpr.and(inQuickOpenContext, ContextKeyExpr.has(defaultQuickOpenContextKey));
......
...@@ -33,6 +33,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten ...@@ -33,6 +33,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
import { ISerializableView } from 'vs/base/browser/ui/grid/grid'; import { ISerializableView } from 'vs/base/browser/ui/grid/grid';
import { LayoutPriority } from 'vs/base/browser/ui/grid/gridview'; import { LayoutPriority } from 'vs/base/browser/ui/grid/gridview';
export const SidebarVisibleContext = new RawContextKey<boolean>('sidebarVisible', false);
export const SidebarFocusContext = new RawContextKey<boolean>('sideBarFocus', false); export const SidebarFocusContext = new RawContextKey<boolean>('sideBarFocus', false);
export const ActiveViewletContext = new RawContextKey<string>('activeViewlet', ''); export const ActiveViewletContext = new RawContextKey<string>('activeViewlet', '');
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { isMacintosh, isLinux, isWindows } from 'vs/base/common/platform';
export const IsMacContext = new RawContextKey<boolean>('isMac', isMacintosh);
export const IsLinuxContext = new RawContextKey<boolean>('isLinux', isLinux);
export const IsWindowsContext = new RawContextKey<boolean>('isWindows', isWindows);
export const HasMacNativeTabsContext = new RawContextKey<boolean>('hasMacNativeTabs', false);
export const SupportsWorkspacesContext = new RawContextKey<boolean>('supportsWorkspaces', true);
export const SupportsOpenFileFolderContext = new RawContextKey<boolean>('supportsOpenFileFolder', isMacintosh);
export const IsDevelopmentContext = new RawContextKey<boolean>('isDevelopment', false);
export const WorkbenchStateContext = new RawContextKey<string>('workbenchState', undefined);
export const WorkspaceFolderCountContext = new RawContextKey<number>('workspaceFolderCount', 0);
\ No newline at end of file
...@@ -23,7 +23,7 @@ import { ResourceContextKey } from 'vs/workbench/common/resources'; ...@@ -23,7 +23,7 @@ import { ResourceContextKey } from 'vs/workbench/common/resources';
import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService'; import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { Schemas } from 'vs/base/common/network'; import { Schemas } from 'vs/base/common/network';
import { SupportsWorkspacesContext } from 'vs/platform/contextkey/common/contextkeys'; import { SupportsWorkspacesContext } from 'vs/workbench/common/contextkeys';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
// Contribute Global Actions // Contribute Global Actions
......
...@@ -12,7 +12,8 @@ import { Context as SuggestContext } from 'vs/editor/contrib/suggest/suggest'; ...@@ -12,7 +12,8 @@ import { Context as SuggestContext } from 'vs/editor/contrib/suggest/suggest';
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
import { MenuId, MenuRegistry, SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { MenuId, MenuRegistry, SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { WorkbenchStateContext } from 'vs/workbench/common/contextkeys';
import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
...@@ -423,7 +424,7 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon ...@@ -423,7 +424,7 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon
dark: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/electron-browser/media/preferences-editor-inverse.svg`)) dark: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/electron-browser/media/preferences-editor-inverse.svg`))
} }
}, },
when: ContextKeyExpr.and(ResourceContextKey.Resource.isEqualTo(this.preferencesService.workspaceSettingsResource.toString()), new RawContextKey<string>('workbenchState', '').isEqualTo('workspace')), when: ContextKeyExpr.and(ResourceContextKey.Resource.isEqualTo(this.preferencesService.workspaceSettingsResource.toString()), WorkbenchStateContext.isEqualTo('workspace')),
group: 'navigation', group: 'navigation',
order: 1 order: 1
}); });
...@@ -478,7 +479,7 @@ MenuRegistry.appendMenuItem(MenuId.CommandPalette, { ...@@ -478,7 +479,7 @@ MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
title: { value: `${category}: ${OpenFolderSettingsAction.LABEL}`, original: 'Preferences: Open Folder Settings' }, title: { value: `${category}: ${OpenFolderSettingsAction.LABEL}`, original: 'Preferences: Open Folder Settings' },
category: nls.localize('preferencesCategory', "Prefernces") category: nls.localize('preferencesCategory', "Prefernces")
}, },
when: new RawContextKey<string>('workbenchState', '').isEqualTo('workspace') when: WorkbenchStateContext.isEqualTo('workspace')
}); });
CommandsRegistry.registerCommand(OpenWorkspaceSettingsAction.ID, serviceAccessor => { CommandsRegistry.registerCommand(OpenWorkspaceSettingsAction.ID, serviceAccessor => {
...@@ -490,7 +491,7 @@ MenuRegistry.appendMenuItem(MenuId.CommandPalette, { ...@@ -490,7 +491,7 @@ MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
title: { value: `${category}: ${OpenWorkspaceSettingsAction.LABEL}`, original: 'Preferences: Open Workspace Settings' }, title: { value: `${category}: ${OpenWorkspaceSettingsAction.LABEL}`, original: 'Preferences: Open Workspace Settings' },
category: nls.localize('preferencesCategory', "Prefernces") category: nls.localize('preferencesCategory', "Prefernces")
}, },
when: new RawContextKey<string>('workbenchState', '').notEqualsTo('empty') when: WorkbenchStateContext.notEqualsTo('empty')
}); });
KeybindingsRegistry.registerCommandAndKeybindingRule({ KeybindingsRegistry.registerCommandAndKeybindingRule({
......
...@@ -15,13 +15,13 @@ import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductor ...@@ -15,13 +15,13 @@ import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductor
import { ToggleSharedProcessAction, InspectContextKeysAction, ToggleScreencastModeAction, ToggleDevToolsAction } from 'vs/workbench/electron-browser/actions/developerActions'; import { ToggleSharedProcessAction, InspectContextKeysAction, ToggleScreencastModeAction, ToggleDevToolsAction } from 'vs/workbench/electron-browser/actions/developerActions';
import { ShowAboutDialogAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, OpenRecentAction, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ReloadWindowAction, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions'; import { ShowAboutDialogAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, OpenRecentAction, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ReloadWindowAction, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions';
import { AddRootFolderAction, GlobalRemoveRootFolderAction, OpenWorkspaceAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, OpenFileFolderAction, OpenFileAction, OpenFolderAction, CloseWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions'; import { AddRootFolderAction, GlobalRemoveRootFolderAction, OpenWorkspaceAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, OpenFileFolderAction, OpenFileAction, OpenFolderAction, CloseWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions';
import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { inQuickOpenContext, getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/quickopen'; import { inQuickOpenContext, getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/quickopen';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ADD_ROOT_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands'; import { ADD_ROOT_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands';
import { SupportsWorkspacesContext, IsMacContext, HasMacNativeTabsContext, IsDevelopmentContext } from 'vs/platform/contextkey/common/contextkeys'; import { SupportsWorkspacesContext, IsMacContext, HasMacNativeTabsContext, IsDevelopmentContext, WorkbenchStateContext, WorkspaceFolderCountContext } from 'vs/workbench/common/contextkeys';
import { NoEditorsVisibleContext, SingleEditorGroupsContext } from 'vs/workbench/common/editor'; import { NoEditorsVisibleContext, SingleEditorGroupsContext } from 'vs/workbench/common/editor';
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
import { LogStorageAction } from 'vs/platform/storage/node/storageService'; import { LogStorageAction } from 'vs/platform/storage/node/storageService';
...@@ -128,7 +128,7 @@ import { LogStorageAction } from 'vs/platform/storage/node/storageService'; ...@@ -128,7 +128,7 @@ import { LogStorageAction } from 'vs/platform/storage/node/storageService';
id: OpenWorkspaceConfigFileAction.ID, id: OpenWorkspaceConfigFileAction.ID,
title: { value: `${workspacesCategory}: ${OpenWorkspaceConfigFileAction.LABEL}`, original: 'Workspaces: Open Workspace Configuration File' }, title: { value: `${workspacesCategory}: ${OpenWorkspaceConfigFileAction.LABEL}`, original: 'Workspaces: Open Workspace Configuration File' },
}, },
when: new RawContextKey<string>('workbenchState', '').isEqualTo('workspace') when: WorkbenchStateContext.isEqualTo('workspace')
}); });
})(); })();
...@@ -308,10 +308,10 @@ import { LogStorageAction } from 'vs/platform/storage/node/storageService'; ...@@ -308,10 +308,10 @@ import { LogStorageAction } from 'vs/platform/storage/node/storageService';
command: { command: {
id: CloseWorkspaceAction.ID, id: CloseWorkspaceAction.ID,
title: nls.localize({ key: 'miCloseFolder', comment: ['&& denotes a mnemonic'] }, "Close &&Folder"), title: nls.localize({ key: 'miCloseFolder', comment: ['&& denotes a mnemonic'] }, "Close &&Folder"),
precondition: new RawContextKey<number>('workspaceFolderCount', 0).notEqualsTo('0') precondition: WorkspaceFolderCountContext.notEqualsTo('0')
}, },
order: 3, order: 3,
when: new RawContextKey<string>('workbenchState', '').notEqualsTo('workspace') when: WorkbenchStateContext.notEqualsTo('workspace')
}); });
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
...@@ -321,7 +321,7 @@ import { LogStorageAction } from 'vs/platform/storage/node/storageService'; ...@@ -321,7 +321,7 @@ import { LogStorageAction } from 'vs/platform/storage/node/storageService';
title: nls.localize({ key: 'miCloseWorkspace', comment: ['&& denotes a mnemonic'] }, "Close &&Workspace") title: nls.localize({ key: 'miCloseWorkspace', comment: ['&& denotes a mnemonic'] }, "Close &&Workspace")
}, },
order: 3, order: 3,
when: new RawContextKey<string>('workbenchState', '').isEqualTo('workspace') when: WorkbenchStateContext.isEqualTo('workspace')
}); });
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
......
...@@ -5,14 +5,12 @@ ...@@ -5,14 +5,12 @@
import * as fs from 'fs'; import * as fs from 'fs';
import { createHash } from 'crypto'; import { createHash } from 'crypto';
import * as nls from 'vs/nls';
import * as perf from 'vs/base/common/performance'; import * as perf from 'vs/base/common/performance';
import { Workbench } from 'vs/workbench/electron-browser/workbench'; import { Workbench } from 'vs/workbench/electron-browser/workbench';
import { ElectronWindow } from 'vs/workbench/electron-browser/window'; import { ElectronWindow } from 'vs/workbench/electron-browser/window';
import * as browser from 'vs/base/browser/browser'; import * as browser from 'vs/base/browser/browser';
import { domContentLoaded } from 'vs/base/browser/dom'; import { domContentLoaded, addDisposableListener, EventType, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { onUnexpectedError } from 'vs/base/common/errors'; import { onUnexpectedError } from 'vs/base/common/errors';
import * as comparer from 'vs/base/common/comparers';
import * as platform from 'vs/base/common/platform'; import * as platform from 'vs/base/common/platform';
import { URI as uri } from 'vs/base/common/uri'; import { URI as uri } from 'vs/base/common/uri';
import { WorkspaceService } from 'vs/workbench/services/configuration/node/configurationService'; import { WorkspaceService } from 'vs/workbench/services/configuration/node/configurationService';
...@@ -45,8 +43,6 @@ import { IMenubarService } from 'vs/platform/menubar/common/menubar'; ...@@ -45,8 +43,6 @@ import { IMenubarService } from 'vs/platform/menubar/common/menubar';
import { Schemas } from 'vs/base/common/network'; import { Schemas } from 'vs/base/common/network';
import { sanitizeFilePath } from 'vs/base/node/extfs'; import { sanitizeFilePath } from 'vs/base/node/extfs';
import { basename } from 'vs/base/common/path'; import { basename } from 'vs/base/common/path';
import { IdleValue } from 'vs/base/common/async';
import { setGlobalLeakWarningThreshold } from 'vs/base/common/event';
import { GlobalStorageDatabaseChannelClient } from 'vs/platform/storage/node/storageIpc'; import { GlobalStorageDatabaseChannelClient } from 'vs/platform/storage/node/storageIpc';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
...@@ -57,6 +53,8 @@ import { registerWindowDriver } from 'vs/platform/driver/electron-browser/driver ...@@ -57,6 +53,8 @@ import { registerWindowDriver } from 'vs/platform/driver/electron-browser/driver
export class CodeWindow extends Disposable { export class CodeWindow extends Disposable {
private workbench: Workbench;
constructor(private readonly configuration: IWindowConfiguration) { constructor(private readonly configuration: IWindowConfiguration) {
super(); super();
...@@ -74,9 +72,6 @@ export class CodeWindow extends Disposable { ...@@ -74,9 +72,6 @@ export class CodeWindow extends Disposable {
// Setup perf // Setup perf
perf.importEntries(this.configuration.perfEntries); perf.importEntries(this.configuration.perfEntries);
// Configure emitter leak warning threshold
setGlobalLeakWarningThreshold(175);
// Browser config // Browser config
browser.setZoomFactor(webFrame.getZoomFactor()); // Ensure others can listen to zoom level changes browser.setZoomFactor(webFrame.getZoomFactor()); // Ensure others can listen to zoom level changes
browser.setZoomLevel(webFrame.getZoomLevel(), true /* isTrusted */); // Can be trusted because we are not setting it ourselves (https://github.com/Microsoft/vscode/issues/26151) browser.setZoomLevel(webFrame.getZoomLevel(), true /* isTrusted */); // Can be trusted because we are not setting it ourselves (https://github.com/Microsoft/vscode/issues/26151)
...@@ -84,24 +79,6 @@ export class CodeWindow extends Disposable { ...@@ -84,24 +79,6 @@ export class CodeWindow extends Disposable {
// Keyboard support // Keyboard support
KeyboardMapperFactory.INSTANCE._onKeyboardLayoutChanged(); KeyboardMapperFactory.INSTANCE._onKeyboardLayoutChanged();
// Setup Intl for comparers
comparer.setFileNameComparer(new IdleValue(() => {
const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' });
return {
collator: collator,
collatorIsNumeric: collator.resolvedOptions().numeric
};
}));
// Inform user about loading issues from the loader
(<any>self).require.config({
onError: err => {
if (err.errorCode === 'load') {
onUnexpectedError(new Error(nls.localize('loaderErrorNative', "Failed to load a required file. Please restart the application to try again. Details: {0}", JSON.stringify(err))));
}
}
});
} }
private reviveUris() { private reviveUris() {
...@@ -135,19 +112,22 @@ export class CodeWindow extends Disposable { ...@@ -135,19 +112,22 @@ export class CodeWindow extends Disposable {
const instantiationService = new InstantiationService(services, true); const instantiationService = new InstantiationService(services, true);
// Create Workbench // Create Workbench
const workbench: Workbench = instantiationService.createInstance( this.workbench = instantiationService.createInstance(
Workbench, Workbench,
document.body, document.body,
this.configuration, this.configuration,
services services
); );
// Layout
this._register(addDisposableListener(window, EventType.RESIZE, e => this.onWindowResize(e, true)));
// Workbench Lifecycle // Workbench Lifecycle
this._register(workbench.onShutdown(() => this.dispose())); this._register(this.workbench.onShutdown(() => this.dispose()));
this._register(workbench.onWillShutdown(event => event.join((services.get(IStorageService) as StorageService).close()))); this._register(this.workbench.onWillShutdown(event => event.join((services.get(IStorageService) as StorageService).close())));
// Startup // Startup
workbench.startup(); this.workbench.startup();
// Window // Window
this._register(instantiationService.createInstance(ElectronWindow)); this._register(instantiationService.createInstance(ElectronWindow));
...@@ -160,6 +140,24 @@ export class CodeWindow extends Disposable { ...@@ -160,6 +140,24 @@ export class CodeWindow extends Disposable {
}); });
} }
private onWindowResize(e: any, retry: boolean): void {
if (e.target === window) {
if (window.document && window.document.body && window.document.body.clientWidth === 0) {
// TODO@Ben this is an electron issue on macOS when simple fullscreen is enabled
// where for some reason the window clientWidth is reported as 0 when switching
// between simple fullscreen and normal screen. In that case we schedule the layout
// call at the next animation frame once, in the hope that the dimensions are
// proper then.
if (retry) {
scheduleAtNextAnimationFrame(() => this.onWindowResize(e, false));
}
return;
}
this.workbench.layout();
}
}
private initServices(electronMainClient: ElectronIPCClient): Promise<ServiceCollection> { private initServices(electronMainClient: ElectronIPCClient): Promise<ServiceCollection> {
const serviceCollection = new ServiceCollection(); const serviceCollection = new ServiceCollection();
......
...@@ -5,10 +5,12 @@ ...@@ -5,10 +5,12 @@
import 'vs/workbench/browser/style'; import 'vs/workbench/browser/style';
import { localize } from 'vs/nls';
import { setFileNameComparer } from 'vs/base/common/comparers';
import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter, setGlobalLeakWarningThreshold } from 'vs/base/common/event';
import { EventType, addDisposableListener, addClasses, scheduleAtNextAnimationFrame, addClass, removeClass, trackFocus, isAncestor, getClientArea, position, size, removeClasses } from 'vs/base/browser/dom'; import { EventType, addDisposableListener, addClasses, addClass, removeClass, isAncestor, getClientArea, position, size, removeClasses } from 'vs/base/browser/dom';
import { RunOnceScheduler, runWhenIdle } from 'vs/base/common/async'; import { RunOnceScheduler, runWhenIdle, IdleValue } from 'vs/base/common/async';
import { getZoomLevel, onDidChangeFullscreen, isFullscreen, getZoomFactor } from 'vs/base/browser/browser'; import { getZoomLevel, onDidChangeFullscreen, isFullscreen, getZoomFactor } from 'vs/base/browser/browser';
import { mark } from 'vs/base/common/performance'; import { mark } from 'vs/base/common/performance';
import { onUnexpectedError, setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { onUnexpectedError, setUnexpectedErrorHandler } from 'vs/base/common/errors';
...@@ -17,9 +19,9 @@ import { Registry } from 'vs/platform/registry/common/platform'; ...@@ -17,9 +19,9 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { isWindows, isLinux, isMacintosh, language } from 'vs/base/common/platform'; import { isWindows, isLinux, isMacintosh, language } from 'vs/base/common/platform';
import { IResourceInput } from 'vs/platform/editor/common/editor'; import { IResourceInput } from 'vs/platform/editor/common/editor';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { IEditorInputFactoryRegistry, Extensions as EditorExtensions, TextCompareEditorVisibleContext, TEXT_DIFF_EDITOR_ID, EditorsVisibleContext, InEditorZenModeContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, IUntitledResourceInput, IResourceDiffInput, SplitEditorsVertically, TextCompareEditorActiveContext, ActiveEditorContext } from 'vs/workbench/common/editor'; import { IEditorInputFactoryRegistry, Extensions as EditorExtensions, IUntitledResourceInput, IResourceDiffInput, InEditorZenModeContext } from 'vs/workbench/common/editor';
import { ActivitybarPart } from 'vs/workbench/browser/parts/activitybar/activitybarPart'; import { ActivitybarPart } from 'vs/workbench/browser/parts/activitybar/activitybarPart';
import { SidebarPart } from 'vs/workbench/browser/parts/sidebar/sidebarPart'; import { SidebarPart, SidebarVisibleContext } from 'vs/workbench/browser/parts/sidebar/sidebarPart';
import { PanelPart } from 'vs/workbench/browser/parts/panel/panelPart'; import { PanelPart } from 'vs/workbench/browser/parts/panel/panelPart';
import { StatusbarPart } from 'vs/workbench/browser/parts/statusbar/statusbarPart'; import { StatusbarPart } from 'vs/workbench/browser/parts/statusbar/statusbarPart';
import { TitlebarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart'; import { TitlebarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart';
...@@ -39,7 +41,7 @@ import { IJSONEditingService } from 'vs/workbench/services/configuration/common/ ...@@ -39,7 +41,7 @@ import { IJSONEditingService } from 'vs/workbench/services/configuration/common/
import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService'; import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IKeybindingEditingService, KeybindingsEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing'; import { IKeybindingEditingService, KeybindingsEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing';
import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IActivityService } from 'vs/workbench/services/activity/common/activity'; import { IActivityService } from 'vs/workbench/services/activity/common/activity';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IFileService } from 'vs/platform/files/common/files'; import { IFileService } from 'vs/platform/files/common/files';
...@@ -71,7 +73,6 @@ import { IDecorationsService } from 'vs/workbench/services/decorations/browser/d ...@@ -71,7 +73,6 @@ import { IDecorationsService } from 'vs/workbench/services/decorations/browser/d
import { ActivityService } from 'vs/workbench/services/activity/browser/activityService'; import { ActivityService } from 'vs/workbench/services/activity/browser/activityService';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { IListService, ListService } from 'vs/platform/list/browser/listService'; import { IListService, ListService } from 'vs/platform/list/browser/listService';
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, SupportsOpenFileFolderContext, SupportsWorkspacesContext, IsDevelopmentContext, HasMacNativeTabsContext } from 'vs/platform/contextkey/common/contextkeys';
import { IViewsService } from 'vs/workbench/common/views'; import { IViewsService } from 'vs/workbench/common/views';
import { ViewsService } from 'vs/workbench/browser/parts/views/views'; import { ViewsService } from 'vs/workbench/browser/parts/views/views';
import { INotificationService } from 'vs/platform/notification/common/notification'; import { INotificationService } from 'vs/platform/notification/common/notification';
...@@ -84,7 +85,7 @@ import { NotificationsToasts } from 'vs/workbench/browser/parts/notifications/no ...@@ -84,7 +85,7 @@ import { NotificationsToasts } from 'vs/workbench/browser/parts/notifications/no
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
import { PreferencesService } from 'vs/workbench/services/preferences/browser/preferencesService'; import { PreferencesService } from 'vs/workbench/services/preferences/browser/preferencesService';
import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService, GroupDirection, preferredSideBySideGroupDirection } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { EditorService } from 'vs/workbench/services/editor/browser/editorService'; import { EditorService } from 'vs/workbench/services/editor/browser/editorService';
import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'; import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
...@@ -138,6 +139,7 @@ import { WorkbenchThemeService } from 'vs/workbench/services/themes/browser/work ...@@ -138,6 +139,7 @@ import { WorkbenchThemeService } from 'vs/workbench/services/themes/browser/work
import { IProductService } from 'vs/platform/product/common/product'; import { IProductService } from 'vs/platform/product/common/product';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { ITextMateService } from 'vs/workbench/services/textMate/common/textMateService'; import { ITextMateService } from 'vs/workbench/services/textMate/common/textMateService';
import { WorkbenchContextKeysHandler } from 'vs/workbench/browser/contextkeys';
// import@node // import@node
import { BackupFileService, InMemoryBackupFileService } from 'vs/workbench/services/backup/node/backupFileService'; import { BackupFileService, InMemoryBackupFileService } from 'vs/workbench/services/backup/node/backupFileService';
...@@ -212,14 +214,6 @@ const Identifiers = { ...@@ -212,14 +214,6 @@ const Identifiers = {
STATUSBAR_PART: 'workbench.parts.statusbar' STATUSBAR_PART: 'workbench.parts.statusbar'
}; };
function getWorkbenchStateString(state: WorkbenchState): string {
switch (state) {
case WorkbenchState.EMPTY: return 'empty';
case WorkbenchState.FOLDER: return 'folder';
case WorkbenchState.WORKSPACE: return 'workspace';
}
}
interface IZenMode { interface IZenMode {
active: boolean; active: boolean;
transitionedToFullScreen: boolean; transitionedToFullScreen: boolean;
...@@ -319,7 +313,7 @@ export class Workbench extends Disposable implements IPartService { ...@@ -319,7 +313,7 @@ export class Workbench extends Disposable implements IPartService {
lastSidebarDimension: 300, lastSidebarDimension: 300,
}; };
private inZenMode: IContextKey<boolean>; private inZenModeContext: IContextKey<boolean>;
private sideBarVisibleContext: IContextKey<boolean>; private sideBarVisibleContext: IContextKey<boolean>;
private closeEmptyWindowScheduler: RunOnceScheduler = this._register(new RunOnceScheduler(() => this.onAllEditorsClosed(), 50)); private closeEmptyWindowScheduler: RunOnceScheduler = this._register(new RunOnceScheduler(() => this.onAllEditorsClosed(), 50));
...@@ -360,6 +354,15 @@ export class Workbench extends Disposable implements IPartService { ...@@ -360,6 +354,15 @@ export class Workbench extends Disposable implements IPartService {
// Install handler for unexpected errors // Install handler for unexpected errors
setUnexpectedErrorHandler(error => this.handleUnexpectedError(error)); setUnexpectedErrorHandler(error => this.handleUnexpectedError(error));
// Inform user about loading issues from the loader
(<any>self).require.config({
onError: err => {
if (err.errorCode === 'load') {
onUnexpectedError(new Error(localize('loaderErrorNative', "Failed to load a required file. Please restart the application to try again. Details: {0}", JSON.stringify(err))));
}
}
});
} }
private handleUnexpectedError(error: any): void { private handleUnexpectedError(error: any): void {
...@@ -401,6 +404,18 @@ export class Workbench extends Disposable implements IPartService { ...@@ -401,6 +404,18 @@ export class Workbench extends Disposable implements IPartService {
// Logging // Logging
this.logService.trace('workbench configuration', JSON.stringify(this.configuration)); this.logService.trace('workbench configuration', JSON.stringify(this.configuration));
// Configure emitter leak warning threshold
setGlobalLeakWarningThreshold(175);
// Setup Intl for comparers
setFileNameComparer(new IdleValue(() => {
const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' });
return {
collator: collator,
collatorIsNumeric: collator.resolvedOptions().numeric
};
}));
// ARIA // ARIA
setARIAContainer(document.body); setARIAContainer(document.body);
...@@ -418,7 +433,9 @@ export class Workbench extends Disposable implements IPartService { ...@@ -418,7 +433,9 @@ export class Workbench extends Disposable implements IPartService {
this.initServices(this.serviceCollection); this.initServices(this.serviceCollection);
// Context Keys // Context Keys
this.handleContextKeys(); this._register(this.instantiationService.createInstance(WorkbenchContextKeysHandler));
this.inZenModeContext = InEditorZenModeContext.bindTo(this.contextKeyService);
this.sideBarVisibleContext = SidebarVisibleContext.bindTo(this.contextKeyService);
// Register Listeners // Register Listeners
this.registerListeners(); this.registerListeners();
...@@ -440,9 +457,7 @@ export class Workbench extends Disposable implements IPartService { ...@@ -440,9 +457,7 @@ export class Workbench extends Disposable implements IPartService {
this.logService.warn('Workbench did not finish loading in 10 seconds, that might be a problem that should be reported.'); this.logService.warn('Workbench did not finish loading in 10 seconds, that might be a problem that should be reported.');
}, 10000); }, 10000);
this.lifecycleService.when(LifecyclePhase.Restored).then(() => { this.lifecycleService.when(LifecyclePhase.Restored).then(() => clearTimeout(timeoutHandle));
clearTimeout(timeoutHandle);
});
// Restore Parts // Restore Parts
return this.restoreParts(); return this.restoreParts();
...@@ -787,31 +802,8 @@ export class Workbench extends Disposable implements IPartService { ...@@ -787,31 +802,8 @@ export class Workbench extends Disposable implements IPartService {
this._register(this.editorGroupService.onDidAddGroup(() => this.centerEditorLayout(this.shouldCenterLayout))); this._register(this.editorGroupService.onDidAddGroup(() => this.centerEditorLayout(this.shouldCenterLayout)));
this._register(this.editorGroupService.onDidRemoveGroup(() => this.centerEditorLayout(this.shouldCenterLayout))); this._register(this.editorGroupService.onDidRemoveGroup(() => this.centerEditorLayout(this.shouldCenterLayout)));
// Layout
this._register(addDisposableListener(window, EventType.RESIZE, e => this.onWindowResize(e, true)));
// Prevent workbench from scrolling #55456 // Prevent workbench from scrolling #55456
this._register(addDisposableListener(this.workbench, EventType.SCROLL, () => { this._register(addDisposableListener(this.workbench, EventType.SCROLL, () => this.workbench.scrollTop = 0));
this.workbench.scrollTop = 0;
}));
}
private onWindowResize(e: any, retry: boolean): void {
if (e.target === window) {
if (window.document && window.document.body && window.document.body.clientWidth === 0) {
// TODO@Ben this is an electron issue on macOS when simple fullscreen is enabled
// where for some reason the window clientWidth is reported as 0 when switching
// between simple fullscreen and normal screen. In that case we schedule the layout
// call at the next animation frame once, in the hope that the dimensions are
// proper then.
if (retry) {
scheduleAtNextAnimationFrame(() => this.onWindowResize(e, false));
}
return;
}
this.layout();
}
} }
private onFullscreenChanged(): void { private onFullscreenChanged(): void {
...@@ -913,119 +905,6 @@ export class Workbench extends Disposable implements IPartService { ...@@ -913,119 +905,6 @@ export class Workbench extends Disposable implements IPartService {
//#endregion //#endregion
private handleContextKeys(): void {
IsMacContext.bindTo(this.contextKeyService);
IsLinuxContext.bindTo(this.contextKeyService);
IsWindowsContext.bindTo(this.contextKeyService);
const windowConfig = this.configurationService.getValue<IWindowConfiguration>();
HasMacNativeTabsContext.bindTo(this.contextKeyService).set(windowConfig && windowConfig.window && windowConfig.window.nativeTabs);
IsDevelopmentContext.bindTo(this.contextKeyService).set(!this.environmentService.isBuilt || this.environmentService.isExtensionDevelopment);
SupportsWorkspacesContext.bindTo(this.contextKeyService);
SupportsOpenFileFolderContext.bindTo(this.contextKeyService).set(!!this.windowService.getConfiguration().remoteAuthority);
this.inZenMode = InEditorZenModeContext.bindTo(this.contextKeyService);
const sidebarVisibleContextRaw = new RawContextKey<boolean>('sidebarVisible', false);
this.sideBarVisibleContext = sidebarVisibleContextRaw.bindTo(this.contextKeyService);
const activeEditorContext = ActiveEditorContext.bindTo(this.contextKeyService);
const editorsVisibleContext = EditorsVisibleContext.bindTo(this.contextKeyService);
const textCompareEditorVisible = TextCompareEditorVisibleContext.bindTo(this.contextKeyService);
const textCompareEditorActive = TextCompareEditorActiveContext.bindTo(this.contextKeyService);
const activeEditorGroupEmpty = ActiveEditorGroupEmptyContext.bindTo(this.contextKeyService);
const multipleEditorGroups = MultipleEditorGroupsContext.bindTo(this.contextKeyService);
const updateEditorContextKeys = () => {
const activeControl = this.editorService.activeControl;
const visibleEditors = this.editorService.visibleControls;
textCompareEditorActive.set(!!activeControl && activeControl.getId() === TEXT_DIFF_EDITOR_ID);
textCompareEditorVisible.set(visibleEditors.some(control => control.getId() === TEXT_DIFF_EDITOR_ID));
if (visibleEditors.length > 0) {
editorsVisibleContext.set(true);
} else {
editorsVisibleContext.reset();
}
if (!this.editorService.activeEditor) {
activeEditorGroupEmpty.set(true);
} else {
activeEditorGroupEmpty.reset();
}
if (this.editorGroupService.count > 1) {
multipleEditorGroups.set(true);
} else {
multipleEditorGroups.reset();
}
if (activeControl) {
activeEditorContext.set(activeControl.getId());
} else {
activeEditorContext.reset();
}
};
this.editorPart.whenRestored.then(() => updateEditorContextKeys());
this._register(this.editorService.onDidActiveEditorChange(() => updateEditorContextKeys()));
this._register(this.editorService.onDidVisibleEditorsChange(() => updateEditorContextKeys()));
this._register(this.editorGroupService.onDidAddGroup(() => updateEditorContextKeys()));
this._register(this.editorGroupService.onDidRemoveGroup(() => updateEditorContextKeys()));
const inputFocused = InputFocusedContext.bindTo(this.contextKeyService);
function activeElementIsInput(): boolean {
return !!document.activeElement && (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA');
}
function trackInputFocus(): void {
const isInputFocused = activeElementIsInput();
inputFocused.set(isInputFocused);
if (isInputFocused) {
const tracker = trackFocus(document.activeElement as HTMLElement);
Event.once(tracker.onDidBlur)(() => {
inputFocused.set(activeElementIsInput());
tracker.dispose();
});
}
}
this._register(addDisposableListener(window, 'focusin', () => trackInputFocus(), true));
const workbenchStateRawContext = new RawContextKey<string>('workbenchState', getWorkbenchStateString(this.configurationService.getWorkbenchState()));
const workbenchStateContext = workbenchStateRawContext.bindTo(this.contextKeyService);
this._register(this.configurationService.onDidChangeWorkbenchState(() => {
workbenchStateContext.set(getWorkbenchStateString(this.configurationService.getWorkbenchState()));
}));
const workspaceFolderCountRawContext = new RawContextKey<number>('workspaceFolderCount', this.configurationService.getWorkspace().folders.length);
const workspaceFolderCountContext = workspaceFolderCountRawContext.bindTo(this.contextKeyService);
this._register(this.configurationService.onDidChangeWorkspaceFolders(() => {
workspaceFolderCountContext.set(this.configurationService.getWorkspace().folders.length);
}));
const splitEditorsVerticallyContext = SplitEditorsVertically.bindTo(this.contextKeyService);
const updateSplitEditorsVerticallyContext = () => {
const direction = preferredSideBySideGroupDirection(this.configurationService);
splitEditorsVerticallyContext.set(direction === GroupDirection.DOWN);
};
this._register(this.configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('workbench.editor.openSideBySideDirection')) {
updateSplitEditorsVerticallyContext();
}
}));
updateSplitEditorsVerticallyContext();
}
private restoreParts(): Promise<void> { private restoreParts(): Promise<void> {
const restorePromises: Promise<any>[] = []; const restorePromises: Promise<any>[] = [];
...@@ -1708,7 +1587,7 @@ export class Workbench extends Disposable implements IPartService { ...@@ -1708,7 +1587,7 @@ export class Workbench extends Disposable implements IPartService {
toggleFullScreen = this.zenMode.transitionedToFullScreen && isFullscreen(); toggleFullScreen = this.zenMode.transitionedToFullScreen && isFullscreen();
} }
this.inZenMode.set(this.zenMode.active); this.inZenModeContext.set(this.zenMode.active);
if (!skipLayout) { if (!skipLayout) {
this.layout(); this.layout();
...@@ -1807,7 +1686,7 @@ export class Workbench extends Disposable implements IPartService { ...@@ -1807,7 +1686,7 @@ export class Workbench extends Disposable implements IPartService {
} }
} }
private layout(options?: ILayoutOptions): void { layout(options?: ILayoutOptions): void {
this.contextViewService.layout(); this.contextViewService.layout();
if (this.workbenchStarted && !this.workbenchShutdown) { if (this.workbenchStarted && !this.workbenchShutdown) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册