mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
Add WebGL acceleration and link handling to terminal (#205)
This PR adds back WebGL acceleration (enabled by default) for XTerm. It also adds back link handling and adds a new option (disabled by default) to open all links internally as a new web block. --------- Co-authored-by: sawka <mike.sawka@gmail.com>
This commit is contained in:
@@ -435,6 +435,20 @@ function isDev() {
|
||||
return cachedIsDev;
|
||||
}
|
||||
|
||||
async function openLink(uri: string) {
|
||||
if (globalStore.get(atoms.settingsConfigAtom)?.web?.openlinksinternally) {
|
||||
const blockDef: BlockDef = {
|
||||
meta: {
|
||||
view: "web",
|
||||
url: uri,
|
||||
},
|
||||
};
|
||||
await createBlock(blockDef);
|
||||
} else {
|
||||
getApi().openExternal(uri);
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
PLATFORM,
|
||||
WOS,
|
||||
@@ -451,6 +465,7 @@ export {
|
||||
initGlobal,
|
||||
initWS,
|
||||
isDev,
|
||||
openLink,
|
||||
sendWSCommand,
|
||||
setBlockFocus,
|
||||
setPlatform,
|
||||
|
||||
@@ -425,7 +425,7 @@ function TableBody({
|
||||
{
|
||||
label: "Open Preview in New Block",
|
||||
click: async () => {
|
||||
const blockDef = {
|
||||
const blockDef: BlockDef = {
|
||||
meta: {
|
||||
view: "preview",
|
||||
file: path,
|
||||
|
||||
@@ -9,14 +9,13 @@ import * as keyutil from "@/util/keyutil";
|
||||
import clsx from "clsx";
|
||||
import { produce } from "immer";
|
||||
import * as jotai from "jotai";
|
||||
import "public/xterm.css";
|
||||
import * as React from "react";
|
||||
import { TermStickers } from "./termsticker";
|
||||
import { TermThemeUpdater } from "./termtheme";
|
||||
import { computeTheme } from "./termutil";
|
||||
import { TermWrap } from "./termwrap";
|
||||
|
||||
import "public/xterm.css";
|
||||
|
||||
const keyMap = {
|
||||
Enter: "\r",
|
||||
Backspace: "\x7f",
|
||||
@@ -248,6 +247,7 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => {
|
||||
},
|
||||
{
|
||||
keydownHandler: handleTerminalKeydown,
|
||||
useWebGl: !termSettings?.disablewebgl,
|
||||
}
|
||||
);
|
||||
(window as any).term = termWrap;
|
||||
|
||||
@@ -2,15 +2,36 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { WshServer } from "@/app/store/wshserver";
|
||||
import { PLATFORM, fetchWaveFile, getFileSubject, sendWSCommand } from "@/store/global";
|
||||
import { PLATFORM, fetchWaveFile, getFileSubject, openLink, sendWSCommand } from "@/store/global";
|
||||
import * as services from "@/store/services";
|
||||
import { base64ToArray } from "@/util/util";
|
||||
import { base64ToArray, fireAndForget } from "@/util/util";
|
||||
import { SerializeAddon } from "@xterm/addon-serialize";
|
||||
import { WebLinksAddon } from "@xterm/addon-web-links";
|
||||
import { WebglAddon } from "@xterm/addon-webgl";
|
||||
import * as TermTypes from "@xterm/xterm";
|
||||
import { Terminal } from "@xterm/xterm";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import { FitAddon } from "./fitaddon";
|
||||
|
||||
// detect webgl support
|
||||
function detectWebGLSupport(): boolean {
|
||||
try {
|
||||
const canvas = document.createElement("canvas");
|
||||
const ctx = canvas.getContext("webgl");
|
||||
return !!ctx;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const WebGLSupported = detectWebGLSupport();
|
||||
let loggedWebGL = false;
|
||||
|
||||
type TermWrapOptions = {
|
||||
keydownHandler?: (e: KeyboardEvent) => void;
|
||||
useWebGl?: boolean;
|
||||
};
|
||||
|
||||
export class TermWrap {
|
||||
blockId: string;
|
||||
ptyOffset: number;
|
||||
@@ -30,7 +51,7 @@ export class TermWrap {
|
||||
blockId: string,
|
||||
connectElem: HTMLDivElement,
|
||||
options: TermTypes.ITerminalOptions & TermTypes.ITerminalInitOnlyOptions,
|
||||
waveOptions: { keydownHandler?: (e: KeyboardEvent) => void }
|
||||
waveOptions: TermWrapOptions
|
||||
) {
|
||||
this.blockId = blockId;
|
||||
this.ptyOffset = 0;
|
||||
@@ -41,6 +62,35 @@ export class TermWrap {
|
||||
this.serializeAddon = new SerializeAddon();
|
||||
this.terminal.loadAddon(this.fitAddon);
|
||||
this.terminal.loadAddon(this.serializeAddon);
|
||||
|
||||
this.terminal.loadAddon(
|
||||
new WebLinksAddon((e, uri) => {
|
||||
e.preventDefault();
|
||||
switch (PLATFORM) {
|
||||
case "darwin":
|
||||
if (e.metaKey) {
|
||||
fireAndForget(() => openLink(uri));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (e.ctrlKey) {
|
||||
fireAndForget(() => openLink(uri));
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
);
|
||||
if (WebGLSupported && waveOptions.useWebGl) {
|
||||
const webglAddon = new WebglAddon();
|
||||
webglAddon.onContextLoss(() => {
|
||||
webglAddon.dispose();
|
||||
});
|
||||
this.terminal.loadAddon(webglAddon);
|
||||
if (!loggedWebGL) {
|
||||
console.log("loaded webgl!");
|
||||
loggedWebGL = true;
|
||||
}
|
||||
}
|
||||
this.connectElem = connectElem;
|
||||
this.mainFileSubject = null;
|
||||
this.loaded = false;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { getApi } from "@/app/store/global";
|
||||
import { openLink } from "@/app/store/global";
|
||||
import { WOS, globalStore } from "@/store/global";
|
||||
import * as services from "@/store/services";
|
||||
import clsx from "clsx";
|
||||
@@ -336,7 +336,7 @@ const WebView = memo(({ parentRef, model }: WebViewProps) => {
|
||||
webview.addEventListener("new-window", (e: any) => {
|
||||
e.preventDefault();
|
||||
const newUrl = e.detail.url;
|
||||
getApi().openExternal(newUrl);
|
||||
openLink(newUrl);
|
||||
});
|
||||
|
||||
// Suppress errors
|
||||
|
||||
Reference in New Issue
Block a user