Skip to content

Commit

Permalink
Merge pull request microsoft#195326 from microsoft/ben/husky-bison
Browse files Browse the repository at this point in the history
Some editors and aux window fixes
  • Loading branch information
bpasero authored and Alex0007 committed Oct 26, 2023
2 parents 4c3e437 + 949dc44 commit 54dd6f9
Show file tree
Hide file tree
Showing 24 changed files with 385 additions and 246 deletions.
4 changes: 2 additions & 2 deletions src/vs/base/parts/sandbox/electron-sandbox/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export const process: ISandboxNodeProcess = globals.vscode.process;
export const context: ISandboxContext = globals.vscode.context;

export interface IGlobalsSlim {
readonly ipcRenderer: Pick<import('vs/base/parts/sandbox/electron-sandbox/electronTypes').IpcRenderer, 'send'>;
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;
}

Expand All @@ -138,7 +138,7 @@ export function getGlobals(win: Window): IGlobalsSlim | undefined {

const auxiliaryWindowCandidate = win as unknown as {
vscode: {
ipcRenderer: Pick<import('vs/base/parts/sandbox/electron-sandbox/electronTypes').IpcRenderer, 'send'>;
ipcRenderer: Pick<import('vs/base/parts/sandbox/electron-sandbox/electronTypes').IpcRenderer, 'send' | 'invoke'>;
webFrame: import('vs/base/parts/sandbox/electron-sandbox/electronTypes').WebFrame;
};
};
Expand Down
13 changes: 12 additions & 1 deletion src/vs/base/parts/sandbox/electron-sandbox/preload-slim.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
* A minimal set of methods exposed from Electron's `ipcRenderer`
* to support communication to main process.
*
* @typedef {Pick<import('./electronTypes').IpcRenderer, 'send'>} IpcRenderer
* @typedef {Pick<import('./electronTypes').IpcRenderer, 'send' | 'invoke'>} IpcRenderer
*
* @type {IpcRenderer}
*/
Expand All @@ -41,6 +41,17 @@
if (validateIPC(channel)) {
ipcRenderer.send(channel, ...args);
}
},

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

Expand Down
12 changes: 9 additions & 3 deletions src/vs/code/electron-main/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ import { ElectronPtyHostStarter } from 'vs/platform/terminal/electron-main/elect
import { PtyHostService } from 'vs/platform/terminal/node/ptyHostService';
import { NODE_REMOTE_RESOURCE_CHANNEL_NAME, NODE_REMOTE_RESOURCE_IPC_METHOD_NAME, NodeRemoteResourceResponse, NodeRemoteResourceRouter } from 'vs/platform/remote/common/electronRemoteResources';
import { Lazy } from 'vs/base/common/lazy';
import { AuxiliaryWindow } from 'vs/platform/windows/electron-main/auxiliaryWindow';
import { IAuxiliaryWindowsMainService } from 'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindows';
import { AuxiliaryWindowsMainService } from 'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindowsMainService';

/**
* The main VS Code application. There will only ever be one instance,
Expand All @@ -132,6 +133,7 @@ export class CodeApplication extends Disposable {
};

private windowsMainService: IWindowsMainService | undefined;
private auxiliaryWindowsMainService: IAuxiliaryWindowsMainService | undefined;
private nativeHostMainService: INativeHostMainService | undefined;

constructor(
Expand Down Expand Up @@ -386,7 +388,7 @@ export class CodeApplication extends Disposable {
// Child Window: delegate to `AuxiliaryWindow` class
const isChildWindow = contents?.opener?.url.startsWith(`${Schemas.vscodeFileResource}://${VSCODE_AUTHORITY}/`);
if (isChildWindow) {
this.mainInstantiationService.createInstance(AuxiliaryWindow, contents);
this.auxiliaryWindowsMainService?.registerWindow(contents);
}

// Block any in-page navigation
Expand All @@ -406,7 +408,7 @@ export class CodeApplication extends Disposable {

return {
action: 'allow',
overrideBrowserWindowOptions: AuxiliaryWindow.open(this.mainInstantiationService)
overrideBrowserWindowOptions: this.auxiliaryWindowsMainService?.createWindow()
};
}

Expand Down Expand Up @@ -459,6 +461,8 @@ export class CodeApplication extends Disposable {

//#region Bootstrap IPC Handlers

validatedIpcMain.handle('vscode:getWindowId', event => Promise.resolve(event.sender.id));

validatedIpcMain.handle('vscode:fetchShellEnv', event => {

// Prefer to use the args and env from the target window
Expand Down Expand Up @@ -992,6 +996,7 @@ export class CodeApplication extends Disposable {

// Windows
services.set(IWindowsMainService, new SyncDescriptor(WindowsMainService, [machineId, this.userEnv], false));
services.set(IAuxiliaryWindowsMainService, new SyncDescriptor(AuxiliaryWindowsMainService, undefined, false));

// Dialogs
const dialogMainService = new DialogMainService(this.logService, this.productService);
Expand Down Expand Up @@ -1210,6 +1215,7 @@ export class CodeApplication extends Disposable {

private async openFirstWindow(accessor: ServicesAccessor, initialProtocolUrls: IInitialProtocolUrls | undefined): Promise<ICodeWindow[]> {
const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService);
this.auxiliaryWindowsMainService = accessor.get(IAuxiliaryWindowsMainService);

const context = isLaunchedFromCli(process.env) ? OpenContext.CLI : OpenContext.DESKTOP;
const args = this.environmentMainService.args;
Expand Down
71 changes: 71 additions & 0 deletions src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { BrowserWindow, WebContents } from 'electron';
import { Emitter, Event } from 'vs/base/common/event';
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
import { BaseWindow } from 'vs/platform/windows/electron-main/windowImpl';

export interface IAuxiliaryWindow {

readonly onDidClose: Event<void>;

readonly id: number;
readonly win: BrowserWindow | null;

focus(options?: { force: boolean }): void;
}

export class AuxiliaryWindow extends BaseWindow implements IAuxiliaryWindow {

readonly id = this.contents.id;

private readonly _onDidClose = this._register(new Emitter<void>());
readonly onDidClose = this._onDidClose.event;

private _win: BrowserWindow | null = null;
get win() {
if (!this._win) {
const window = BrowserWindow.fromWebContents(this.contents);
if (window) {
this._win = window;
this.registerWindowListeners(window);
}
}

return this._win;
}

protected getWin(): BrowserWindow | null {
return this.win;
}

constructor(
private readonly contents: WebContents,
@IEnvironmentMainService private readonly environmentMainService: IEnvironmentMainService
) {
super();

this.create();
}

private create(): void {

// Handle devtools argument
if (this.environmentMainService.args['open-devtools'] === true) {
this.contents.openDevTools({ mode: 'bottom' });
}
}

private registerWindowListeners(window: BrowserWindow): void {

// Window close
window.on('closed', () => {
this._onDidClose.fire();

this.dispose();
});
}
}
21 changes: 21 additions & 0 deletions src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindows.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { BrowserWindowConstructorOptions, WebContents } from 'electron';
import { IAuxiliaryWindow } from 'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindow';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';

export const IAuxiliaryWindowsMainService = createDecorator<IAuxiliaryWindowsMainService>('auxiliaryWindowsMainService');

export interface IAuxiliaryWindowsMainService {

readonly _serviceBrand: undefined;

createWindow(): BrowserWindowConstructorOptions;
registerWindow(webContents: WebContents): void;

getWindowById(windowId: number): IAuxiliaryWindow | undefined;
getFocusedWindow(): IAuxiliaryWindow | undefined;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { BrowserWindow, BrowserWindowConstructorOptions, WebContents } from 'electron';
import { Event } from 'vs/base/common/event';
import { FileAccess } from 'vs/base/common/network';
import { AuxiliaryWindow, IAuxiliaryWindow } from 'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindow';
import { IAuxiliaryWindowsMainService } from 'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindows';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { defaultBrowserWindowOptions } from 'vs/platform/windows/electron-main/windows';

export class AuxiliaryWindowsMainService implements IAuxiliaryWindowsMainService {

declare readonly _serviceBrand: undefined;

private readonly windows = new Map<number, IAuxiliaryWindow>();

constructor(
@IInstantiationService private readonly instantiationService: IInstantiationService
) { }

createWindow(): BrowserWindowConstructorOptions {
return this.instantiationService.invokeFunction(defaultBrowserWindowOptions, undefined, {
webPreferences: {
preload: FileAccess.asFileUri('vs/base/parts/sandbox/electron-sandbox/preload-slim.js').fsPath
}
});
}

registerWindow(webContents: WebContents): void {
const auxiliaryWindow = this.instantiationService.createInstance(AuxiliaryWindow, webContents);
this.windows.set(auxiliaryWindow.id, auxiliaryWindow);

Event.once(auxiliaryWindow.onDidClose)(() => this.windows.delete(auxiliaryWindow.id));
}

getWindowById(windowId: number): IAuxiliaryWindow | undefined {
return this.windows.get(windowId);
}

getFocusedWindow(): IAuxiliaryWindow | undefined {
const window = BrowserWindow.getFocusedWindow();
if (window) {
return this.getWindowById(window.id);
}

return undefined;
}
}
4 changes: 2 additions & 2 deletions src/vs/platform/native/common/native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export interface ICommonNativeHostService {
maximizeWindow(): Promise<void>;
unmaximizeWindow(): Promise<void>;
minimizeWindow(): Promise<void>;
moveWindowTop(): Promise<void>;
moveWindowTop(options?: { targetWindowId?: number }): Promise<void>;

/**
* Only supported on Windows and macOS. Updates the window controls to match the title bar size.
Expand All @@ -96,7 +96,7 @@ export interface ICommonNativeHostService {
* should only be used if it is necessary to steal focus from the current
* focused application which may not be VSCode.
*/
focusWindow(options?: { windowId?: number; force?: boolean }): Promise<void>;
focusWindow(options?: { targetWindowId?: number; force?: boolean }): Promise<void>;

// Dialogs
showMessageBox(options: MessageBoxOptions): Promise<MessageBoxReturnValue>;
Expand Down

0 comments on commit 54dd6f9

Please sign in to comment.