Path: blob/main/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts
3296 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 { IpcMainEvent, Menu, MenuItem } from 'electron';6import { validatedIpcMain } from '../../ipc/electron-main/ipcMain.js';7import { CONTEXT_MENU_CHANNEL, CONTEXT_MENU_CLOSE_CHANNEL, IPopupOptions, ISerializableContextMenuItem } from '../common/contextmenu.js';89export function registerContextMenuListener(): void {10validatedIpcMain.on(CONTEXT_MENU_CHANNEL, (event: IpcMainEvent, contextMenuId: number, items: ISerializableContextMenuItem[], onClickChannel: string, options?: IPopupOptions) => {11const menu = createMenu(event, onClickChannel, items);1213menu.popup({14x: options ? options.x : undefined,15y: options ? options.y : undefined,16positioningItem: options ? options.positioningItem : undefined,17callback: () => {18// Workaround for https://github.com/microsoft/vscode/issues/7244719// It turns out that the menu gets GC'ed if not referenced anymore20// As such we drag it into this scope so that it is not being GC'ed21if (menu) {22event.sender.send(CONTEXT_MENU_CLOSE_CHANNEL, contextMenuId);23}24}25});26});27}2829function createMenu(event: IpcMainEvent, onClickChannel: string, items: ISerializableContextMenuItem[]): Menu {30const menu = new Menu();3132items.forEach(item => {33let menuitem: MenuItem;3435// Separator36if (item.type === 'separator') {37menuitem = new MenuItem({38type: item.type,39});40}4142// Sub Menu43else if (Array.isArray(item.submenu)) {44menuitem = new MenuItem({45submenu: createMenu(event, onClickChannel, item.submenu),46label: item.label47});48}4950// Normal Menu Item51else {52menuitem = new MenuItem({53label: item.label,54type: item.type,55accelerator: item.accelerator,56checked: item.checked,57enabled: item.enabled,58visible: item.visible,59click: (menuItem, win, contextmenuEvent) => event.sender.send(onClickChannel, item.id, contextmenuEvent)60});61}6263menu.append(menuitem);64});6566return menu;67}686970