diff --git a/package.json b/package.json index d86eeb1..b9f4f2e 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,7 @@ "dependencies": { "@tauri-apps/api": "^2.0.0", "@tauri-apps/plugin-clipboard-manager": "^2.0.0", - "@tauri-apps/plugin-opener": "^2.0.0", "@xterm/addon-fit": "^0.10.0", - "@xterm/addon-web-links": "^0.12.0", "@xterm/xterm": "^5.5.0", "react": "^18.3.0", "react-dom": "^18.3.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3eb8b88..aab158b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,15 +14,9 @@ importers: '@tauri-apps/plugin-clipboard-manager': specifier: ^2.0.0 version: 2.3.2 - '@tauri-apps/plugin-opener': - specifier: ^2.0.0 - version: 2.5.4 '@xterm/addon-fit': specifier: ^0.10.0 version: 0.10.0(@xterm/xterm@5.5.0) - '@xterm/addon-web-links': - specifier: ^0.12.0 - version: 0.12.0 '@xterm/xterm': specifier: ^5.5.0 version: 5.5.0 @@ -517,9 +511,6 @@ packages: '@tauri-apps/plugin-clipboard-manager@2.3.2': resolution: {integrity: sha512-CUlb5Hqi2oZbcZf4VUyUH53XWPPdtpw43EUpCza5HWZJwxEoDowFzNUDt1tRUXA8Uq+XPn17Ysfptip33sG4eQ==} - '@tauri-apps/plugin-opener@2.5.4': - resolution: {integrity: sha512-1HnPkb+AmgO29HBazm4uPLKB+r7zzcTBW1d0fyYp1uP+jwtpoiNDGKMMzz58SFp49nOIrxdE3aUJtT57lfO9CQ==} - '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -589,9 +580,6 @@ packages: peerDependencies: '@xterm/xterm': ^5.0.0 - '@xterm/addon-web-links@0.12.0': - resolution: {integrity: sha512-4Smom3RPyVp7ZMYOYDoC/9eGJJJqYhnPLGGqJ6wOBfB8VxPViJNSKdgRYb8NpaM6YSelEKbA2SStD7lGyqaobw==} - '@xterm/xterm@5.5.0': resolution: {integrity: sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==} @@ -1194,10 +1182,6 @@ snapshots: dependencies: '@tauri-apps/api': 2.11.0 - '@tauri-apps/plugin-opener@2.5.4': - dependencies: - '@tauri-apps/api': 2.11.0 - '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.29.3 @@ -1290,8 +1274,6 @@ snapshots: dependencies: '@xterm/xterm': 5.5.0 - '@xterm/addon-web-links@0.12.0': {} - '@xterm/xterm@5.5.0': {} assertion-error@2.0.1: {} diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 28063fb..65febb2 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -16,7 +16,6 @@ tauri-build = { version = "2", features = [] } [dependencies] tauri = { version = "2", features = [] } tauri-plugin-clipboard-manager = "2" -tauri-plugin-opener = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 8071b47..8d355d9 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -8,7 +8,6 @@ "core:event:default", "core:window:default", "clipboard-manager:allow-read-text", - "clipboard-manager:allow-write-text", - "opener:allow-open-url" + "clipboard-manager:allow-write-text" ] } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index dfbf1aa..06dea5f 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -16,7 +16,6 @@ pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_clipboard_manager::init()) - .plugin(tauri_plugin_opener::init()) .manage(PtyManager::new()) .invoke_handler(tauri::generate_handler![ commands::list_distros, diff --git a/src-tauri/src/pty.rs b/src-tauri/src/pty.rs index 117d97a..094d847 100644 --- a/src-tauri/src/pty.rs +++ b/src-tauri/src/pty.rs @@ -13,10 +13,6 @@ use portable_pty::{CommandBuilder, MasterPty, PtySize, native_pty_system}; use serde::Serialize; use tauri::{AppHandle, Emitter}; -/// Sentinel "distro" name used to spawn Windows PowerShell instead of WSL. -/// Frontend appends this to the distro list it shows in the dropdown. -pub const POWERSHELL_DISTRO: &str = "PowerShell"; - pub type PaneId = u64; /// What we keep alive for each spawned PTY. @@ -66,40 +62,26 @@ impl PtyManager { }) .context("openpty failed")?; - let is_powershell = distro.as_deref() == Some(POWERSHELL_DISTRO); + let mut cmd = CommandBuilder::new("wsl.exe"); + if let Some(d) = distro.as_deref() { + cmd.arg("-d"); + cmd.arg(d); + } + // Default new panes to the WSL user's home (~) rather than the + // Windows-side cwd we inherit from the launcher (typically + // C:\Users\, which shows up as /mnt/c/Users/ inside WSL). + // wsl.exe resolves `~` against the distro's default shell. + let resolved_cwd = cwd.as_deref().unwrap_or("~"); + cmd.arg("--cd"); + cmd.arg(resolved_cwd); + // Force a login shell so .bashrc etc. run and PATH is populated. + // wsl.exe without an explicit command launches the default shell + // interactively, which is exactly what we want. - let cmd = if is_powershell { - // cwd from the leaf is ignored — leaves may carry Linux-style - // paths (e.g. `~`, `/mnt/d/...`) from a previously-assigned WSL - // distro that PowerShell wouldn't understand. PowerShell starts - // in its own default cwd; user can `cd` if they want. - let mut c = CommandBuilder::new("powershell.exe"); - c.arg("-NoLogo"); - c - } else { - let mut c = CommandBuilder::new("wsl.exe"); - if let Some(d) = distro.as_deref() { - c.arg("-d"); - c.arg(d); - } - // Default new panes to the WSL user's home (~) rather than the - // Windows-side cwd we inherit from the launcher (typically - // C:\Users\, which shows up as /mnt/c/Users/ inside WSL). - // wsl.exe resolves `~` against the distro's default shell. - let resolved_cwd = cwd.as_deref().unwrap_or("~"); - c.arg("--cd"); - c.arg(resolved_cwd); - // wsl.exe without an explicit command launches the default shell - // interactively, which is exactly what we want. - c - }; - - let spawn_err = if is_powershell { - "failed to spawn powershell.exe" - } else { - "failed to spawn wsl.exe; is WSL installed?" - }; - let child = pair.slave.spawn_command(cmd).context(spawn_err)?; + let child = pair + .slave + .spawn_command(cmd) + .context("failed to spawn wsl.exe; is WSL installed?")?; // We need to keep the master alive (drop = close the PTY), but we // also need the reader and writer split from it. diff --git a/src/App.tsx b/src/App.tsx index f3c72c9..9c40c98 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -49,9 +49,6 @@ import "./lib/layout/Gutter.css"; const LEGACY_STORAGE_KEY = "tiletopia.tree.v1"; const SAVE_DEBOUNCE_MS = 500; -/** Sentinel "distro" the backend recognises to spawn powershell.exe instead - * of wsl.exe. Must match `POWERSHELL_DISTRO` in `src-tauri/src/pty.rs`. */ -const POWERSHELL_DISTRO = "PowerShell"; function isInteractiveDistro(name: string): boolean { return !name.toLowerCase().startsWith("docker-desktop"); @@ -103,14 +100,11 @@ export default function App() { let resolvedDefault: string | undefined; try { resolvedDistros = await listDistros(); + resolvedDefault = + resolvedDistros.find(isInteractiveDistro) ?? resolvedDistros[0]; } catch (e) { console.warn("list_distros failed:", e); } - // Append PowerShell as a pseudo-distro so it appears in the titlebar - // default-picker and the per-pane dropdown. - resolvedDistros = [...resolvedDistros, POWERSHELL_DISTRO]; - resolvedDefault = - resolvedDistros.find(isInteractiveDistro) ?? resolvedDistros[0]; if (cancelled) return; if (loaded) { diff --git a/src/components/XtermPane.tsx b/src/components/XtermPane.tsx index 7222800..022502b 100644 --- a/src/components/XtermPane.tsx +++ b/src/components/XtermPane.tsx @@ -1,13 +1,11 @@ import { useRef, useEffect } from "react"; import { Terminal } from "@xterm/xterm"; import { FitAddon } from "@xterm/addon-fit"; -import { WebLinksAddon } from "@xterm/addon-web-links"; import type { UnlistenFn } from "@tauri-apps/api/event"; import { readText as clipboardReadText, writeText as clipboardWriteText, } from "@tauri-apps/plugin-clipboard-manager"; -import { openUrl } from "@tauri-apps/plugin-opener"; import { spawnPane, writeToPane, @@ -126,16 +124,6 @@ export default function XtermPane({ const fit = new FitAddon(); fitRef.current = fit; term.loadAddon(fit); - // Underlines http(s) URLs in the terminal output and routes clicks - // through Tauri's opener plugin so they open in the user's default - // browser (WebView2 won't navigate on a plain window.open). - term.loadAddon( - new WebLinksAddon((_event, uri) => { - void openUrl(uri).catch((err) => - console.warn("openUrl failed:", err), - ); - }), - ); term.open(container); // Initial size — fit before asking the PTY for its dimensions.