terminal context menu

This commit is contained in:
sawka
2024-06-19 15:42:33 -07:00
parent 58684744b0
commit 5c6cfbc112
4 changed files with 112 additions and 5 deletions
+26 -2
View File
@@ -2,7 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
import { Workspace } from "@/app/workspace/workspace";
import { atoms, globalStore } from "@/store/global";
import { atoms, getApi, globalStore } from "@/store/global";
import * as util from "@/util/util";
import * as jotai from "jotai";
import { Provider } from "jotai";
@@ -19,6 +20,29 @@ const App = () => {
);
};
function handleContextMenu(e: React.MouseEvent<HTMLDivElement>) {
let isInNonTermInput = false;
const activeElem = document.activeElement;
if (activeElem != null && activeElem.nodeName == "TEXTAREA") {
if (!activeElem.classList.contains("xterm-helper-textarea")) {
isInNonTermInput = true;
}
}
if (activeElem != null && activeElem.nodeName == "INPUT" && activeElem.getAttribute("type") == "text") {
isInNonTermInput = true;
}
const opts: ContextMenuOpts = {};
if (isInNonTermInput) {
opts.showCut = true;
}
const sel = window.getSelection();
if (!util.isBlank(sel?.toString()) || isInNonTermInput) {
getApi().contextEditMenu({ x: e.clientX, y: e.clientY }, opts);
} else {
getApi().contextEditMenu({ x: e.clientX, y: e.clientY }, { onlyPaste: true });
}
}
const AppInner = () => {
const client = jotai.useAtomValue(atoms.client);
const windowData = jotai.useAtomValue(atoms.waveWindow);
@@ -31,7 +55,7 @@ const AppInner = () => {
);
}
return (
<div className="mainapp">
<div className="mainapp" onContextMenu={handleContextMenu}>
<DndProvider backend={HTML5Backend}>
<div className="titlebar"></div>
<Workspace />
+25
View File
@@ -6,6 +6,11 @@ declare global {
blockId: string;
};
type ContextMenuOpts = {
showCut?: boolean;
onlyPaste?: boolean;
};
type ElectronApi = {
/**
* Determines whether the current app instance is a development build.
@@ -22,6 +27,26 @@ declare global {
* @returns A point value.
*/
getCursorPoint: () => Electron.Point;
contextEditMenu: (position: { x: number; y: number }, opts: ContextMenuOpts) => void;
showContextMenu: (menu: ElectronContextMenuItem[], position: { x: number; y: number }) => void;
onContextMenuClick: (callback: (id: string) => void) => void;
};
type ElectronContextMenuItem = {
id: string; // unique id, used for communication
label: string;
role?: string; // electron role (optional)
type?: "separator" | "normal" | "submenu";
submenu?: ElectronContextMenuItem[];
};
type ContextMenuItem = {
label?: string;
type?: "separator" | "normal" | "submenu";
role?: string; // electron role (optional)
click?: () => void; // not required if role is set
submenu?: ContextMenuItem[];
};
type SubjectWithRef<T> = rxjs.Subject<T> & { refCount: number; release: () => void };