Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/base/parts/contextmenu/electron-browser/contextmenu.ts
5251 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 { CONTEXT_MENU_CHANNEL, CONTEXT_MENU_CLOSE_CHANNEL, IContextMenuEvent, IContextMenuItem, IPopupOptions, ISerializableContextMenuItem } from '../common/contextmenu.js';
7
import { ipcRenderer } from '../../sandbox/electron-browser/globals.js';
8
9
let contextMenuIdPool = 0;
10
11
export function popup(items: IContextMenuItem[], options?: IPopupOptions, onHide?: () => void): void {
12
const processedItems: IContextMenuItem[] = [];
13
14
const contextMenuId = contextMenuIdPool++;
15
const onClickChannel = `vscode:onContextMenu${contextMenuId}`;
16
const onClickChannelHandler = (_event: unknown, ...args: unknown[]) => {
17
const itemId = args[0] as number;
18
const context = args[1] as IContextMenuEvent;
19
const item = processedItems[itemId];
20
item.click?.(context);
21
};
22
23
ipcRenderer.once(onClickChannel, onClickChannelHandler);
24
ipcRenderer.once(CONTEXT_MENU_CLOSE_CHANNEL, (_event: unknown, ...args: unknown[]) => {
25
const closedContextMenuId = args[0] as number;
26
if (closedContextMenuId !== contextMenuId) {
27
return;
28
}
29
30
ipcRenderer.removeListener(onClickChannel, onClickChannelHandler);
31
32
onHide?.();
33
});
34
35
ipcRenderer.send(CONTEXT_MENU_CHANNEL, contextMenuId, items.map(item => createItem(item, processedItems)), onClickChannel, options);
36
}
37
38
function createItem(item: IContextMenuItem, processedItems: IContextMenuItem[]): ISerializableContextMenuItem {
39
const serializableItem: ISerializableContextMenuItem = {
40
id: processedItems.length,
41
label: item.label,
42
type: item.type,
43
accelerator: item.accelerator,
44
checked: item.checked,
45
enabled: typeof item.enabled === 'boolean' ? item.enabled : true,
46
visible: typeof item.visible === 'boolean' ? item.visible : true
47
};
48
49
processedItems.push(item);
50
51
// Submenu
52
if (Array.isArray(item.submenu)) {
53
serializableItem.submenu = item.submenu.map(submenuItem => createItem(submenuItem, processedItems));
54
}
55
56
return serializableItem;
57
}
58
59