feat: drag-and-drop file paths into terminals (Terminal.app parity)#1
Open
KickingTheTV wants to merge 1 commit into
Open
feat: drag-and-drop file paths into terminals (Terminal.app parity)#1KickingTheTV wants to merge 1 commit into
KickingTheTV wants to merge 1 commit into
Conversation
Dropping a file (e.g. a screenshot) onto a terminal now inserts the file's escaped path at the prompt, matching macOS Terminal.app / iTerm2. This is the move you reach for to hand an agent a screenshot — drag it in, the path lands where you're typing, and claude/gemini/codex read it from there. Why a new path rather than HTML5 drag-and-drop: Tauri's native file-drop (window `dragDropEnabled`, default true) intercepts the OS drag before the WKWebView's `drop` event fires, and WKWebView won't expose a dropped File's real filesystem path anyway. Tauri's native `onDragDropEvent` is the only source of the absolute paths (plus a physical-pixel drop point), so nothing happened on drop before — the event had no listener. Implementation (frontend-only; no Rust/config/capability changes): - src/lib/terminalDrop.ts: one app-wide onDragDropEvent listener + a host-element -> pty-id registry. On drop it walks up from the drop point to the terminal under the cursor and writes the escaped path(s) through the same ipc.ptyWrite channel as a keystroke. Drop position is converted from physical to CSS px (devicePixelRatio) for elementFromPoint. - TerminalPane / AuxTerminal: register their xterm host on mount, unregister on teardown (getter reads ptyRef lazily so Restart's fresh PTY still works). - main.tsx: initialise the listener once at startup. - index.css: a layout-safe inset-ring highlight on the hovered terminal. Paths are backslash-escaped like Terminal.app (spaces, parens, $, & survive), so they work both at an agent prompt and in a plain shell. Multiple files are space-joined; a trailing space is appended. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Dropping a file (e.g. a screenshot) onto a terminal now inserts the file's escaped path at the prompt, matching macOS Terminal.app / iTerm2. This is the move you reach for to hand an agent a screenshot — drag it in, the path lands where you're typing, and claude/gemini/codex read it from there. Before this, dropping a file did nothing.
Why not HTML5 drag-and-drop
Tauri's native file-drop (the window's
dragDropEnabled, which defaults totrue) intercepts the OS drag before the WKWebView's HTML5dropevent would fire — and WKWebView won't expose a droppedFile's real filesystem path anyway. So the browser DnD route is a dead end on both counts. Tauri's nativeonDragDropEventis the only source of the absolute paths (plus a physical-pixel drop point). Nothing happened on drop before simply because that native event had no listener.Implementation (frontend-only — no Rust, config, or capability changes)
src/lib/terminalDrop.ts(new): one app-wideonDragDropEventlistener + ahost element → pty-idregistry. On drop it walks up from the drop point to the terminal under the cursor and writes the escaped path(s) through the sameipc.ptyWritechannel as a keystroke — so to the agent CLI it's indistinguishable from typing. Drop position is converted physical→CSS px viadevicePixelRatioforelementFromPoint.TerminalPane.tsx/AuxTerminal.tsx: register their xterm host on mount, unregister on teardown. The registry stores a getter for the pty id, so a Restart that mints a fresh PTY is picked up without re-registering.main.tsx: initialise the single listener once at startup (idempotent against HMR re-eval).index.css: a layout-safe inset-ring highlight (box-shadow, so it can't perturb xterm'sfit()/cell grid) on the terminal under the cursor during a drag.Paths are backslash-escaped like Terminal.app (spaces, parens,
$,&all survive), so they work both at an agent prompt and in a plain shell. Multiple files are space-joined; a trailing space is appended.Testing
Manually verified on macOS (Tauri 2.11, dev build):
AuxTerminal) too.Note: the registry approach means any future terminal surface gets drop support by registering its host. The same
ptyWriteplumbing could also back a clipboard-image paste later.🤖 Generated with Claude Code