Repository navigation
Take file drops on Linux in the shell, where the WebView cannot see them - #680
Merged
Merged
Conversation
Dropping a file on the Linux desktop app turned the window into a bare media player playing it, with only a right click and Back to get out. Dropping it on the URL box typed its file:// URI into the box, and pressing Process then failed with "URL must use http or https" (#672). Both come from one place. WebKitGTK reports a drag from a GTK file manager as text/uri-list and text/html, never as "Files", so the drop guard added in #612, which keys on "Files", never recognised it and WebKit's default ran: navigate to the file, or insert the URI into an editable target. The guard works on Windows, macOS and in Chromium, which do report "Files", which is why it was never seen there. Widening the guard was not a fix. Measured against a real drag into WebKitGTK 2.52, a cancelled drop reaches the page with no File objects, no file items, and the path blanked out of text/uri-list. The page cannot get the file at all, only stop the navigation. So on Linux the main window's native drop handler is on and the drop is taken in the shell. Tauri's handler returns true on a drop, which consumes it before WebKit's default runs, and wry only claims drags carrying a file uri-list, so the library's own HTML5 drags between folders, lanes and the trash are left alone. That was the reason the handler is off everywhere (#24): on Windows, WebView2 stops delivering HTML5 drags while it is on. It stays off on Windows and macOS, where the page already gets the files. The window is now built in setup from its tauri.conf.json entry, marked "create": false, with that one field set per platform. A per-platform config file would have needed a second full copy of the window, since its merge replaces arrays rather than patching them. No command takes a path from JavaScript. The page is a remote origin to Tauri, so app commands are callable from it without an ACL, and dragout and download_to_path already keep paths on the Rust side for that reason. A drop is recorded against opaque ids; the page is told a name and a size for each, and can read back a file the user dropped, once, by id. Only the latest drop is readable, a folder or a vanished file is refused, and the read is capped at the upload limit against the open handle so it cannot be raced past. The page cannot listen to Tauri events without a remote capability, and granting one would open every core event command to it. It already talks to the shell only through commands, so it waits on next_drop_signal instead. The signals are a log read by cursor rather than a queue that is popped: a reload leaves the old page's call waiting with nobody to answer, and a popped queue would hand it the next drop. On the page, applyFiles is split into screening and staging. A native drop is screened on its names and sizes first, so a file that will be refused as not audio or too large is never read, and only accepted files are fetched, one at a time, as raw bytes. From there it is the same path as the picker: same refusals, same pill, same staging. A file that has gone by the time it is read says so by name, in all ten languages. The upload limit now exists in three languages, so a test holds the server, the page and the shell to the same number. The first two were already duplicated with only a comment saying they must match. Verified in a real Tauri 2.11 shell around this module on Linux, driving genuine XDND drags from a separate GTK process: a drop on the page and a drop on a text box both arrive as ids with the file's real bytes, nothing navigates, nothing is typed into the box, a second read of an id is refused, and an internal drag with the library's own data types still lands on its target. The Windows build still opens its window.
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.
Closes #672
What was wrong
On the Linux desktop app, dropping a file anywhere turned the window into a bare media player. Dropping it on the URL box typed its
file://path into the box, and Process then failed with "URL must use http or https".Both have one cause. WebKitGTK, the Linux webview, reports a drag from a file manager as
text/uri-listandtext/html, never asFiles. The drop guard from #612 looks forFiles, so it never recognised the drag, and WebKit's default ran instead: open the file, or type its path into a text box. Windows, macOS and Chromium all reportFiles, which is why the guard works there.Widening the guard would not have fixed it. I measured it against a real drag into WebKitGTK 2.52. Even with the drop cancelled, the page receives no files and the path is blanked out. The page can stop the navigation but can never get the file.
The fix
On Linux the app takes the drop, not the page.
wryonly claims drags that carry files, so the library's own drags between folders, lanes and the trash are untouched.The window is now built in
setupfrom its existingtauri.conf.jsonentry, marked"create": false, with only that one setting changed per platform. A per-platform config file would have needed a second full copy of the window definition.No command takes a file path from JavaScript. The page is a remote origin to Tauri, and
dragoutanddownload_to_pathalready follow this rule for that reason.The page waits on a command, not an event. A remote origin cannot listen to Tauri events without a capability that would expose every core event command. Signals are kept in a log that each caller reads from its own position, so a reloaded page's leftover call cannot swallow the next drop.
On the page,
applyFilesis split into screening and staging.The upload limit now appears in three languages, and a new test holds the server, the page and the app to the same number.
Verification