diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 9fdb90b02951..33db58c922f9 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -85,6 +85,7 @@ import { ActiveWindowManager } from 'vs/platform/windows/common/windowTracker'; import { IKeyboardLayoutMainService, KeyboardLayoutMainService } from 'vs/platform/keyboardLayout/electron-main/keyboardLayoutMainService'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; +import { DisplayMainService, IDisplayMainService } from 'vs/platform/display/electron-main/displayMainService'; export class CodeApplication extends Disposable { private windowsMainService: IWindowsMainService | undefined; @@ -464,6 +465,7 @@ export class CodeApplication extends Disposable { services.set(IIssueMainService, new SyncDescriptor(IssueMainService, [machineId, this.userEnv])); services.set(IEncryptionMainService, new SyncDescriptor(EncryptionMainService, [machineId])); services.set(IKeyboardLayoutMainService, new SyncDescriptor(KeyboardLayoutMainService)); + services.set(IDisplayMainService, new SyncDescriptor(DisplayMainService)); services.set(INativeHostMainService, new SyncDescriptor(NativeHostMainService)); services.set(IWebviewManagerService, new SyncDescriptor(WebviewMainService)); services.set(IWorkspacesService, new SyncDescriptor(WorkspacesService)); @@ -558,6 +560,10 @@ export class CodeApplication extends Disposable { const keyboardLayoutChannel = createChannelReceiver(keyboardLayoutMainService); electronIpcServer.registerChannel('keyboardLayout', keyboardLayoutChannel); + const displayMainService = accessor.get(IDisplayMainService); + const displayChannel = createChannelReceiver(displayMainService); + electronIpcServer.registerChannel('display', displayChannel); + const nativeHostMainService = this.nativeHostMainService = accessor.get(INativeHostMainService); const nativeHostChannel = createChannelReceiver(this.nativeHostMainService); electronIpcServer.registerChannel('nativeHost', nativeHostChannel); diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 9eea5509673d..f8fe899ca4b4 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -468,9 +468,6 @@ export class CodeWindow extends Disposable implements ICodeWindow { return; // disposed } - // Notify renderers about displays changed - this.sendWhenReady('vscode:displayChanged'); - // Simple fullscreen doesn't resize automatically when the resolution changes so as a workaround // we need to detect when display metrics change or displays are added/removed and toggle the // fullscreen manually. diff --git a/src/vs/platform/display/common/displayMainService.ts b/src/vs/platform/display/common/displayMainService.ts new file mode 100644 index 000000000000..44d79f8d545d --- /dev/null +++ b/src/vs/platform/display/common/displayMainService.ts @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * 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'; + +export interface IDisplayMainService { + readonly _serviceBrand: undefined; + readonly onDidDisplayChanged: Event; +} diff --git a/src/vs/platform/display/electron-main/displayMainService.ts b/src/vs/platform/display/electron-main/displayMainService.ts new file mode 100644 index 000000000000..e360fc48693a --- /dev/null +++ b/src/vs/platform/display/electron-main/displayMainService.ts @@ -0,0 +1,47 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IDisplayMainService as ICommonDisplayMainService } from 'vs/platform/display/common/displayMainService'; +import { Emitter } from 'vs/base/common/event'; +import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; +import { app, Display, screen } from 'electron'; +import { RunOnceScheduler } from 'vs/base/common/async'; + +export const IDisplayMainService = createDecorator('displayMainService'); + +export interface IDisplayMainService extends ICommonDisplayMainService { } + +export class DisplayMainService extends Disposable implements ICommonDisplayMainService { + + declare readonly _serviceBrand: undefined; + + private readonly _onDidDisplayChanged = this._register(new Emitter()); + readonly onDidDisplayChanged = this._onDidDisplayChanged.event; + + constructor() { + super(); + + const displayChangedScheduler = this._register(new RunOnceScheduler(() => { + this._onDidDisplayChanged.fire(); + }, 100)); + + app.whenReady().then(() => { + + const displayChangedListener = (event: Event, display: Display, changedMetrics?: string[]) => { + displayChangedScheduler.schedule(); + }; + + screen.on('display-metrics-changed', displayChangedListener); + this._register(toDisposable(() => screen.removeListener('display-metrics-changed', displayChangedListener))); + + screen.on('display-added', displayChangedListener); + this._register(toDisposable(() => screen.removeListener('display-added', displayChangedListener))); + + screen.on('display-removed', displayChangedListener); + this._register(toDisposable(() => screen.removeListener('display-removed', displayChangedListener))); + }); + } +} diff --git a/src/vs/workbench/contrib/codeEditor/electron-sandbox/codeEditor.contribution.ts b/src/vs/workbench/contrib/codeEditor/electron-sandbox/codeEditor.contribution.ts index 087637541876..d544a687a80a 100644 --- a/src/vs/workbench/contrib/codeEditor/electron-sandbox/codeEditor.contribution.ts +++ b/src/vs/workbench/contrib/codeEditor/electron-sandbox/codeEditor.contribution.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import './displayChangeRemeasureFonts'; import './inputClipboardActions'; import './selectionClipboard'; import './sleepResumeRepaintMinimap'; diff --git a/src/vs/workbench/contrib/codeEditor/electron-sandbox/displayChangeRemeasureFonts.ts b/src/vs/workbench/contrib/codeEditor/electron-sandbox/displayChangeRemeasureFonts.ts new file mode 100644 index 000000000000..efcdd8981df7 --- /dev/null +++ b/src/vs/workbench/contrib/codeEditor/electron-sandbox/displayChangeRemeasureFonts.ts @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService'; +import { IDisplayMainService } from 'vs/platform/display/common/displayMainService'; +import { createChannelSender } from 'vs/base/parts/ipc/common/ipc'; +import { clearAllFontInfos } from 'vs/editor/browser/config/configuration'; + +class DisplayChangeRemeasureFonts extends Disposable implements IWorkbenchContribution { + + constructor( + @IMainProcessService mainProcessService: IMainProcessService + ) { + super(); + const displayMainService = createChannelSender(mainProcessService.getChannel('display')); + displayMainService.onDidDisplayChanged(() => { + clearAllFontInfos(); + }); + } +} + +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DisplayChangeRemeasureFonts, LifecyclePhase.Eventually); diff --git a/src/vs/workbench/electron-sandbox/window.ts b/src/vs/workbench/electron-sandbox/window.ts index 9062e49737c8..aabf783b3108 100644 --- a/src/vs/workbench/electron-sandbox/window.ts +++ b/src/vs/workbench/electron-sandbox/window.ts @@ -59,7 +59,6 @@ import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IWorkingCopyService, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { Event } from 'vs/base/common/event'; -import { clearAllFontInfos } from 'vs/editor/browser/config/configuration'; import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { IAddressProvider, IAddress } from 'vs/platform/remote/common/remoteAgentConnection'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; @@ -205,11 +204,6 @@ export class NativeWindow extends Disposable { choices )); - // Display change events - ipcRenderer.on('vscode:displayChanged', () => { - clearAllFontInfos(); - }); - // Fullscreen Events ipcRenderer.on('vscode:enterFullScreen', async () => { await this.lifecycleService.when(LifecyclePhase.Ready);