mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
terminal context menu
This commit is contained in:
+26
-2
@@ -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 />
|
||||
|
||||
Vendored
+25
@@ -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 };
|
||||
|
||||
Reference in New Issue
Block a user