Route terminal clipboard through tauri-plugin-clipboard-manager; bump to 0.2.3
navigator.clipboard.readText() triggers WebView2's "Allow clipboard access?"
permission prompt on every paste. The plugin goes through IPC + the OS
clipboard directly, so the prompt never fires.
Wired the Rust plugin, granted clipboard-manager:allow-{read,write}-text in
the capabilities manifest, swapped XtermPane's copy/paste handler to use
the plugin's readText/writeText.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e94d2499d1
commit
29b15f19c1
7 changed files with 29 additions and 9 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "tiletopia",
|
"name": "tiletopia",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^2.0.0",
|
"@tauri-apps/api": "^2.0.0",
|
||||||
|
"@tauri-apps/plugin-clipboard-manager": "^2.0.0",
|
||||||
"@xterm/addon-fit": "^0.10.0",
|
"@xterm/addon-fit": "^0.10.0",
|
||||||
"@xterm/xterm": "^5.5.0",
|
"@xterm/xterm": "^5.5.0",
|
||||||
"react": "^18.3.0",
|
"react": "^18.3.0",
|
||||||
|
|
|
||||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
|
|
@ -11,6 +11,9 @@ importers:
|
||||||
'@tauri-apps/api':
|
'@tauri-apps/api':
|
||||||
specifier: ^2.0.0
|
specifier: ^2.0.0
|
||||||
version: 2.11.0
|
version: 2.11.0
|
||||||
|
'@tauri-apps/plugin-clipboard-manager':
|
||||||
|
specifier: ^2.0.0
|
||||||
|
version: 2.3.2
|
||||||
'@xterm/addon-fit':
|
'@xterm/addon-fit':
|
||||||
specifier: ^0.10.0
|
specifier: ^0.10.0
|
||||||
version: 0.10.0(@xterm/xterm@5.5.0)
|
version: 0.10.0(@xterm/xterm@5.5.0)
|
||||||
|
|
@ -505,6 +508,9 @@ packages:
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
'@tauri-apps/plugin-clipboard-manager@2.3.2':
|
||||||
|
resolution: {integrity: sha512-CUlb5Hqi2oZbcZf4VUyUH53XWPPdtpw43EUpCza5HWZJwxEoDowFzNUDt1tRUXA8Uq+XPn17Ysfptip33sG4eQ==}
|
||||||
|
|
||||||
'@types/babel__core@7.20.5':
|
'@types/babel__core@7.20.5':
|
||||||
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
|
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
|
||||||
|
|
||||||
|
|
@ -1172,6 +1178,10 @@ snapshots:
|
||||||
'@tauri-apps/cli-win32-ia32-msvc': 2.11.2
|
'@tauri-apps/cli-win32-ia32-msvc': 2.11.2
|
||||||
'@tauri-apps/cli-win32-x64-msvc': 2.11.2
|
'@tauri-apps/cli-win32-x64-msvc': 2.11.2
|
||||||
|
|
||||||
|
'@tauri-apps/plugin-clipboard-manager@2.3.2':
|
||||||
|
dependencies:
|
||||||
|
'@tauri-apps/api': 2.11.0
|
||||||
|
|
||||||
'@types/babel__core@7.20.5':
|
'@types/babel__core@7.20.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/parser': 7.29.3
|
'@babel/parser': 7.29.3
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tiletopia"
|
name = "tiletopia"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
description = "Tiling multi-terminal manager for WSL"
|
description = "Tiling multi-terminal manager for WSL"
|
||||||
authors = ["megaproxy"]
|
authors = ["megaproxy"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"core:default",
|
"core:default",
|
||||||
"core:event:default",
|
"core:event:default",
|
||||||
"core:window:default"
|
"core:window:default",
|
||||||
|
"clipboard-manager:allow-read-text",
|
||||||
|
"clipboard-manager:allow-write-text"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ pub fn run() {
|
||||||
.try_init();
|
.try_init();
|
||||||
|
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
.plugin(tauri_plugin_clipboard_manager::init())
|
||||||
.manage(PtyManager::new())
|
.manage(PtyManager::new())
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
commands::list_distros,
|
commands::list_distros,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "tiletopia",
|
"productName": "tiletopia",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"identifier": "com.megaproxy.tiletopia",
|
"identifier": "com.megaproxy.tiletopia",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "pnpm dev",
|
"beforeDevCommand": "pnpm dev",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@ import { useRef, useEffect } from "react";
|
||||||
import { Terminal } from "@xterm/xterm";
|
import { Terminal } from "@xterm/xterm";
|
||||||
import { FitAddon } from "@xterm/addon-fit";
|
import { FitAddon } from "@xterm/addon-fit";
|
||||||
import type { UnlistenFn } from "@tauri-apps/api/event";
|
import type { UnlistenFn } from "@tauri-apps/api/event";
|
||||||
|
import {
|
||||||
|
readText as clipboardReadText,
|
||||||
|
writeText as clipboardWriteText,
|
||||||
|
} from "@tauri-apps/plugin-clipboard-manager";
|
||||||
import {
|
import {
|
||||||
spawnPane,
|
spawnPane,
|
||||||
writeToPane,
|
writeToPane,
|
||||||
|
|
@ -174,23 +178,25 @@ export default function XtermPane({
|
||||||
// Ctrl+V (which would otherwise inject ^V into the PTY). term.paste()
|
// Ctrl+V (which would otherwise inject ^V into the PTY). term.paste()
|
||||||
// routes through onData → writeToPane, so broadcasting and bracketed
|
// routes through onData → writeToPane, so broadcasting and bracketed
|
||||||
// paste both keep working for free.
|
// paste both keep working for free.
|
||||||
|
//
|
||||||
|
// Uses tauri-plugin-clipboard-manager instead of navigator.clipboard so
|
||||||
|
// WebView2 doesn't surface its native "Allow clipboard access?" prompt.
|
||||||
term?.attachCustomKeyEventHandler((e) => {
|
term?.attachCustomKeyEventHandler((e) => {
|
||||||
if (e.type !== "keydown") return true;
|
if (e.type !== "keydown") return true;
|
||||||
if (!e.ctrlKey || !e.shiftKey || e.altKey) return true;
|
if (!e.ctrlKey || !e.shiftKey || e.altKey) return true;
|
||||||
if (e.code === "KeyC") {
|
if (e.code === "KeyC") {
|
||||||
const sel = term?.getSelection();
|
const sel = term?.getSelection();
|
||||||
if (sel) {
|
if (sel) {
|
||||||
void navigator.clipboard
|
void clipboardWriteText(sel).catch((err) =>
|
||||||
.writeText(sel)
|
console.warn("clipboard write failed:", err),
|
||||||
.catch((err) => console.warn("clipboard write failed:", err));
|
);
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (e.code === "KeyV") {
|
if (e.code === "KeyV") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
navigator.clipboard
|
clipboardReadText()
|
||||||
.readText()
|
|
||||||
.then((text) => {
|
.then((text) => {
|
||||||
if (text && term) term.paste(text);
|
if (text && term) term.paste(text);
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue