未验证 提交 5684336d 编写于 作者: M Matt Bierner 提交者: GitHub

Move webview's use of setIgnoreMenuShortcuts to main process (#98131)

* Move webview's use of setIgnoreMenuShortcuts to main processes

Part of #95955

Switches from calling `setIgnoreMenuShortcuts` on the renderer to calling it on the main thread

* Use channels for communication instead of ipc

* Cleanup ipc implementation

* Rename webviewMainService -> WebviewManagerService
上级 f29b61dd
......@@ -80,6 +80,9 @@ import { INativeEnvironmentService } from 'vs/platform/environment/node/environm
import { mnemonicButtonLabel, getPathLabel } from 'vs/base/common/labels';
import { IFileService } from 'vs/platform/files/common/files';
import { WebviewProtocolProvider } from 'vs/platform/webview/electron-main/webviewProtocolProvider';
import { WebviewChannel } from 'vs/platform/webview/electron-main/webviewIpcs';
import { WebviewMainService } from 'vs/platform/webview/electron-main/webviewMainService';
import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService';
export class CodeApplication extends Disposable {
private windowsMainService: IWindowsMainService | undefined;
......@@ -471,6 +474,7 @@ export class CodeApplication extends Disposable {
services.set(IIssueMainService, new SyncDescriptor(IssueMainService, [machineId, this.userEnv]));
services.set(IElectronMainService, new SyncDescriptor(ElectronMainService));
services.set(IWebviewManagerService, new SyncDescriptor(WebviewMainService));
services.set(IWorkspacesService, new SyncDescriptor(WorkspacesService));
services.set(IMenubarMainService, new SyncDescriptor(MenubarMainService));
......@@ -578,6 +582,10 @@ export class CodeApplication extends Disposable {
const urlChannel = createChannelReceiver(urlService);
electronIpcServer.registerChannel('url', urlChannel);
const webviewManagerService = accessor.get(IWebviewManagerService);
const webviewChannel = new WebviewChannel(webviewManagerService);
electronIpcServer.registerChannel('webview', webviewChannel);
const storageMainService = accessor.get(IStorageMainService);
const storageChannel = this._register(new GlobalStorageDatabaseChannel(this.logService, storageMainService));
electronIpcServer.registerChannel('storage', storageChannel);
......
/*---------------------------------------------------------------------------------------------
* 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';
export const IWebviewManagerService = createDecorator<IWebviewManagerService>('webviewManagerService');
export interface IWebviewManagerService {
_serviceBrand: unknown;
setIgnoreMenuShortcuts(webContentsId: number, enabled: boolean): void;
}
/*---------------------------------------------------------------------------------------------
* 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';
import { IServerChannel } from 'vs/base/parts/ipc/common/ipc';
import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService';
export class WebviewChannel implements IServerChannel {
constructor(
@IWebviewManagerService private readonly webviewMainService: IWebviewManagerService,
) { }
listen(_: unknown, event: string): Event<any> {
throw new Error(`Event not found: ${event}`);
}
async call(_: unknown, command: string, arg?: any): Promise<any> {
switch (command) {
case 'setIgnoreMenuShortcuts': this.webviewMainService.setIgnoreMenuShortcuts(arg[0], arg[1]); return;
}
throw new Error(`Call not found: ${command}`);
}
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { webContents } from 'electron';
import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService';
export class WebviewMainService implements IWebviewManagerService {
_serviceBrand: undefined;
public setIgnoreMenuShortcuts(webContentsId: number, enabled: boolean): void {
const contents = webContents.fromId(webContentsId);
if (!contents) {
throw new Error(`Invalid webContentsId: ${webContentsId}`);
}
if (!contents.isDestroyed()) {
contents.setIgnoreMenuShortcuts(enabled);
}
}
}
......@@ -6,6 +6,7 @@
import { FindInPageOptions, OnBeforeRequestListenerDetails, OnHeadersReceivedListenerDetails, Response, WebContents, WebviewTag } from 'electron';
import { ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { addDisposableListener } from 'vs/base/browser/dom';
import { equals } from 'vs/base/common/arrays';
import { ThrottledDelayer } from 'vs/base/common/async';
import { Emitter, Event } from 'vs/base/common/event';
import { once } from 'vs/base/common/functional';
......@@ -26,8 +27,9 @@ import { WebviewPortMappingManager } from 'vs/workbench/contrib/webview/common/p
import { WebviewThemeDataProvider } from 'vs/workbench/contrib/webview/common/themeing';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { WebviewFindDelegate, WebviewFindWidget } from '../browser/webviewFindWidget';
import { equals } from 'vs/base/common/arrays';
import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService';
import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService';
import { createChannelSender } from 'vs/base/parts/ipc/common/ipc';
class WebviewTagHandle extends Disposable {
......@@ -185,26 +187,30 @@ class WebviewPortMappingProvider extends Disposable {
class WebviewKeyboardHandler {
private readonly _webviews = new Set<WebviewTagHandle>();
private readonly _webviews = new Set<WebviewTag>();
private readonly _isUsingNativeTitleBars: boolean;
constructor(configurationService: IConfigurationService) {
private readonly webviewMainService: IWebviewManagerService;
constructor(
configurationService: IConfigurationService,
mainProcessService: IMainProcessService,
) {
this._isUsingNativeTitleBars = configurationService.getValue<string>('window.titleBarStyle') === 'native';
this.webviewMainService = createChannelSender<IWebviewManagerService>(mainProcessService.getChannel('webview'));
}
public add(
webviewHandle: WebviewTagHandle,
): IDisposable {
this._webviews.add(webviewHandle);
public add(webview: WebviewTag): IDisposable {
this._webviews.add(webview);
const disposables = new DisposableStore();
if (this.shouldToggleMenuShortcutsEnablement) {
disposables.add(webviewHandle.onFirstLoad(() => {
this.setIgnoreMenuShortcutsForWebview(webviewHandle, true);
}));
this.setIgnoreMenuShortcutsForWebview(webview, true);
}
disposables.add(addDisposableListener(webviewHandle.webview, 'ipc-message', (event) => {
disposables.add(addDisposableListener(webview, 'ipc-message', (event) => {
switch (event.channel) {
case 'did-focus':
this.setIgnoreMenuShortcuts(true);
......@@ -218,7 +224,7 @@ class WebviewKeyboardHandler {
return toDisposable(() => {
disposables.dispose();
this._webviews.delete(webviewHandle);
this._webviews.delete(webview);
});
}
......@@ -232,12 +238,9 @@ class WebviewKeyboardHandler {
}
}
private setIgnoreMenuShortcutsForWebview(webview: WebviewTagHandle, value: boolean) {
private setIgnoreMenuShortcutsForWebview(webview: WebviewTag, value: boolean) {
if (this.shouldToggleMenuShortcutsEnablement) {
const contents = webview.webContents;
if (!contents?.isDestroyed()) {
contents?.setIgnoreMenuShortcuts(value);
}
this.webviewMainService.setIgnoreMenuShortcuts(webview.getWebContentsId(), value);
}
}
}
......@@ -246,9 +249,12 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
private static _webviewKeyboardHandler: WebviewKeyboardHandler | undefined;
private static getWebviewKeyboardHandler(configService: IConfigurationService) {
private static getWebviewKeyboardHandler(
configService: IConfigurationService,
mainProcessService: IMainProcessService,
) {
if (!this._webviewKeyboardHandler) {
this._webviewKeyboardHandler = new WebviewKeyboardHandler(configService);
this._webviewKeyboardHandler = new WebviewKeyboardHandler(configService, mainProcessService);
}
return this._webviewKeyboardHandler;
}
......@@ -276,6 +282,7 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
@IEnvironmentService environementService: IEnvironmentService,
@IWorkbenchEnvironmentService workbenchEnvironmentService: IWorkbenchEnvironmentService,
@IConfigurationService configurationService: IConfigurationService,
@IMainProcessService mainProcessService: IMainProcessService,
) {
super(id, options, contentOptions, extension, _webviewThemeDataProvider, telemetryService, environementService, workbenchEnvironmentService);
......@@ -291,7 +298,9 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
tunnelService,
));
this._register(ElectronWebviewBasedWebview.getWebviewKeyboardHandler(configurationService).add(webviewAndContents));
this._register(addDisposableListener(this.element!, 'did-start-loading', once(() => {
this._register(ElectronWebviewBasedWebview.getWebviewKeyboardHandler(configurationService, mainProcessService).add(this.element!));
})));
this._domReady = new Promise(resolve => {
const subscription = this._register(this.on(WebviewMessageChannels.webviewReady, () => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册