Path: blob/main/src/vs/base/parts/contextmenu/electron-browser/contextmenu.ts
5251 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { CONTEXT_MENU_CHANNEL, CONTEXT_MENU_CLOSE_CHANNEL, IContextMenuEvent, IContextMenuItem, IPopupOptions, ISerializableContextMenuItem } from '../common/contextmenu.js';6import { ipcRenderer } from '../../sandbox/electron-browser/globals.js';78let contextMenuIdPool = 0;910export function popup(items: IContextMenuItem[], options?: IPopupOptions, onHide?: () => void): void {11const processedItems: IContextMenuItem[] = [];1213const contextMenuId = contextMenuIdPool++;14const onClickChannel = `vscode:onContextMenu${contextMenuId}`;15const onClickChannelHandler = (_event: unknown, ...args: unknown[]) => {16const itemId = args[0] as number;17const context = args[1] as IContextMenuEvent;18const item = processedItems[itemId];19item.click?.(context);20};2122ipcRenderer.once(onClickChannel, onClickChannelHandler);23ipcRenderer.once(CONTEXT_MENU_CLOSE_CHANNEL, (_event: unknown, ...args: unknown[]) => {24const closedContextMenuId = args[0] as number;25if (closedContextMenuId !== contextMenuId) {26return;27}2829ipcRenderer.removeListener(onClickChannel, onClickChannelHandler);3031onHide?.();32});3334ipcRenderer.send(CONTEXT_MENU_CHANNEL, contextMenuId, items.map(item => createItem(item, processedItems)), onClickChannel, options);35}3637function createItem(item: IContextMenuItem, processedItems: IContextMenuItem[]): ISerializableContextMenuItem {38const serializableItem: ISerializableContextMenuItem = {39id: processedItems.length,40label: item.label,41type: item.type,42accelerator: item.accelerator,43checked: item.checked,44enabled: typeof item.enabled === 'boolean' ? item.enabled : true,45visible: typeof item.visible === 'boolean' ? item.visible : true46};4748processedItems.push(item);4950// Submenu51if (Array.isArray(item.submenu)) {52serializableItem.submenu = item.submenu.map(submenuItem => createItem(submenuItem, processedItems));53}5455return serializableItem;56}575859