From 2def841f1b784a0c325028c896e49a046c60c0aa Mon Sep 17 00:00:00 2001 From: Will Chen Date: Thu, 9 Oct 2025 13:36:44 -0700 Subject: [PATCH] Context menu (right-click copy, paste, etc.) (#1492) --- src/main.ts | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 8052e8f..8a0f1ca 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import { app, BrowserWindow, dialog } from "electron"; +import { app, BrowserWindow, dialog, Menu } from "electron"; import * as path from "node:path"; import { registerIpcHandlers } from "./ipc/ipc_host"; import dotenv from "dotenv"; @@ -163,6 +163,47 @@ const createWindow = () => { // Open the DevTools. mainWindow.webContents.openDevTools(); } + + // Enable native context menu on right-click + mainWindow.webContents.on("context-menu", (event, params) => { + // Prevent any default behavior and show our own menu + event.preventDefault(); + + const template: Electron.MenuItemConstructorOptions[] = []; + + if (params.isEditable) { + template.push( + { role: "undo" }, + { role: "redo" }, + { type: "separator" }, + { role: "cut" }, + { role: "copy" }, + { role: "paste" }, + { role: "delete" }, + { type: "separator" }, + { role: "selectAll" }, + ); + } else { + if (params.selectionText && params.selectionText.length > 0) { + template.push({ role: "copy" }); + } + template.push({ role: "selectAll" }); + } + + if (process.env.NODE_ENV === "development") { + template.push( + { type: "separator" }, + { + label: "Inspect Element", + click: () => + mainWindow?.webContents.inspectElement(params.x, params.y), + }, + ); + } + + const menu = Menu.buildFromTemplate(template); + menu.popup({ window: mainWindow! }); + }); }; const gotTheLock = app.requestSingleInstanceLock();