提交 8795b2de 编写于 作者: B Benjamin Pasero

workbench - move more things into window classes

上级 43822906
......@@ -5,7 +5,7 @@
import { mark } from 'vs/base/common/performance';
import { hash } from 'vs/base/common/hash';
import { domContentLoaded, addDisposableListener, EventType, EventHelper, detectFullscreen, addDisposableThrottledListener, getCookieValue } from 'vs/base/browser/dom';
import { domContentLoaded, detectFullscreen, getCookieValue } from 'vs/base/browser/dom';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { ILogService, ConsoleLogService, MultiplexLogService, getLogLevel } from 'vs/platform/log/common/log';
import { ConsoleLogInAutomationService } from 'vs/platform/log/browser/log';
......@@ -27,7 +27,6 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
import { onUnexpectedError } from 'vs/base/common/errors';
import { setFullscreen } from 'vs/base/browser/browser';
import { isIOS, isMacintosh } from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';
import { IWorkspaceInitializationPayload } from 'vs/platform/workspaces/common/workspaces';
import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService';
......@@ -37,7 +36,6 @@ import { SignService } from 'vs/platform/sign/browser/signService';
import type { IWorkbenchConstructionOptions, IWorkspace, IWorkbench } from 'vs/workbench/workbench.web.api';
import { BrowserStorageService } from 'vs/platform/storage/browser/storageService';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { registerWindowDriver } from 'vs/platform/driver/browser/driver';
import { BufferLogService } from 'vs/platform/log/common/bufferLog';
import { FileLogService } from 'vs/platform/log/common/fileLogService';
import { toLocalISOString } from 'vs/base/common/date';
......@@ -54,7 +52,7 @@ import { UserDataSyncStoreManagementService } from 'vs/platform/userDataSync/com
import { IUserDataSyncStoreManagementService } from 'vs/platform/userDataSync/common/userDataSync';
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { localize } from 'vs/nls';
import { CATEGORIES } from 'vs/workbench/common/actions';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
......@@ -63,7 +61,6 @@ import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/ur
import { UriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentityService';
import { BrowserWindow } from 'vs/workbench/browser/window';
import { ITimerService } from 'vs/workbench/services/timer/browser/timerService';
import { ILabelService } from 'vs/platform/label/common/label';
class BrowserMain extends Disposable {
......@@ -89,20 +86,11 @@ class BrowserMain extends Disposable {
mark('code/willStartWorkbench');
// Create Workbench
const workbench = new Workbench(
this.domElement,
services.serviceCollection,
services.logService
);
const workbench = new Workbench(this.domElement, services.serviceCollection, services.logService);
// Listeners
this.registerListeners(workbench, services.storageService, services.logService);
// Driver
if (this.configuration.driver) {
(async () => this._register(await registerWindowDriver()))();
}
// Startup
const instantiationService = workbench.startup();
......@@ -112,9 +100,6 @@ class BrowserMain extends Disposable {
// Logging
services.logService.trace('workbench configuration', JSON.stringify(this.configuration));
// Label formatting
this.registerLabelFormatters(instantiationService);
// Return API Facade
return instantiationService.invokeFunction(accessor => {
const commandService = accessor.get(ICommandService);
......@@ -139,22 +124,6 @@ class BrowserMain extends Disposable {
private registerListeners(workbench: Workbench, storageService: BrowserStorageService, logService: ILogService): void {
// Layout
const viewport = isIOS && window.visualViewport ? window.visualViewport /** Visual viewport */ : window /** Layout viewport */;
this._register(addDisposableListener(viewport, EventType.RESIZE, () => {
logService.trace(`web.main#${isIOS && window.visualViewport ? 'visualViewport' : 'window'}Resize`);
workbench.layout();
}));
// Prevent the back/forward gestures in macOS
this._register(addDisposableListener(this.domElement, EventType.WHEEL, e => e.preventDefault(), { passive: false }));
// Prevent native context menus in web
this._register(addDisposableListener(this.domElement, EventType.CONTEXT_MENU, e => EventHelper.stop(e, true)));
// Prevent default navigation on drop
this._register(addDisposableListener(this.domElement, EventType.DROP, e => EventHelper.stop(e, true)));
// Workbench Lifecycle
this._register(workbench.onBeforeShutdown(event => {
if (storageService.hasPendingUpdate) {
......@@ -163,16 +132,6 @@ class BrowserMain extends Disposable {
}));
this._register(workbench.onWillShutdown(() => storageService.close()));
this._register(workbench.onShutdown(() => this.dispose()));
// Fullscreen (Browser)
[EventType.FULLSCREEN_CHANGE, EventType.WK_FULLSCREEN_CHANGE].forEach(event => {
this._register(addDisposableListener(document, event, () => setFullscreen(!!detectFullscreen())));
});
// Fullscreen (Native)
this._register(addDisposableThrottledListener(viewport, EventType.RESIZE, () => {
setFullscreen(!!detectFullscreen());
}, undefined, isMacintosh ? 2000 /* adjust for macOS animation */ : 800 /* can be throttled */));
}
private async initServices(): Promise<{ serviceCollection: ServiceCollection, configurationService: IWorkbenchConfigurationService, logService: ILogService, storageService: BrowserStorageService }> {
......@@ -343,19 +302,6 @@ class BrowserMain extends Disposable {
}
}
private registerLabelFormatters(instantiationService: IInstantiationService) {
instantiationService.invokeFunction((accessor) => {
accessor.get(ILabelService).registerFormatter({
scheme: Schemas.userData,
priority: true,
formatting: {
label: '${scheme}:${path}',
separator: '/',
}
});
});
}
private async createStorageService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: IFileService, logService: ILogService): Promise<BrowserStorageService> {
const storageService = new BrowserStorageService(environmentService, fileService);
......
......@@ -3,17 +3,24 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { EventType, windowOpenNoOpener } from 'vs/base/browser/dom';
import { setFullscreen } from 'vs/base/browser/browser';
import { addDisposableListener, addDisposableThrottledListener, detectFullscreen, EventHelper, EventType, windowOpenNoOpener } from 'vs/base/browser/dom';
import { domEvent } from 'vs/base/browser/event';
import { timeout } from 'vs/base/common/async';
import { Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { Schemas } from 'vs/base/common/network';
import { isIOS, isMacintosh } from 'vs/base/common/platform';
import Severity from 'vs/base/common/severity';
import { localize } from 'vs/nls';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { registerWindowDriver } from 'vs/platform/driver/browser/driver';
import { ILabelService } from 'vs/platform/label/common/label';
import { ILogService } from 'vs/platform/log/common/log';
import { IOpenerService, matchesScheme } from 'vs/platform/opener/common/opener';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { BrowserLifecycleService } from 'vs/workbench/services/lifecycle/browser/lifecycleService';
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
......@@ -23,7 +30,11 @@ export class BrowserWindow extends Disposable {
@IOpenerService private readonly openerService: IOpenerService,
@ILifecycleService private readonly lifecycleService: BrowserLifecycleService,
@IDialogService private readonly dialogService: IDialogService,
@IHostService private readonly hostService: IHostService
@IHostService private readonly hostService: IHostService,
@ILabelService private readonly labelService: ILabelService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
@ILogService private readonly logService: ILogService,
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService
) {
super();
......@@ -32,7 +43,38 @@ export class BrowserWindow extends Disposable {
}
private registerListeners(): void {
// Lifecycle
this._register(this.lifecycleService.onWillShutdown(() => this.onWillShutdown()));
// Layout
const viewport = isIOS && window.visualViewport ? window.visualViewport /** Visual viewport */ : window /** Layout viewport */;
this._register(addDisposableListener(viewport, EventType.RESIZE, () => this.onWindowResize()));
// Prevent the back/forward gestures in macOS
this._register(addDisposableListener(this.layoutService.getWorkbenchContainer(), EventType.WHEEL, e => e.preventDefault(), { passive: false }));
// Prevent native context menus in web
this._register(addDisposableListener(this.layoutService.getWorkbenchContainer(), EventType.CONTEXT_MENU, e => EventHelper.stop(e, true)));
// Prevent default navigation on drop
this._register(addDisposableListener(this.layoutService.getWorkbenchContainer(), EventType.DROP, e => EventHelper.stop(e, true)));
// Fullscreen (Browser)
[EventType.FULLSCREEN_CHANGE, EventType.WK_FULLSCREEN_CHANGE].forEach(event => {
this._register(addDisposableListener(document, event, () => setFullscreen(!!detectFullscreen())));
});
// Fullscreen (Native)
this._register(addDisposableThrottledListener(viewport, EventType.RESIZE, () => {
setFullscreen(!!detectFullscreen());
}, undefined, isMacintosh ? 2000 /* adjust for macOS animation */ : 800 /* can be throttled */));
}
private onWindowResize(): void {
this.logService.trace(`web.main#${isIOS && window.visualViewport ? 'visualViewport' : 'window'}Resize`);
this.layoutService.layout();
}
private onWillShutdown(): void {
......@@ -72,8 +114,16 @@ export class BrowserWindow extends Disposable {
private create(): void {
// Driver
if (this.environmentService.options?.driver) {
(async () => this._register(await registerWindowDriver()))();
}
// Handle open calls
this.setupOpenHandlers();
// Label formatting
this.registerLabelFormatters();
}
private setupOpenHandlers(): void {
......@@ -97,4 +147,15 @@ export class BrowserWindow extends Disposable {
}
});
}
private registerLabelFormatters() {
this.labelService.registerFormatter({
scheme: Schemas.userData,
priority: true,
formatting: {
label: '${scheme}:${path}',
separator: '/',
}
});
}
}
......@@ -13,7 +13,7 @@ import { mark } from 'vs/base/common/performance';
import { Workbench } from 'vs/workbench/browser/workbench';
import { NativeWindow } from 'vs/workbench/electron-sandbox/window';
import { setZoomLevel, setZoomFactor, setFullscreen } from 'vs/base/browser/browser';
import { domContentLoaded, addDisposableListener, EventType, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { domContentLoaded } from 'vs/base/browser/dom';
import { onUnexpectedError } from 'vs/base/common/errors';
import { URI } from 'vs/base/common/uri';
import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService';
......@@ -137,32 +137,11 @@ class NativeMain extends Disposable {
private registerListeners(workbench: Workbench, storageService: NativeStorageService): void {
// Layout
this._register(addDisposableListener(window, EventType.RESIZE, e => this.onWindowResize(e, true, workbench)));
// Workbench Lifecycle
this._register(workbench.onShutdown(() => this.dispose()));
this._register(workbench.onWillShutdown(event => event.join(storageService.close(), 'join.closeStorage')));
}
private onWindowResize(e: Event, retry: boolean, workbench: Workbench): void {
if (e.target === window) {
if (window.document && window.document.body && window.document.body.clientWidth === 0) {
// TODO@bpasero 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, workbench));
}
return;
}
workbench.layout();
}
}
private async initServices(): Promise<{ serviceCollection: ServiceCollection, logService: ILogService, storageService: NativeStorageService }> {
const serviceCollection = new ServiceCollection();
......
......@@ -81,3 +81,19 @@ export class ToggleSharedProcessAction extends Action2 {
return accessor.get(INativeHostService).toggleSharedProcessWindow();
}
}
export class ReloadWindowWithExtensionsDisabledAction extends Action2 {
constructor() {
super({
id: 'workbench.action.reloadWindowWithExtensionsDisabled',
title: { value: localize('reloadWindowWithExtensionsDisabled', "Reload With Extensions Disabled"), original: 'Reload With Extensions Disabled' },
category: CATEGORIES.Developer,
f1: true
});
}
async run(accessor: ServicesAccessor): Promise<void> {
return accessor.get(INativeHostService).reload({ disableExtensions: true });
}
}
......@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/actions';
import { URI } from 'vs/base/common/uri';
import { Action } from 'vs/base/common/actions';
import * as nls from 'vs/nls';
......@@ -122,26 +121,6 @@ export class ZoomResetAction extends BaseZoomAction {
}
}
export class ReloadWindowWithExtensionsDisabledAction extends Action {
static readonly ID = 'workbench.action.reloadWindowWithExtensionsDisabled';
static readonly LABEL = nls.localize('reloadWindowWithExtensionsDisabled', "Reload With Extensions Disabled");
constructor(
id: string,
label: string,
@INativeHostService private readonly nativeHostService: INativeHostService
) {
super(id, label);
}
async run(): Promise<boolean> {
await this.nativeHostService.reload({ disableExtensions: true });
return true;
}
}
export abstract class BaseSwitchWindow extends Action {
private readonly closeWindowAction: IQuickInputButton = {
......
......@@ -11,8 +11,8 @@ import { IConfigurationRegistry, Extensions as ConfigurationExtensions, Configur
import { IWorkbenchActionRegistry, Extensions, CATEGORIES } from 'vs/workbench/common/actions';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { isLinux, isMacintosh } from 'vs/base/common/platform';
import { ConfigureRuntimeArgumentsAction, ToggleDevToolsAction, ToggleSharedProcessAction } from 'vs/workbench/electron-sandbox/actions/developerActions';
import { ZoomResetAction, ZoomOutAction, ZoomInAction, CloseCurrentWindowAction, SwitchWindow, QuickSwitchWindow, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-sandbox/actions/windowActions';
import { ConfigureRuntimeArgumentsAction, ToggleDevToolsAction, ToggleSharedProcessAction, ReloadWindowWithExtensionsDisabledAction } from 'vs/workbench/electron-sandbox/actions/developerActions';
import { ZoomResetAction, ZoomOutAction, ZoomInAction, CloseCurrentWindowAction, SwitchWindow, QuickSwitchWindow, NewWindowTabHandler, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-sandbox/actions/windowActions';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
......@@ -87,8 +87,7 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema';
// Actions: Developer
(function registerDeveloperActions(): void {
registry.registerWorkbenchAction(SyncActionDescriptor.from(ReloadWindowWithExtensionsDisabledAction), 'Developer: Reload With Extensions Disabled', CATEGORIES.Developer.value);
registerAction2(ReloadWindowWithExtensionsDisabledAction);
registerAction2(ConfigureRuntimeArgumentsAction);
registerAction2(ToggleSharedProcessAction);
registerAction2(ToggleDevToolsAction);
......
......@@ -8,7 +8,7 @@ import { mark } from 'vs/base/common/performance';
import { Workbench } from 'vs/workbench/browser/workbench';
import { NativeWindow } from 'vs/workbench/electron-sandbox/window';
import { setZoomLevel, setZoomFactor, setFullscreen } from 'vs/base/browser/browser';
import { domContentLoaded, addDisposableListener, EventType, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { domContentLoaded } from 'vs/base/browser/dom';
import { URI } from 'vs/base/common/uri';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
......@@ -109,32 +109,11 @@ class NativeMain extends Disposable {
private registerListeners(workbench: Workbench, storageService: SimpleStorageService): void {
// Layout
this._register(addDisposableListener(window, EventType.RESIZE, e => this.onWindowResize(e, true, workbench)));
// Workbench Lifecycle
this._register(workbench.onShutdown(() => this.dispose()));
this._register(workbench.onWillShutdown(event => event.join(storageService.close(), 'join.closeStorage')));
}
private onWindowResize(e: Event, retry: boolean, workbench: Workbench): void {
if (e.target === window) {
if (window.document && window.document.body && window.document.body.clientWidth === 0) {
// TODO@bpasero 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, workbench));
}
return;
}
workbench.layout();
}
}
private async initServices(): Promise<{ serviceCollection: ServiceCollection, logService: ILogService, storageService: SimpleStorageService }> {
const serviceCollection = new ServiceCollection();
......
......@@ -7,7 +7,7 @@ import { localize } from 'vs/nls';
import { URI } from 'vs/base/common/uri';
import { onUnexpectedError } from 'vs/base/common/errors';
import { equals } from 'vs/base/common/objects';
import { EventType, EventHelper, addDisposableListener } from 'vs/base/browser/dom';
import { EventType, EventHelper, addDisposableListener, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { Separator } from 'vs/base/common/actions';
import { IFileService } from 'vs/platform/files/common/files';
import { EditorResourceAccessor, IUntitledTextResourceEditorInput, SideBySideEditor, pathsToEditors } from 'vs/workbench/common/editor';
......@@ -115,6 +115,9 @@ export class NativeWindow extends Disposable {
private registerListeners(): void {
// Layout
this._register(addDisposableListener(window, EventType.RESIZE, e => this.onWindowResize(e, true)));
// React to editor input changes
this._register(this.editorService.onDidActiveEditorChange(() => this.updateTouchbarMenu()));
......@@ -328,6 +331,24 @@ export class NativeWindow extends Disposable {
this.onDidPanelPositionChange(this.layoutService.getPanelPosition());
}
private onWindowResize(e: UIEvent, retry: boolean): void {
if (e.target === window) {
if (window.document && window.document.body && window.document.body.clientWidth === 0) {
// TODO@bpasero 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.layoutService.layout();
}
}
private updateDocumentEdited(isDirty = this.workingCopyService.hasDirty): void {
if ((!this.isDocumentedEdited && isDirty) || (this.isDocumentedEdited && !isDirty)) {
this.isDocumentedEdited = isDirty;
......
......@@ -106,6 +106,11 @@ export interface IWorkbenchLayoutService extends ILayoutService {
*/
readonly onPartVisibilityChange: Event<void>;
/**
* Run a layout of the workbench.
*/
layout(): void;
/**
* Asks the part service if all parts have been fully restored. For editor part
* this means that the contents of editors have loaded.
......
......@@ -439,6 +439,7 @@ export class TestLayoutService implements IWorkbenchLayoutService {
private readonly _onMenubarVisibilityChange = new Emitter<Dimension>();
get onMenubarVisibilityChange(): Event<Dimension> { return this._onMenubarVisibilityChange.event; }
layout(): void { }
isRestored(): boolean { return true; }
hasFocus(_part: Parts): boolean { return false; }
focusPart(_part: Parts): void { }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册