Skip to content

Commit 8d72e84

Browse files
authored
Debt: avoid electron remote module (microsoft#57134)
* debt - avoid usages of electron remote module * debt - comment out remote & sendSync from electron.d.ts
1 parent 6e17ed2 commit 8d72e84

13 files changed

Lines changed: 281 additions & 106 deletions

File tree

src/typings/electron.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ declare namespace Electron {
104104
const powerMonitor: PowerMonitor;
105105
const powerSaveBlocker: PowerSaveBlocker;
106106
const protocol: Protocol;
107-
const remote: Remote;
107+
// const remote: Remote; ### VSCODE CHANGE (we do not want to use remote)
108108
const screen: Screen;
109109
type session = Session;
110110
const session: typeof Session;
@@ -2962,7 +2962,7 @@ declare namespace Electron {
29622962
* event.returnValue. Note: Sending a synchronous message will block the whole
29632963
* renderer process, unless you know what you are doing you should never use it.
29642964
*/
2965-
sendSync(channel: string, ...args: any[]): any;
2965+
// sendSync(channel: string, ...args: any[]): any; ### VSCODE CHANGE (we do not want to use sendSync)
29662966
/**
29672967
* Sends a message to a window with windowid via channel.
29682968
*/

src/vs/base/browser/contextmenu.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
1010
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
1111
import { SubmenuAction } from 'vs/base/browser/ui/menu/menu';
1212

13-
export interface IEvent {
13+
export interface IContextMenuEvent {
1414
shiftKey?: boolean;
1515
ctrlKey?: boolean;
1616
altKey?: boolean;
@@ -27,7 +27,7 @@ export interface IContextMenuDelegate {
2727
getAnchor(): HTMLElement | { x: number; y: number; };
2828
getActions(): TPromise<(IAction | ContextSubMenu)[]>;
2929
getActionItem?(action: IAction): IActionItem;
30-
getActionsContext?(event?: IEvent): any;
30+
getActionsContext?(event?: IContextMenuEvent): any;
3131
getKeyBinding?(action: IAction): ResolvedKeybinding;
3232
getMenuClassName?(): string;
3333
onHide?(didCancel: boolean): void;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
'use strict';
7+
8+
export interface ICommonContextMenuItem {
9+
label?: string;
10+
11+
type?: 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio';
12+
13+
accelerator?: string;
14+
15+
enabled?: boolean;
16+
visible?: boolean;
17+
checked?: boolean;
18+
}
19+
20+
export interface ISerializableContextMenuItem extends ICommonContextMenuItem {
21+
id: number;
22+
submenu?: ISerializableContextMenuItem[];
23+
}
24+
25+
export interface IContextMenuItem extends ICommonContextMenuItem {
26+
click?: (event: IContextMenuEvent) => void;
27+
submenu?: IContextMenuItem[];
28+
}
29+
30+
export interface IContextMenuEvent {
31+
shiftKey?: boolean;
32+
ctrlKey?: boolean;
33+
altKey?: boolean;
34+
metaKey?: boolean;
35+
}
36+
37+
export interface IPopupOptions {
38+
x?: number;
39+
y?: number;
40+
positioningItem?: number;
41+
onHide?: () => void;
42+
}
43+
44+
export const CONTEXT_MENU_CHANNEL = 'vscode:contextmenu';
45+
export const CONTEXT_MENU_CLOSE_CHANNEL = 'vscode:onCloseContextMenu';
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
'use strict';
7+
8+
import { ipcRenderer, Event } from 'electron';
9+
import { IContextMenuItem, ISerializableContextMenuItem, CONTEXT_MENU_CLOSE_CHANNEL, CONTEXT_MENU_CHANNEL, IPopupOptions, IContextMenuEvent } from 'vs/base/parts/contextmenu/common/contextmenu';
10+
11+
let onClickChannelIds = 0;
12+
13+
export function popup(items: IContextMenuItem[], options?: IPopupOptions): void {
14+
const processedItems: IContextMenuItem[] = [];
15+
16+
const onClickChannel = `vscode:onContextMenu${onClickChannelIds++}`;
17+
const onClickChannelHandler = (event: Event, itemId: number, context: IContextMenuEvent) => processedItems[itemId].click(context);
18+
19+
ipcRenderer.once(onClickChannel, onClickChannelHandler);
20+
ipcRenderer.once(CONTEXT_MENU_CLOSE_CHANNEL, () => {
21+
ipcRenderer.removeListener(onClickChannel, onClickChannelHandler);
22+
23+
if (options && options.onHide) {
24+
options.onHide();
25+
}
26+
});
27+
28+
ipcRenderer.send(CONTEXT_MENU_CHANNEL, items.map(item => createItem(item, processedItems)), onClickChannel, options);
29+
}
30+
31+
function createItem(item: IContextMenuItem, processedItems: IContextMenuItem[]): ISerializableContextMenuItem {
32+
const serializableItem = {
33+
id: processedItems.length,
34+
label: item.label,
35+
type: item.type,
36+
accelerator: item.accelerator,
37+
checked: item.checked,
38+
enabled: typeof item.enabled === 'boolean' ? item.enabled : true,
39+
visible: typeof item.visible === 'boolean' ? item.visible : true
40+
} as ISerializableContextMenuItem;
41+
42+
processedItems.push(item);
43+
44+
// Submenu
45+
if (Array.isArray(item.submenu)) {
46+
serializableItem.submenu = item.submenu.map(submenuItem => createItem(submenuItem, processedItems));
47+
}
48+
49+
return serializableItem;
50+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
'use strict';
7+
8+
import { Menu, MenuItem, BrowserWindow, Event, ipcMain } from 'electron';
9+
import { ISerializableContextMenuItem, CONTEXT_MENU_CLOSE_CHANNEL, CONTEXT_MENU_CHANNEL, IPopupOptions } from 'vs/base/parts/contextmenu/common/contextmenu';
10+
11+
export function registerContextMenuListener(): void {
12+
ipcMain.on(CONTEXT_MENU_CHANNEL, (event: Event, items: ISerializableContextMenuItem[], onClickChannel: string, options?: IPopupOptions) => {
13+
const menu = createMenu(event, onClickChannel, items);
14+
15+
menu.popup({
16+
window: BrowserWindow.fromWebContents(event.sender),
17+
x: options ? options.x : void 0,
18+
y: options ? options.y : void 0,
19+
positioningItem: options ? options.positioningItem : void 0,
20+
callback: () => {
21+
event.sender.send(CONTEXT_MENU_CLOSE_CHANNEL);
22+
}
23+
});
24+
});
25+
}
26+
27+
function createMenu(event: Event, onClickChannel: string, items: ISerializableContextMenuItem[]): Menu {
28+
const menu = new Menu();
29+
30+
items.forEach(item => {
31+
let menuitem: MenuItem;
32+
33+
// Separator
34+
if (item.type === 'separator') {
35+
menuitem = new MenuItem({
36+
type: item.type,
37+
});
38+
}
39+
40+
// Sub Menu
41+
else if (Array.isArray(item.submenu)) {
42+
menuitem = new MenuItem({
43+
submenu: createMenu(event, onClickChannel, item.submenu),
44+
label: item.label
45+
});
46+
}
47+
48+
// Normal Menu Item
49+
else {
50+
menuitem = new MenuItem({
51+
label: item.label,
52+
type: item.type,
53+
accelerator: item.accelerator,
54+
checked: item.checked,
55+
enabled: item.enabled,
56+
visible: item.visible,
57+
click: (menuItem, win, contextmenuEvent) => event.sender.send(onClickChannel, item.id, contextmenuEvent)
58+
});
59+
}
60+
61+
menu.append(menuitem);
62+
});
63+
64+
return menu;
65+
}

src/vs/code/electron-browser/processExplorer/processExplorerMain.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@
77

88
import 'vs/css!./media/processExplorer';
99
import { listProcesses, ProcessItem } from 'vs/base/node/ps';
10-
import { remote, webFrame, ipcRenderer, clipboard } from 'electron';
10+
import { webFrame, ipcRenderer, clipboard } from 'electron';
1111
import { repeat } from 'vs/base/common/strings';
1212
import { totalmem } from 'os';
1313
import product from 'vs/platform/node/product';
1414
import { localize } from 'vs/nls';
1515
import { ProcessExplorerStyles, ProcessExplorerData } from 'vs/platform/issue/common/issue';
1616
import * as browser from 'vs/base/browser/browser';
1717
import * as platform from 'vs/base/common/platform';
18+
import { IContextMenuItem } from 'vs/base/parts/contextmenu/common/contextmenu';
19+
import { popup } from 'vs/base/parts/contextmenu/electron-browser/contextmenu';
1820

1921
let processList: any[];
2022
let mapPidToWindowTitle = new Map<number, string>();
@@ -137,60 +139,60 @@ function applyZoom(zoomLevel: number): void {
137139
function showContextMenu(e) {
138140
e.preventDefault();
139141

140-
const menu = new remote.Menu();
142+
const items: IContextMenuItem[] = [];
141143

142144
const pid = parseInt(e.currentTarget.id);
143145
if (pid && typeof pid === 'number') {
144-
menu.append(new remote.MenuItem({
146+
items.push({
145147
label: localize('killProcess', "Kill Process"),
146148
click() {
147149
process.kill(pid, 'SIGTERM');
148150
}
149-
}));
151+
});
150152

151-
menu.append(new remote.MenuItem({
153+
items.push({
152154
label: localize('forceKillProcess', "Force Kill Process"),
153155
click() {
154156
process.kill(pid, 'SIGKILL');
155157
}
156-
}));
158+
});
157159

158-
menu.append(new remote.MenuItem({
160+
items.push({
159161
type: 'separator'
160-
}));
162+
});
161163

162-
menu.append(new remote.MenuItem({
164+
items.push({
163165
label: localize('copy', "Copy"),
164166
click() {
165167
const row = document.getElementById(pid.toString());
166168
if (row) {
167169
clipboard.writeText(row.innerText);
168170
}
169171
}
170-
}));
172+
});
171173

172-
menu.append(new remote.MenuItem({
174+
items.push({
173175
label: localize('copyAll', "Copy All"),
174176
click() {
175177
const processList = document.getElementById('process-list');
176178
if (processList) {
177179
clipboard.writeText(processList.innerText);
178180
}
179181
}
180-
}));
182+
});
181183
} else {
182-
menu.append(new remote.MenuItem({
184+
items.push({
183185
label: localize('copyAll', "Copy All"),
184186
click() {
185187
const processList = document.getElementById('process-list');
186188
if (processList) {
187189
clipboard.writeText(processList.innerText);
188190
}
189191
}
190-
}));
192+
});
191193
}
192194

193-
menu.popup({ window: remote.getCurrentWindow() });
195+
popup(items);
194196
}
195197

196198
export function startup(data: ProcessExplorerData): void {
@@ -206,7 +208,7 @@ export function startup(data: ProcessExplorerData): void {
206208
setInterval(() => {
207209
ipcRenderer.send('windowsInfoRequest');
208210

209-
listProcesses(remote.process.pid).then(processes => {
211+
listProcesses(data.pid).then(processes => {
210212
processList = getProcessList(processes);
211213
updateProcessInfo(processList);
212214

src/vs/code/electron-main/app.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import { ILabelService } from 'vs/platform/label/common/label';
6767
import { CodeMenu } from 'vs/code/electron-main/menus';
6868
import { hasArgs } from 'vs/platform/environment/node/argv';
6969
import { RunOnceScheduler } from 'vs/base/common/async';
70+
import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu';
7071

7172
export class CodeApplication {
7273

@@ -104,6 +105,9 @@ export class CodeApplication {
104105
process.on('uncaughtException', err => this.onUnexpectedError(err));
105106
process.on('unhandledRejection', (reason: any, promise: Promise<any>) => errors.onUnexpectedError(reason));
106107

108+
// Contextmenu via IPC support
109+
registerContextMenuListener();
110+
107111
app.on('will-quit', () => {
108112
this.logService.trace('App#will-quit: disposing resources');
109113

src/vs/code/electron-main/windows.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,7 @@ export class WindowsManager implements IWindowsMainService {
11821182
const configuration: IWindowConfiguration = mixin({}, options.cli); // inherit all properties from CLI
11831183
configuration.appRoot = this.environmentService.appRoot;
11841184
configuration.machineId = this.machineId;
1185+
configuration.mainPid = process.pid;
11851186
configuration.execPath = process.execPath;
11861187
configuration.userEnv = assign({}, this.initialUserEnv, options.userEnv || {});
11871188
configuration.isInitialStartup = options.initialStartup;

src/vs/platform/driver/electron-browser/driver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class WindowDriver implements IWindowDriver {
8686
private _click(selector: string, clickCount: number, xoffset?: number, yoffset?: number): TPromise<void> {
8787
return this._getElementXY(selector, xoffset, yoffset).then(({ x, y }) => {
8888

89-
const webContents = electron.remote.getCurrentWebContents();
89+
const webContents: electron.WebContents = (electron as any).remote.getCurrentWebContents();
9090
webContents.sendInputEvent({ type: 'mouseDown', x, y, button: 'left', clickCount } as any);
9191

9292
return TPromise.timeout(10).then(() => {

src/vs/platform/issue/common/issue.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export interface ProcessExplorerStyles extends WindowStyles {
7474
}
7575

7676
export interface ProcessExplorerData extends WindowData {
77+
pid: number;
7778
styles: ProcessExplorerStyles;
7879
}
7980

0 commit comments

Comments
 (0)