提交 1fd399e1 编写于 作者: B Benjamin Pasero

debt - move some electron specific listeners

上级 3946e323
......@@ -311,7 +311,7 @@
"./vs/workbench/contrib/themes/test/electron-browser/themes.test.contribution.ts",
"./vs/workbench/contrib/url/common/url.contribution.ts",
"./vs/workbench/contrib/webview/electron-browser/webviewProtocols.ts",
"./vs/workbench/electron-browser/window.ts",
// "./vs/workbench/electron-browser/window.ts", TODO@matt https://github.com/Microsoft/vscode/issues/69198
"./vs/workbench/services/activity/common/activity.ts",
"./vs/workbench/services/backup/common/backup.ts",
"./vs/workbench/services/backup/node/backupFileService.ts",
......
......@@ -4,21 +4,21 @@
*--------------------------------------------------------------------------------------------*/
import * as fs from 'fs';
import * as gracefulFs from 'graceful-fs';
import { createHash } from 'crypto';
import * as perf from 'vs/base/common/performance';
import { importEntries, mark } from 'vs/base/common/performance';
import { Workbench } from 'vs/workbench/electron-browser/workbench';
import { ElectronWindow } from 'vs/workbench/electron-browser/window';
import * as browser from 'vs/base/browser/browser';
import { setZoomLevel, setZoomFactor, setFullscreen } from 'vs/base/browser/browser';
import { domContentLoaded, addDisposableListener, EventType, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { onUnexpectedError } from 'vs/base/common/errors';
import * as platform from 'vs/base/common/platform';
import { isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
import { URI as uri } from 'vs/base/common/uri';
import { WorkspaceService } from 'vs/workbench/services/configuration/node/configurationService';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { stat } from 'vs/base/node/pfs';
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
import * as gracefulFs from 'graceful-fs';
import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/keybindingService';
import { IWindowConfiguration, IWindowsService } from 'vs/platform/windows/common/windows';
import { WindowsChannelClient } from 'vs/platform/windows/node/windowsIpc';
......@@ -51,7 +51,7 @@ import { InstantiationService } from 'vs/platform/instantiation/common/instantia
import { Disposable } from 'vs/base/common/lifecycle';
import { registerWindowDriver } from 'vs/platform/driver/electron-browser/driver';
export class CodeWindow extends Disposable {
class CodeRendererMain extends Disposable {
private workbench: Workbench;
......@@ -70,12 +70,12 @@ export class CodeWindow extends Disposable {
this.reviveUris();
// Setup perf
perf.importEntries(this.configuration.perfEntries);
importEntries(this.configuration.perfEntries);
// Browser config
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.setFullscreen(!!this.configuration.fullscreen);
setZoomFactor(webFrame.getZoomFactor()); // Ensure others can listen to zoom level changes
setZoomLevel(webFrame.getZoomLevel(), true /* isTrusted */); // Can be trusted because we are not setting it ourselves (https://github.com/Microsoft/vscode/issues/26151)
setFullscreen(!!this.configuration.fullscreen);
// Keyboard support
KeyboardMapperFactory.INSTANCE._onKeyboardLayoutChanged();
......@@ -107,7 +107,7 @@ export class CodeWindow extends Disposable {
return this.initServices(electronMainClient).then(services => {
return domContentLoaded().then(() => {
perf.mark('willStartWorkbench');
mark('willStartWorkbench');
const instantiationService = new InstantiationService(services, true);
......@@ -261,11 +261,11 @@ export class CodeWindow extends Disposable {
function computeLocalDiskFolderId(folder: uri, stat: fs.Stats): string {
let ctime: number | undefined;
if (platform.isLinux) {
if (isLinux) {
ctime = stat.ino; // Linux: birthtime is ctime, so we cannot use it! We use the ino instead!
} else if (platform.isMacintosh) {
} else if (isMacintosh) {
ctime = stat.birthtime.getTime(); // macOS: birthtime is fine to use as is
} else if (platform.isWindows) {
} else if (isWindows) {
if (typeof stat.birthtimeMs === 'number') {
ctime = Math.floor(stat.birthtimeMs); // Windows: fix precision issue in node.js 8.x to get 7.x results (see https://github.com/nodejs/node/issues/19897)
} else {
......@@ -323,7 +323,7 @@ export class CodeWindow extends Disposable {
}
export function main(configuration: IWindowConfiguration): Promise<void> {
const window = new CodeWindow(configuration);
const renderer = new CodeRendererMain(configuration);
return window.open();
return renderer.open();
}
......@@ -23,14 +23,13 @@ import * as browser from 'vs/base/browser/browser';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IResourceInput } from 'vs/platform/editor/common/editor';
import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/keybindingService';
import { Themable } from 'vs/workbench/common/theme';
import { ipcRenderer as ipc, webFrame, crashReporter } from 'electron';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { IMenuService, MenuId, IMenu, MenuItemAction, ICommandAction } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { fillInActionBarActions } from 'vs/platform/actions/browser/menuItemActionItem';
import { RunOnceScheduler } from 'vs/base/common/async';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
import { LifecyclePhase, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
import { IIntegrityService } from 'vs/workbench/services/integrity/common/integrity';
......@@ -42,6 +41,7 @@ import { EditorServiceImpl } from 'vs/workbench/browser/parts/editor/editor';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
const TextInputActions: IAction[] = [
new Action('undo', nls.localize('undo', "Undo"), undefined, true, () => Promise.resolve(document.execCommand('undo'))),
......@@ -54,7 +54,9 @@ const TextInputActions: IAction[] = [
new Action('editor.action.selectAll', nls.localize('selectAll', "Select All"), undefined, true, () => Promise.resolve(document.execCommand('selectAll')))
];
export class ElectronWindow extends Themable {
export class ElectronWindow extends Disposable {
private static readonly closeWhenEmptyConfigurationKey = 'window.closeWhenEmpty';
private touchBarMenu?: IMenu;
private touchBarUpdater: RunOnceScheduler;
......@@ -66,6 +68,8 @@ export class ElectronWindow extends Themable {
private addFoldersScheduler: RunOnceScheduler;
private pendingFoldersToAdd: URI[];
private closeEmptyWindowScheduler: RunOnceScheduler = this._register(new RunOnceScheduler(() => this.onAllEditorsClosed(), 50));
constructor(
@IEditorService private readonly editorService: EditorServiceImpl,
@IWindowsService private readonly windowsService: IWindowsService,
......@@ -84,9 +88,10 @@ export class ElectronWindow extends Themable {
@ILifecycleService private readonly lifecycleService: ILifecycleService,
@IIntegrityService private readonly integrityService: IIntegrityService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IAccessibilityService private readonly accessibilityService: IAccessibilityService
@IAccessibilityService private readonly accessibilityService: IAccessibilityService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService
) {
super(themeService);
super();
this.touchBarDisposables = [];
......@@ -219,6 +224,51 @@ export class ElectronWindow extends Themable {
// Context menu support in input/textarea
window.document.addEventListener('contextmenu', e => this.onContextMenu(e));
// Listen to visible editor changes
this._register(this.editorService.onDidVisibleEditorsChange(() => this.onDidVisibleEditorsChange()));
// Listen to editor closing (if we run with --wait)
const filesToWait = this.windowService.getConfiguration().filesToWait;
if (filesToWait) {
const resourcesToWaitFor = filesToWait.paths.map(p => p.fileUri);
const waitMarkerFile = URI.file(filesToWait.waitMarkerFilePath);
const listenerDispose = this.editorService.onDidCloseEditor(() => this.onEditorClosed(listenerDispose, resourcesToWaitFor, waitMarkerFile));
this._register(listenerDispose);
}
}
private onDidVisibleEditorsChange(): void {
// Close when empty: check if we should close the window based on the setting
// Overruled by: window has a workspace opened or this window is for extension development
// or setting is disabled. Also enabled when running with --wait from the command line.
const visibleEditors = this.editorService.visibleControls;
if (visibleEditors.length === 0 && this.contextService.getWorkbenchState() === WorkbenchState.EMPTY && !this.environmentService.isExtensionDevelopment) {
const closeWhenEmpty = this.configurationService.getValue<boolean>(ElectronWindow.closeWhenEmptyConfigurationKey);
if (closeWhenEmpty || this.environmentService.args.wait) {
this.closeEmptyWindowScheduler.schedule();
}
}
}
private onAllEditorsClosed(): void {
const visibleEditors = this.editorService.visibleControls.length;
if (visibleEditors === 0) {
this.windowService.closeWindow();
}
}
private onEditorClosed(listenerDispose: IDisposable, resourcesToWaitFor: URI[], waitMarkerFile: URI): void {
// In wait mode, listen to changes to the editors and wait until the files
// are closed that the user wants to wait for. When this happens we delete
// the wait marker file to signal to the outside that editing is done.
if (resourcesToWaitFor.every(resource => !this.editorService.isOpen({ resource }))) {
listenerDispose.dispose();
this.fileService.del(waitMarkerFile);
}
}
private onContextMenu(e: MouseEvent): void {
......
......@@ -10,7 +10,7 @@ import { setFileNameComparer } from 'vs/base/common/comparers';
import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
import { Event, Emitter, setGlobalLeakWarningThreshold } from 'vs/base/common/event';
import { EventType, addDisposableListener, addClasses, addClass, removeClass, isAncestor, getClientArea, position, size, removeClasses } from 'vs/base/browser/dom';
import { RunOnceScheduler, runWhenIdle, IdleValue } from 'vs/base/common/async';
import { runWhenIdle, IdleValue } from 'vs/base/common/async';
import { getZoomLevel, onDidChangeFullscreen, isFullscreen, getZoomFactor } from 'vs/base/browser/browser';
import { mark } from 'vs/base/common/performance';
import { onUnexpectedError, setUnexpectedErrorHandler } from 'vs/base/common/errors';
......@@ -71,7 +71,6 @@ import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common
import { FileDecorationsService } from 'vs/workbench/services/decorations/browser/decorationsService';
import { IDecorationsService } from 'vs/workbench/services/decorations/browser/decorations';
import { ActivityService } from 'vs/workbench/services/activity/browser/activityService';
import { URI } from 'vs/base/common/uri';
import { IListService, ListService } from 'vs/platform/list/browser/listService';
import { IViewsService } from 'vs/workbench/common/views';
import { ViewsService } from 'vs/workbench/browser/parts/views/views';
......@@ -241,7 +240,6 @@ export class Workbench extends Disposable implements IPartService {
private static readonly sidebarPositionConfigurationKey = 'workbench.sideBar.location';
private static readonly statusbarVisibleConfigurationKey = 'workbench.statusBar.visible';
private static readonly activityBarVisibleConfigurationKey = 'workbench.activityBar.visible';
private static readonly closeWhenEmptyConfigurationKey = 'window.closeWhenEmpty';
private static readonly fontAliasingConfigurationKey = 'workbench.fontAliasing';
_serviceBrand: any;
......@@ -316,8 +314,6 @@ export class Workbench extends Disposable implements IPartService {
private inZenModeContext: IContextKey<boolean>;
private sideBarVisibleContext: IContextKey<boolean>;
private closeEmptyWindowScheduler: RunOnceScheduler = this._register(new RunOnceScheduler(() => this.onAllEditorsClosed(), 50));
constructor(
private container: HTMLElement,
private configuration: IWindowConfiguration,
......@@ -453,10 +449,7 @@ export class Workbench extends Disposable implements IPartService {
this.layout();
// Handle case where workbench is not starting up properly
const timeoutHandle = setTimeout(() => {
this.logService.warn('Workbench did not finish loading in 10 seconds, that might be a problem that should be reported.');
}, 10000);
const timeoutHandle = setTimeout(() => this.logService.warn('Workbench did not finish loading in 10 seconds, that might be a problem that should be reported.'), 10000);
this.lifecycleService.when(LifecyclePhase.Restored).then(() => clearTimeout(timeoutHandle));
// Restore Parts
......@@ -776,21 +769,9 @@ export class Workbench extends Disposable implements IPartService {
// Storage
this._register(this.storageService.onWillSaveState(e => this.saveState(e)));
// Listen to visible editor changes
this._register(this.editorService.onDidVisibleEditorsChange(() => this.onDidVisibleEditorsChange()));
// Listen to editor group activations when editor is hidden
this._register(this.editorPart.onDidActivateGroup(() => { if (this.editorHidden) { this.setEditorHidden(false); } }));
// Listen to editor closing (if we run with --wait)
const filesToWait = this.configuration.filesToWait;
if (filesToWait) {
const resourcesToWaitFor = filesToWait.paths.map(p => p.fileUri);
const waitMarkerFile = URI.file(filesToWait.waitMarkerFilePath);
const listenerDispose = this.editorService.onDidCloseEditor(() => this.onEditorClosed(listenerDispose, resourcesToWaitFor, waitMarkerFile));
this._register(listenerDispose);
}
// Restore editor if hidden and it changes
this._register(this.editorService.onDidVisibleEditorsChange(() => this.restoreHiddenEditor()));
this._register(this.editorPart.onDidActivateGroup(() => this.restoreHiddenEditor()));
// Configuration changes
this._register(this.configurationService.onDidChangeConfiguration(() => this.onDidUpdateConfiguration()));
......@@ -837,42 +818,12 @@ export class Workbench extends Disposable implements IPartService {
}
}
private onEditorClosed(listenerDispose: IDisposable, resourcesToWaitFor: URI[], waitMarkerFile: URI): void {
// In wait mode, listen to changes to the editors and wait until the files
// are closed that the user wants to wait for. When this happens we delete
// the wait marker file to signal to the outside that editing is done.
if (resourcesToWaitFor.every(resource => !this.editorService.isOpen({ resource }))) {
listenerDispose.dispose();
this.fileService.del(waitMarkerFile);
}
}
private onDidVisibleEditorsChange(): void {
const visibleEditors = this.editorService.visibleControls;
// Close when empty: check if we should close the window based on the setting
// Overruled by: window has a workspace opened or this window is for extension development
// or setting is disabled. Also enabled when running with --wait from the command line.
if (visibleEditors.length === 0 && this.contextService.getWorkbenchState() === WorkbenchState.EMPTY && !this.environmentService.isExtensionDevelopment) {
const closeWhenEmpty = this.configurationService.getValue<boolean>(Workbench.closeWhenEmptyConfigurationKey);
if (closeWhenEmpty || this.environmentService.args.wait) {
this.closeEmptyWindowScheduler.schedule();
}
}
private restoreHiddenEditor(): void {
if (this.editorHidden) {
this.setEditorHidden(false);
}
}
private onAllEditorsClosed(): void {
const visibleEditors = this.editorService.visibleControls.length;
if (visibleEditors === 0) {
this.windowService.closeWindow();
}
}
private onDidUpdateConfiguration(skipLayout?: boolean): void {
const newSidebarPositionValue = this.configurationService.getValue<string>(Workbench.sidebarPositionConfigurationKey);
const newSidebarPosition = (newSidebarPositionValue === 'right') ? Position.RIGHT : Position.LEFT;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册