Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts
3296 views
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
import { IpcMainEvent, Menu, MenuItem } from 'electron';
7
import { validatedIpcMain } from '../../ipc/electron-main/ipcMain.js';
8
import { CONTEXT_MENU_CHANNEL, CONTEXT_MENU_CLOSE_CHANNEL, IPopupOptions, ISerializableContextMenuItem } from '../common/contextmenu.js';
9
10
export function registerContextMenuListener(): void {
11
validatedIpcMain.on(CONTEXT_MENU_CHANNEL, (event: IpcMainEvent, contextMenuId: number, items: ISerializableContextMenuItem[], onClickChannel: string, options?: IPopupOptions) => {
12
const menu = createMenu(event, onClickChannel, items);
13
14
menu.popup({
15
x: options ? options.x : undefined,
16
y: options ? options.y : undefined,
17
positioningItem: options ? options.positioningItem : undefined,
18
callback: () => {
19
// Workaround for https://github.com/microsoft/vscode/issues/72447
20
// It turns out that the menu gets GC'ed if not referenced anymore
21
// As such we drag it into this scope so that it is not being GC'ed
22
if (menu) {
23
event.sender.send(CONTEXT_MENU_CLOSE_CHANNEL, contextMenuId);
24
}
25
}
26
});
27
});
28
}
29
30
function createMenu(event: IpcMainEvent, onClickChannel: string, items: ISerializableContextMenuItem[]): Menu {
31
const menu = new Menu();
32
33
items.forEach(item => {
34
let menuitem: MenuItem;
35
36
// Separator
37
if (item.type === 'separator') {
38
menuitem = new MenuItem({
39
type: item.type,
40
});
41
}
42
43
// Sub Menu
44
else if (Array.isArray(item.submenu)) {
45
menuitem = new MenuItem({
46
submenu: createMenu(event, onClickChannel, item.submenu),
47
label: item.label
48
});
49
}
50
51
// Normal Menu Item
52
else {
53
menuitem = new MenuItem({
54
label: item.label,
55
type: item.type,
56
accelerator: item.accelerator,
57
checked: item.checked,
58
enabled: item.enabled,
59
visible: item.visible,
60
click: (menuItem, win, contextmenuEvent) => event.sender.send(onClickChannel, item.id, contextmenuEvent)
61
});
62
}
63
64
menu.append(menuitem);
65
});
66
67
return menu;
68
}
69
70