Repository navigation
fix(linux): deliver deep links and opened files to the app - #8976
Conversation
On Linux the bundled desktop entry advertises DBX as the handler for
dbx:// links and for .sql files, but never passes either to the app, so
both silently do nothing.
tauri-bundler derives MimeType from the deep-link schemes and the file
associations, so the desktop routes dbx:// links and .sql files to DBX.
Its stock template then emits a bare `Exec={{exec}}` with no field code,
so the URL or path is dropped instead of being appended to argv. Both
entry points in lib.rs read std::env::args(): the startup path at
line 1629 and the single-instance callback at line 1416. With nothing in
argv, connection_deep_links_from_args, ai_config_deep_links_from_args and
sql_file_paths_from_args all return empty, so dbx://connection/new,
dbx://settings/ai/new, dbx://open and .sql file opening are lost.
Add a custom desktopTemplate using `Exec={{exec}} %U`. %U rather than %f
because one Exec line serves both a URL scheme and file associations, and
the arg handlers already accept multiple values.
%U means a file manager may hand over file:// URLs rather than plain
paths, and the path parsers treated their argument as a literal path:
"file:///tmp/q.sql" is not absolute, so it was joined onto the cwd and
became "/cwd/file:///tmp/q.sql". Add normalize_launch_path_arg to decode
file:// URLs, including percent-escapes, and use it from both parsers.
Also set bundle.category, which was unset and left Categories= empty, so
the app files under no menu category.
Wired into deb and rpm since both are published; AppImage inherits the
deb template because its bundler reuses debian::generate_data.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01XWr9UtfXxdTdfHMydFh4V8
t8y2
left a comment
There was a problem hiding this comment.
Thanks — reviewed and approved. Verified against the pinned toolchain (@tauri-apps/cli 2.11.4): the stock main.desktop template indeed ships without a field code, deb/rpm both honor desktopTemplate, and AppImage inherits it via debian::generate_data, so the Exec={{exec}} %U template reaches all three Linux targets. %U is the right code per the freedesktop spec, and normalize_launch_path_arg correctly handles the file:// form file managers pass under it. Deep-link dbx:// args bypass the helper and macOS/Windows argv behavior is unchanged. One note for our release notes: bundle.category is cross-platform, so the macOS Info.plist also gains LSApplicationCategoryType — harmless for direct distribution. The CI run is waiting on first-time contributor workflow approval on our side.
|
Thanks for the contribution! Merged in f6e5b3a, will be released in the next version. |
The bug
On Linux, DBX is advertised as the handler for
dbx://links and for.sqlfiles, but never receives either. Both silently do nothing:dbx://connection/new?...— open a connection from a linkdbx://settings/ai/new?...— add an AI providerdbx://open— bring the app to the front.sqlfile in a file managerWhy
The handler is advertised.
tauri-bundlerbuildsMimeType=from both the deep-link schemes and the file associations intauri.conf.json, so the desktop entry claimsx-scheme-handler/dbxandapplication/sqland the desktop routes those to DBX.But nothing is passed. The bundler's stock template emits a bare
Exec={{exec}}with no field code (main.desktop). Per the Desktop Entry spec, a handler receives its URL or file only ifExec=carries a field code. Without one the argument is discarded rather than appended to argv.Both entry points read argv. The startup path (
lib.rs#L1629) usesstd::env::args().skip(1), and the single-instance callback (lib.rs#L1416) works off theargsit is handed. With nothing in argv,connection_deep_links_from_args,ai_config_deep_links_from_args,sql_file_paths_from_argsanddb_file_paths_from_argsall return empty.Changes
New
src-tauri/linux/DBX.desktop— the bundler's stock template with a field code added:Exec={{exec}} %U%Urather than%f/%Fbecause a singleExec=line serves both a URL scheme and file associations:%fcannot carry adbx://URL, while%Ucovers both and the arg handlers already accept multiple values.normalize_launch_path_arg(src-tauri/src/commands/launch_args.rs) — required by that choice. With%U, file managers such as Nautilus and Dolphin hand overfile://URLs instead of plain paths, and the path parsers treated their argument as a literal path. I checked the current behaviour by compilingsql_file_path_from_argas-is:"file:///tmp/q.sql"is not absolute, so it was joined onto the cwd and became a path that cannot exist. The new helper decodesfile://URLs (including percent-escapes and alocalhostauthority), returns every other argument untouched, and rejectsfile://URLs pointing at another host.sql_file_path_from_arganddb_file_path_from_argnow go through it.src-tauri/tauri.conf.json— pointsdebandrpmat the template, and setsbundle.category, which was unset and leftCategories=empty so the app files under no menu category.Rendered entry:
Notes
StartupWMClassdeliberately keeps bare{{exec}}with no field code — it must match the actual WM class or window-to-launcher grouping breaks.Namekeeps{{name}}andproductNameis untouched, so the binary name, WM class and updater artifacts are unaffected.DeveloperToolmaps toDevelopment;on freedesktop andpublic.app-category.developer-toolson macOS.debian::generate_data.Separate observation, not addressed here
The
.db/.sqlite/.sqlite3/.duckdbassociation declares nomimeType, so unlike.sqlit contributes nothing toMimeType=and those files are not associated with DBX on Linux at all.db_file_paths_from_argsstill benefits from this PR (paths arrive when DBX is launched with one), but wiring up the association needs a MIME type plus a shared-mime-info package, which felt like a separate change. Happy to open an issue.Verification
make cargo-test-fastequivalent (cargo test --no-default-features --features sqlite-bundled):The full
commands::externalsuite also passes (28 passed, 0 failed), so the parser change is not a regression.Two of the new tests are file-content checks on the shipped desktop entry, per the guidance in CONTRIBUTING that these suit shipped artifacts and cross-runtime contracts: the
Exec=field code is precisely the contract that puts links and files intostd::env::args(), and it is invisible to behaviour tests. One pins that the entry keeps a URL field code and thatStartupWMClassstays bare; the other pins that the bundler is actually pointed at the template, so the fix cannot be silently unwired.Also:
rustfmtclean under the repo'smax_width = 120/use_small_heuristics = "Max", andtauri.conf.jsonvalidates against the official schema for the resolvedtauri 2.11.5—BundleConfig,DebConfigandRpmConfigall setadditionalProperties: false, so that confirmscategoryanddesktopTemplateare recognized keys rather than silently ignored.If you add a preview/build label I'm glad to help confirm on the resulting .deb that a
dbx://link and a.sqldouble-click both reach the app.No linked issue: blank issues are disabled and the bug report template is database-specific, so the analysis lives here. Happy to file one in whatever form you prefer.