add submenu support, add signal submenu to line context menu (#572)

This commit is contained in:
Mike Sawka 2024-04-11 10:57:14 -07:00 committed by GitHub
parent 15485d7235
commit d923de412a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 51 additions and 13 deletions

View File

@ -672,6 +672,7 @@ class LineCmd extends React.Component<
let { line, screen } = this.props; let { line, screen } = this.props;
const containerType = screen.getContainerType(); const containerType = screen.getContainerType();
const isMainContainer = containerType == appconst.LineContainer_Main; const isMainContainer = containerType == appconst.LineContainer_Main;
const cmd = screen.getCmd(line);
let menu: ContextMenuItem[] = [ let menu: ContextMenuItem[] = [
{ role: "copy", label: "Copy", type: "normal" }, { role: "copy", label: "Copy", type: "normal" },
{ role: "paste", label: "Paste", type: "normal" }, { role: "paste", label: "Paste", type: "normal" },
@ -697,6 +698,22 @@ class LineCmd extends React.Component<
click: () => GlobalCommandRunner.lineMinimize(line.lineid, true, true), click: () => GlobalCommandRunner.lineMinimize(line.lineid, true, true),
}); });
} }
if (cmd?.isRunning()) {
menu.push({ type: "separator" });
menu.push({
label: "Send Signal",
type: "submenu",
submenu: [
{ label: "SIGINT", click: () => GlobalCommandRunner.lineSignal(line.lineid, "SIGINT", true) },
{ label: "SIGTERM", click: () => GlobalCommandRunner.lineSignal(line.lineid, "SIGTERM", true) },
{ label: "SIGKILL", click: () => GlobalCommandRunner.lineSignal(line.lineid, "SIGKILL", true) },
{ type: "separator" },
{ label: "SIGUSR1", click: () => GlobalCommandRunner.lineSignal(line.lineid, "SIGUSR1", true) },
{ label: "SIGUSR2", click: () => GlobalCommandRunner.lineSignal(line.lineid, "SIGUSR2", true) },
],
});
}
menu.push({ type: "separator" }); menu.push({ type: "separator" });
menu.push({ label: "Restart Line", click: () => GlobalCommandRunner.lineRestart(line.lineid, true) }); menu.push({ label: "Restart Line", click: () => GlobalCommandRunner.lineRestart(line.lineid, true) });
menu.push({ type: "separator" }); menu.push({ type: "separator" });

View File

@ -470,23 +470,31 @@ electron.ipcMain.on("toggle-developer-tools", (event) => {
event.returnValue = true; event.returnValue = true;
}); });
electron.ipcMain.on("contextmenu-show", (event, menuDefArr, { x, y }) => { function convertMenuDefArrToMenu(menuDefArr: ElectronContextMenuItem[]): electron.Menu {
if (menuDefArr == null || menuDefArr.length == 0) { const menuItems: electron.MenuItem[] = [];
return;
}
const menu = new electron.Menu();
for (const menuDef of menuDefArr) { for (const menuDef of menuDefArr) {
const menuItemTemplate = { const menuItemTemplate: electron.MenuItemConstructorOptions = {
role: menuDef.role, role: menuDef.role as any,
label: menuDef.label, label: menuDef.label,
type: menuDef.type, type: menuDef.type,
click: () => { click: () => {
MainWindow?.webContents.send("contextmenu-click", menuDef.id); MainWindow?.webContents.send("contextmenu-click", menuDef.id);
}, },
}; };
if (menuDef.submenu != null) {
menuItemTemplate.submenu = convertMenuDefArrToMenu(menuDef.submenu);
}
const menuItem = new electron.MenuItem(menuItemTemplate); const menuItem = new electron.MenuItem(menuItemTemplate);
menu.append(menuItem); menuItems.push(menuItem);
} }
return electron.Menu.buildFromTemplate(menuItems);
}
electron.ipcMain.on("contextmenu-show", (event, menuDefArr: ElectronContextMenuItem[], { x, y }) => {
if (menuDefArr == null || menuDefArr.length == 0) {
return;
}
const menu = convertMenuDefArrToMenu(menuDefArr);
menu.popup({ x, y }); menu.popup({ x, y });
event.returnValue = true; event.returnValue = true;
}); });

View File

@ -86,6 +86,10 @@ class CommandRunner {
return GlobalModel.submitCommand("line", "restart", [lineArg], { nohist: "1" }, interactive); return GlobalModel.submitCommand("line", "restart", [lineArg], { nohist: "1" }, interactive);
} }
lineSignal(lineArg: string, signal: string, interactive: boolean): Promise<CommandRtnType> {
return GlobalModel.submitCommand("signal", null, [lineArg, signal], { nohist: "1" }, interactive);
}
lineSet(lineArg: string, opts: { renderer?: string }): Promise<CommandRtnType> { lineSet(lineArg: string, opts: { renderer?: string }): Promise<CommandRtnType> {
let kwargs = { nohist: "1" }; let kwargs = { nohist: "1" };
if ("renderer" in opts) { if ("renderer" in opts) {

View File

@ -20,8 +20,7 @@ class ContextMenuModel {
} }
} }
showContextMenu(menu: ContextMenuItem[], position: { x: number; y: number }): void { _convertAndRegisterMenu(menu: ContextMenuItem[]): ElectronContextMenuItem[] {
this.handlers.clear();
let electronMenuItems: ElectronContextMenuItem[] = []; let electronMenuItems: ElectronContextMenuItem[] = [];
for (let item of menu) { for (let item of menu) {
let electronItem: ElectronContextMenuItem = { let electronItem: ElectronContextMenuItem = {
@ -33,8 +32,17 @@ class ContextMenuModel {
if (item.click) { if (item.click) {
this.handlers.set(electronItem.id, item.click); this.handlers.set(electronItem.id, item.click);
} }
if (item.submenu) {
electronItem.submenu = this._convertAndRegisterMenu(item.submenu);
}
electronMenuItems.push(electronItem); electronMenuItems.push(electronItem);
} }
return electronMenuItems;
}
showContextMenu(menu: ContextMenuItem[], position: { x: number; y: number }): void {
this.handlers.clear();
const electronMenuItems = this._convertAndRegisterMenu(menu);
this.globalModel.getElectronApi().showContextMenu(electronMenuItems, position); this.globalModel.getElectronApi().showContextMenu(electronMenuItems, position);
} }
} }

View File

@ -954,15 +954,16 @@ declare global {
id: string; // unique id, used for communication id: string; // unique id, used for communication
label: string; label: string;
role?: string; // electron role (optional) role?: string; // electron role (optional)
type?: "separator" | "normal"; type?: "separator" | "normal" | "submenu";
submenu?: ElectronContextMenuItem[];
}; };
// possible to add support for submenus when needed
type ContextMenuItem = { type ContextMenuItem = {
label?: string; label?: string;
type?: "separator" | "normal"; type?: "separator" | "normal" | "submenu";
role?: string; // electron role (optional) role?: string; // electron role (optional)
click?: () => void; // not required if role is set click?: () => void; // not required if role is set
submenu?: ContextMenuItem[];
}; };
} }