From ef5be896438dc5c7668da8d86f6d3cd2e84a23ad Mon Sep 17 00:00:00 2001 From: bluebluesoda <300733005+bluebluesoda@users.noreply.github.com> Date: Sat, 26 Sep 2026 15:46:48 +0000 Subject: [PATCH] feat(webssh): replace the arrow keys with a Paste button - drop the four on-screen arrow buttons: a physical keyboard already sends them, and the app-cursor mode that made them awkward is handled by keySequence - add a Paste button that reads the clipboard and hands the text to the shell the same way a browser paste does, bracketed paste included - report a refusal (no secure context or permission) instead of looking dead, and fall back to Ctrl+V --- docs/web-ssh.md | 5 ++++- src/internal/panel/assets/term.js | 15 ++++++++++++-- src/internal/panel/templates/webssh.html | 26 ++++++++++++++++++------ 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/docs/web-ssh.md b/docs/web-ssh.md index 192e0b0..be6eb7a 100644 --- a/docs/web-ssh.md +++ b/docs/web-ssh.md @@ -52,7 +52,10 @@ Insert/Delete, Tab, Escape and the function keys all send what a terminal sends, and the arrows follow the mode a full-screen program asks for. A small bar above the terminal carries the few keys a browser keeps for itself -(Ctrl+C, Ctrl+Z, Ctrl+D, Escape, Tab), so they are never out of reach. +(Ctrl+C, Ctrl+Z, Ctrl+D, Escape, Tab), so they are never out of reach, plus a +**Paste** button. It reads the clipboard through the browser's clipboard API, +so it needs a secure context and permission; if either is missing the bar says +so, and Ctrl+V still works. Selecting text is left to the browser, so it works like text anywhere: drag across the terminal to select, double-click a word, and the selection survives diff --git a/src/internal/panel/assets/term.js b/src/internal/panel/assets/term.js index 3040e9e..65668de 100644 --- a/src/internal/panel/assets/term.js +++ b/src/internal/panel/assets/term.js @@ -664,12 +664,20 @@ e.preventDefault(); }; + // paste hands text to the shell the way a browser paste would, including the + // bracketed-paste wrapper when the running program asked for it. The toolbar's + // Paste button goes through here so it behaves exactly like Ctrl+V. + Term.prototype.paste = function (text) { + if (!text) return; + if (this.modes.bracketed) this._send("\x1b[200~" + text + "\x1b[201~"); + else this._send(text); + }; + Term.prototype._onPaste = function (e) { var text = (e.clipboardData || window.clipboardData).getData("text"); if (!text) return; e.preventDefault(); - if (this.modes.bracketed) this._send("\x1b[200~" + text + "\x1b[201~"); - else this._send(text); + this.paste(text); }; // keySequence is what a named key sends. The arrows depend on the mode the @@ -961,6 +969,9 @@ if (seq !== null) { input(seq); term.focus(); } }, raw: function (text) { input(text); if (term) term.focus(); }, + // paste is the toolbar's Paste button: clipboard text is delivered the + // same way a browser paste is, so bracketed paste still applies. + paste: function (text) { if (term) { term.paste(text); term.focus(); } }, // reconnect is the manual path offered once the retries are exhausted. reconnect: function () { finished = false; diff --git a/src/internal/panel/templates/webssh.html b/src/internal/panel/templates/webssh.html index 8409bd9..4e6457b 100644 --- a/src/internal/panel/templates/webssh.html +++ b/src/internal/panel/templates/webssh.html @@ -71,14 +71,11 @@ main>div{height:100%} - - - - - + +