aux window - cleanup preloads (#196832)

* aux window - cleanup preloads

* 💄

* 💄
This commit is contained in:
Benjamin Pasero 2023-10-27 16:42:45 +02:00 committed by GitHub
parent 56088b01d9
commit 62fdec2def
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 72 additions and 81 deletions

View file

@ -64,7 +64,7 @@ const vscodeResources = [
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,cpuUsage.sh,ps.sh}',
'out-build/vs/base/browser/ui/codicons/codicon/**',
'out-build/vs/base/parts/sandbox/electron-sandbox/preload.js',
'out-build/vs/base/parts/sandbox/electron-sandbox/preload-slim.js',
'out-build/vs/base/parts/sandbox/electron-sandbox/preload-aux.js',
'out-build/vs/workbench/browser/media/*-theme.css',
'out-build/vs/workbench/contrib/debug/**/*.json',
'out-build/vs/workbench/contrib/externalTerminal/**/*.scpt',

View file

@ -121,31 +121,11 @@ export const webFrame: WebFrame = globals.vscode.webFrame;
export const process: ISandboxNodeProcess = globals.vscode.process;
export const context: ISandboxContext = globals.vscode.context;
export interface IGlobalsSlim {
/**
* A set of globals that are available in all windows that either
* depend on `preload.js` or `preload-aux.js`.
*/
export interface ISandboxGlobals {
readonly ipcRenderer: Pick<import('vs/base/parts/sandbox/electron-sandbox/electronTypes').IpcRenderer, 'send' | 'invoke'>;
readonly webFrame: import('vs/base/parts/sandbox/electron-sandbox/electronTypes').WebFrame;
}
/**
* Get the globals that are available in the given window. Since
* this method supports auxiliary windows, only a subset of globals
* is returned.
*/
export function getGlobals(win: Window): IGlobalsSlim | undefined {
if (win === window) {
return { ipcRenderer, webFrame };
}
const auxiliaryWindowCandidate = win as unknown as {
vscode: {
ipcRenderer: Pick<import('vs/base/parts/sandbox/electron-sandbox/electronTypes').IpcRenderer, 'send' | 'invoke'>;
webFrame: import('vs/base/parts/sandbox/electron-sandbox/electronTypes').WebFrame;
};
};
if (auxiliaryWindowCandidate?.vscode?.ipcRenderer && auxiliaryWindowCandidate?.vscode?.webFrame) {
return auxiliaryWindowCandidate.vscode;
}
return undefined;
}

View file

@ -46,12 +46,12 @@
/**
* @param {string} channel
* @param {any[]} args
* @returns {Promise<any> | never}
* @returns {Promise<any>}
*/
invoke(channel, ...args) {
if (validateIPC(channel)) {
return ipcRenderer.invoke(channel, ...args);
}
validateIPC(channel);
return ipcRenderer.invoke(channel, ...args);
}
},

View file

@ -56,24 +56,23 @@
}
try {
if (validateIPC(windowConfigIpcChannel)) {
validateIPC(windowConfigIpcChannel);
// Resolve configuration from electron-main
configuration = await ipcRenderer.invoke(windowConfigIpcChannel);
// Resolve configuration from electron-main
const resolvedConfiguration = configuration = await ipcRenderer.invoke(windowConfigIpcChannel);
// Apply `userEnv` directly
Object.assign(process.env, configuration.userEnv);
// Apply `userEnv` directly
Object.assign(process.env, resolvedConfiguration.userEnv);
// Apply zoom level early before even building the
// window DOM elements to avoid UI flicker. We always
// have to set the zoom level from within the window
// because Chrome has it's own way of remembering zoom
// settings per origin (if vscode-file:// is used) and
// we want to ensure that the user configuration wins.
webFrame.setZoomLevel(configuration.zoomLevel ?? 0);
// Apply zoom level early before even building the
// window DOM elements to avoid UI flicker. We always
// have to set the zoom level from within the window
// because Chrome has it's own way of remembering zoom
// settings per origin (if vscode-file:// is used) and
// we want to ensure that the user configuration wins.
webFrame.setZoomLevel(resolvedConfiguration.zoomLevel ?? 0);
return configuration;
}
return resolvedConfiguration;
} catch (error) {
throw new Error(`Preload: unable to fetch vscode-window-config: ${error}`);
}
@ -145,51 +144,51 @@
/**
* @param {string} channel
* @param {any[]} args
* @returns {Promise<any> | never}
* @returns {Promise<any>}
*/
invoke(channel, ...args) {
if (validateIPC(channel)) {
return ipcRenderer.invoke(channel, ...args);
}
validateIPC(channel);
return ipcRenderer.invoke(channel, ...args);
},
/**
* @param {string} channel
* @param {(event: IpcRendererEvent, ...args: any[]) => void} listener
* @returns {IpcRenderer | never}
* @returns {IpcRenderer}
*/
on(channel, listener) {
if (validateIPC(channel)) {
ipcRenderer.on(channel, listener);
validateIPC(channel);
return this;
}
ipcRenderer.on(channel, listener);
return this;
},
/**
* @param {string} channel
* @param {(event: IpcRendererEvent, ...args: any[]) => void} listener
* @returns {IpcRenderer | never}
* @returns {IpcRenderer}
*/
once(channel, listener) {
if (validateIPC(channel)) {
ipcRenderer.once(channel, listener);
validateIPC(channel);
return this;
}
ipcRenderer.once(channel, listener);
return this;
},
/**
* @param {string} channel
* @param {(event: IpcRendererEvent, ...args: any[]) => void} listener
* @returns {IpcRenderer | never}
* @returns {IpcRenderer}
*/
removeListener(channel, listener) {
if (validateIPC(channel)) {
ipcRenderer.removeListener(channel, listener);
validateIPC(channel);
return this;
}
ipcRenderer.removeListener(channel, listener);
return this;
}
},

View file

@ -42,7 +42,7 @@ export class AuxiliaryWindowsMainService implements IAuxiliaryWindowsMainService
createWindow(): BrowserWindowConstructorOptions {
return this.instantiationService.invokeFunction(defaultBrowserWindowOptions, undefined, {
webPreferences: {
preload: FileAccess.asFileUri('vs/base/parts/sandbox/electron-sandbox/preload-slim.js').fsPath
preload: FileAccess.asFileUri('vs/base/parts/sandbox/electron-sandbox/preload-aux.js').fsPath
}
});
}

View file

@ -5,7 +5,7 @@
import { getZoomLevel, setZoomFactor, setZoomLevel } from 'vs/base/browser/browser';
import { getWindows } from 'vs/base/browser/dom';
import { getGlobals } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { ISandboxGlobals, ipcRenderer, webFrame } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { zoomLevelToZoomFactor } from 'vs/platform/window/common/window';
/**
@ -20,6 +20,21 @@ export function applyZoom(zoomLevel: number): void {
setZoomLevel(zoomLevel);
}
function getGlobals(win: Window): ISandboxGlobals | undefined {
if (win === window) {
// main window
return { ipcRenderer, webFrame };
} else {
// auxiliary window
const auxiliaryWindow = win as unknown as { vscode: ISandboxGlobals };
if (auxiliaryWindow?.vscode?.ipcRenderer && auxiliaryWindow?.vscode?.webFrame) {
return auxiliaryWindow.vscode;
}
}
return undefined;
}
export function zoomIn(): void {
applyZoom(getZoomLevel() + 1);
}

View file

@ -64,7 +64,7 @@ export class CloseWindowAction extends Action2 {
const window = getActiveWindow();
if (isAuxiliaryWindow(window)) {
return nativeHostService.closeWindowById(await window.vscodeWindowId);
return nativeHostService.closeWindowById(window.vscodeWindowId);
}
return nativeHostService.closeWindow();
@ -368,7 +368,7 @@ export class ExperimentalSplitWindowAction extends Action2 {
let activeWindowId: number;
const activeWindow = getActiveWindow();
if (isAuxiliaryWindow(activeWindow)) {
activeWindowId = await activeWindow.vscodeWindowId;
activeWindowId = activeWindow.vscodeWindowId;
} else {
activeWindowId = environmentService.window.id;
}

View file

@ -6,23 +6,23 @@
import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { BrowserAuxiliaryWindowService, IAuxiliaryWindowService, AuxiliaryWindow as BaseAuxiliaryWindow } from 'vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService';
import { getGlobals } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { ISandboxGlobals } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWindowsConfiguration } from 'vs/platform/window/common/window';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { INativeHostService } from 'vs/platform/native/common/native';
import { DeferredPromise } from 'vs/base/common/async';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { getActiveWindow } from 'vs/base/browser/dom';
type AuxiliaryWindow = BaseAuxiliaryWindow & {
readonly vscodeWindowId: Promise<number>;
readonly vscode: ISandboxGlobals;
readonly vscodeWindowId: number;
};
export function isAuxiliaryWindow(obj: unknown): obj is AuxiliaryWindow {
const candidate = obj as AuxiliaryWindow | undefined;
return candidate?.vscodeWindowId instanceof Promise;
return !!candidate?.vscode && Object.hasOwn(candidate, 'vscodeWindowId');
}
export class NativeAuxiliaryWindowService extends BrowserAuxiliaryWindowService {
@ -41,7 +41,7 @@ export class NativeAuxiliaryWindowService extends BrowserAuxiliaryWindowService
// Zoom level
const windowConfig = this.configurationService.getValue<IWindowsConfiguration>();
const windowZoomLevel = typeof windowConfig.window?.zoomLevel === 'number' ? windowConfig.window.zoomLevel : 0;
getGlobals(auxiliaryWindow)?.webFrame?.setZoomLevel(windowZoomLevel);
auxiliaryWindow.vscode.webFrame.setZoomLevel(windowZoomLevel);
return super.create(auxiliaryWindow, disposables);
}
@ -50,17 +50,14 @@ export class NativeAuxiliaryWindowService extends BrowserAuxiliaryWindowService
super.patchMethods(auxiliaryWindow);
// Obtain window identifier
const windowId = new DeferredPromise<number>();
let resolvedWindowId: number;
(async () => {
windowId.complete(await getGlobals(auxiliaryWindow)?.ipcRenderer.invoke('vscode:getWindowId'));
resolvedWindowId = await auxiliaryWindow.vscode.ipcRenderer.invoke('vscode:getWindowId');
})();
// Add a `windowId` property
Object.defineProperty(auxiliaryWindow, 'vscodeWindowId', {
value: windowId.p,
writable: false,
enumerable: false,
configurable: false
get: () => resolvedWindowId
});
// Enable `window.focus()` to work in Electron by
@ -68,11 +65,11 @@ export class NativeAuxiliaryWindowService extends BrowserAuxiliaryWindowService
// https://github.com/electron/electron/issues/25578
const that = this;
const originalWindowFocus = auxiliaryWindow.focus.bind(auxiliaryWindow);
auxiliaryWindow.focus = async function () {
auxiliaryWindow.focus = function () {
originalWindowFocus();
if (getActiveWindow() !== auxiliaryWindow) {
that.nativeHostService.focusWindow({ targetWindowId: await windowId.p });
that.nativeHostService.focusWindow({ targetWindowId: resolvedWindowId });
}
};
}

View file

@ -138,7 +138,7 @@ class WorkbenchHostService extends Disposable implements IHostService {
return; // does not apply when only one window is opened
}
return this.nativeHostService.moveWindowTop(isAuxiliaryWindow(window) ? { targetWindowId: await window.vscodeWindowId } : undefined);
return this.nativeHostService.moveWindowTop(isAuxiliaryWindow(window) ? { targetWindowId: window.vscodeWindowId } : undefined);
}
//#endregion