Skip to content

Copy Selected Result Path as Text: Ctrl+Shift+C (Absolute), Ctrl+Shift+R (Relative) - #202

Open
Ocean572 wants to merge 1 commit into
ARahim3:mainfrom
Ocean572:fix/copy-path-hotkey-148
Open

Ocean572 wants to merge 1 commit into
ARahim3:mainfrom
Ocean572:fix/copy-path-hotkey-148

Conversation

@Ocean572

@Ocean572 Ocean572 commented Nov 6, 2026 •

Copy link
Copy Markdown

Closes #148.

Problem

Users requested keyboard shortcuts to copy the selected search result's file path as plain text, making it possible to paste the path directly into an open or upload dialog.

The existing copy behavior did not support this workflow:

  • Ctrl+C copies the actual file, allowing it to be pasted into a file manager, chat, or email. It does not populate the filename field in an open/upload dialog.
  • The window's existing "Copy Path" menu item used navigator.clipboard, which requires clipboard permissions that the shell's Tauri capability configuration does not provide. Consequently, it did not work on Linux or Windows.
  • The search panel had no path-copy functionality at all.

Changes

1. Windows and Linux Shell

A shared copyPathText implementation in results.js adds two keyboard shortcuts for focused search results:

Shortcut Action
Ctrl+Shift+C Copy absolute file path
Ctrl+Shift+R Copy path relative to its search folder

Both the search panel and the main window support these shortcuts.

The main window's right-click context menu also gains a Copy Relative Path option alongside the existing Copy Path action.

2. Relative Path Resolution

Relative path generation is handled by a new Rust helper, relative_path, exposed to the frontend through relative_path_text.

The helper applies the following rules:

  • Uses the longest containing search folder when multiple search folders contain the file.
  • Displays / as the path separator.
  • Compares folder paths case-insensitively to match Windows path behavior.
  • Falls back to the absolute path when no configured search folder contains the file.

This ensures nested search folders resolve against the most specific matching root.

3. Native System Clipboard Integration

A new Tauri command, copy_text, handles copying path strings to the system clipboard.

Platform-specific implementations use:

  • Windows: CF_UNICODETEXT.
  • Linux: GTK clipboard text.

This uses the same native clipboard mechanism already used by the application's existing file-copy functionality.

Why Not navigator.clipboard?

The initial implementation used navigator.clipboard.writeText, but pre-push code review identified a platform compatibility problem.

Tauri serves its frontend through a custom URL scheme. On Windows, this uses http://tauri.localhost, which is not considered a secure context for the browser clipboard API.

Consequently, the web clipboard API is unavailable in this environment.

The native clipboard implementation avoids this limitation and does not require:

  • Additional Tauri capabilities or clipboard permissions.
  • A clipboard plugin.
  • A secure browser origin.

It also uses the same underlying native clipboard approach that the application already relies on.

4. Panel State and Selection Handling

Pre-push review also identified a regression in the original implementation.

The panel's state object did not include an info property. As a result, its first panel-shown event attempted to access missing state, causing an exception and preventing the search field from receiving focus.

This is fixed by:

  • Initializing folder information through state.info.folders.
  • Refreshing the folder information whenever the panel is shown.

The keyboard shortcuts also preserve normal text-selection behavior.

If text is selected in the search query field or elsewhere on the page, the shortcut is allowed to perform its normal copy-selection action instead of copying the selected file path.

This is particularly important for Ctrl+Shift+C, which WebKitGTK uses as a text-selection copy shortcut.

5. macOS Support

The macOS application receives equivalent functionality in the search panel:

Shortcut Action
⌘⇧C Copy absolute file path
⌘⇧R Copy relative file path

Additional UI changes include:

  • Panel keyboard hints now display ⌘⇧C Path.
  • Search result context menus gain Copy Relative Path.
  • Relative paths are only offered when the relevant search folders are available.

The panel now passes its folder configuration through to the result rows.

The main window's rows do not currently receive that folder information, so the relative-path option is intentionally omitted there. This avoids presenting a relative-path action that would simply return the absolute path.

6. Shared macOS Relative Path Logic

Both keyboard shortcuts and context menu actions use a shared implementation:

FileDragView.relativeSpelling

Its behavior matches the shell's Rust relative_path implementation:

  • Trims trailing path separators, including multiple trailing separators.
  • Treats / as a root that contains every absolute path.
  • Uses the longest matching search folder when resolving nested roots.

This keeps relative-path generation consistent across the macOS and Windows/Linux implementations.

Testing and Verification

Measured on the development machine:

Hardware and environment: Apple M1, 8 GB RAM, macOS 26.5.1.

Rust Tests

  • cargo test: 14 tests passed.
  • New copy_path_tests cover:
    • Windows-style backslash paths.
    • Nested search folders and longest-folder matching.
    • Case-insensitive root matching.
    • Absolute-path fallback when no root contains the file.
    • Root-itself fallback behavior.
    • / as a root containing all absolute paths.
    • Longest-folder matching taking precedence over /.
    • Roots with one or multiple trailing separators.

Additional Test Suites

  • Swift test suite: 125 tests passed.
  • Shell JavaScript tests: node --test — 17 tests passed.
  • All frontend pages passed node --check.

Scope and Limitations

The following items remain unverified or have known platform-specific limitations:

  • Live Tauri clipboard verification: Clipboard writes have not been verified inside a running Tauri webview. The shell application does not run on macOS, and the Windows-specific copy_text implementation is only compiled for Windows targets.
  • macOS GUI acceptance: The new macOS panel keyboard shortcuts and context menu behavior have not been exercised through GUI testing on this development machine.
  • Windows WebView2 shortcut handling: Ctrl+Shift+C may be intercepted by the browser control for its own copy functionality. The text-selection guard handles the common case. Ctrl+Shift+R does not have the same shortcut conflict.
  • Linux filenames containing literal backslashes: A filename containing a literal \ character will have its separators rewritten during relative-path formatting. This behavior exists in both implementations and is expected to be extremely uncommon.
  • Non-ASCII case sensitivity: The shell compares folder names using ASCII case-insensitive matching, consistent with Windows path behavior. The macOS implementation performs case-insensitive matching across the full alphabet. This creates a minor divergence for non-ASCII folder names.
  • Window folder-state freshness: The main window loads its folder configuration when the window opens, whereas the search panel refreshes its folders every time it is shown. If folders change while the main window remains open, relative paths may be calculated using the older folder list until the window is reloaded.

…solute, Ctrl+Shift+R relative to its search folder

Issue ARahim3#148 asked for a hotkey that puts the path of the selected search result on the
clipboard as text, to paste into open/upload dialogs: the existing Ctrl+C copies the file
itself (file-manager/chat paste), which does not paste into a dialog's name field, and the
window's "Copy Path" menu line used `navigator.clipboard`, which needs Tauri's clipboard
permission the shell's capability file doesn't carry — so it did nothing on Linux/Windows
(and the panel had no path copy at all).

The shell (Windows/Linux): a shared `copyPathText` in `results.js` takes Ctrl+Shift+C /
Ctrl+Shift+R on a focused result in the panel and the window, and the window's right-click
menu gains "Copy Relative Path" beside "Copy Path". The relative spelling comes from a
Rust helper, `relative_path` (the longest containing search folder, `/` shown,
case-insensitive like Windows spells folders; absolute when no root holds the file),
exposed as `relative_path_text`. The text goes onto the system clipboard through a new
`copy_text` command in `clipboard.rs` — CF_UNICODETEXT on Windows, GTK clipboard text on
Linux, the native channel Ctrl+C's file copy already uses. The pre-push review rejected
the original `navigator.clipboard.writeText` plan: Tauri serves its pages from a custom
scheme (`http://tauri.localhost` on Windows), a non-secure context where the web clipboard
API is unavailable — the native route needs no capability, no plugin, and no secure
origin, and it is the mechanism this app has always pasted with. The panel's
`panel-shown` event carries the shell's current folders, which the page keeps for the
relative spelling (and the panel page gained its `state.info` — the review caught that
the panel's state literal had none, so the first listener line threw on every show and
the field lost focus: a visible panel breakage no suite at that commit exercised).
Text selected in the query field or page keeps its own copy — Ctrl+Shift+C is WebKitGTK's
copy-selection shortcut, and the guard lets it through.

The Mac app mirrors it: ⌘⇧C / ⌘⇧R in the panel (SearchPanel key handling, same
selected-text rule as ⌘C's), the panel key hints say "⌘⇧C Path", and the rows' menu gains
"Copy Relative Path" — offered only where the folders are known (the panel threads them;
the window rows don't today, and an item that would echo the absolute path under a
relative label is a promise not to make). The spelling is one function,
`FileDragView.relativeSpelling`, used by keys and menu alike; it trims trailing
separators (any number) and treats a root spelled `/` as holding every absolute path,
matching the shell's `relative_path` (the shell compares ASCII as Windows spells folder
names, the Mac the whole alphabet — disclosed divergence for non-ASCII roots).

Verified on this box: cargo test 14 green — `copy_path_tests` covers Windows
backslashes, longest-folder nesting, case-insensitive roots, no-root and root-itself
fallbacks, the `/` root (and the longest-folder rule beating it), and roots with one or
many trailing separators; Swift suite 125 green (base count, app target compiles);
shell JS `node --test` 17 pass, all pages pass `node --check`. Not verified: the
clipboard writes in a live Tauri webview (the shell app doesn't run on macOS; the
Windows `copy_text` block compiles only for Windows targets, disclosed), and the Mac
panel keys (app GUI acceptance, morning).

Disclosed edges: on Windows WebView2 Ctrl+Shift+C may be captured by the browser control
for its own copy — the has-selection guard covers the common case; Ctrl+Shift+R is free.
A Linux filename containing a literal `\` gets its separators rewritten in the relative
spelling (both impls; near-unseen). Window-page folders refresh at window load (panel
folders are fresh at every show) — a mid-session folder change on an open window spells
new paths against the list the window was opened with until reload.
@Ocean572 Ocean572 changed the title Copy the selected result's path as text: Ctrl+Shift+C absolute, Ctrl+Shift+R relative to its search folder Copy Selected Result Path as Text: Ctrl+Shift+C (Absolute), Ctrl+Shift+R (Relative) Nov 6, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Copy file path hotkey

1 participant