Skip to content

fix(linux): pass deep-link URL to the app so sign-in works on cold start - #151

Merged
Blankll merged 1 commit into
geek-fun:masterfrom
anandghegde:fix/linux-deep-link-exec-field-code
Sep 15, 2026
Merged

Blankll merged 1 commit into
geek-fun:masterfrom
anandghegde:fix/linux-deep-link-exec-field-code

Conversation

@anandghegde

@anandghegde anandghegde commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

The bug

On Linux, clicking the sqlkit://auth?... sign-in callback while SqlKit is not already running launches the app but never signs you in. The token is silently dropped.

The desktop entry advertises SqlKit as the sqlkit:// handler, so the link is routed to the app correctly — it just arrives empty.

Why

Four links in the chain, all in current master:

  1. The handler is advertised. tauri-bundler derives MimeType=x-scheme-handler/sqlkit from the deep-link config in tauri.conf.json (deep_link_protocols() branch in freedesktop/mod.rs), so the desktop dispatches sqlkit:// links to SqlKit.

  2. But the URL is never passed. The bundler's stock template emits a bare Exec={{exec}} with no field code (main.desktop). Per the Desktop Entry spec, a handler only receives the URL if Exec= carries %u/%U. Without it the URL is discarded rather than appended to argv.

  3. The plugin reads argv. tauri-plugin-deep-link builds its URL list from std::env::args() at init (handle_cli_arguments), so get_current() returns None.

  4. So the auth event never fires. src-tauri/src/lib.rs#L197if let Ok(Some(urls)) = app.deep_link().get_current() — never enters, parse_auth_from_url is never called, and the sqlkit://auth event that src/App.vue#L32 listens for is never emitted. accountStore.setAuth(token, username, email) never runs.

Worth noting: the deep-link plugin's own runtime-registration template already uses Exec="{path}" %u, so %u is what the plugin expects. SqlKit doesn't call register(), so it relies on the bundled entry — which lacks it.

Changes

New src-tauri/linux/SqlKit.desktop — the bundler's stock template with %u added:

Exec={{exec}} %u

src-tauri/tauri.conf.json — points deb and rpm at that template, and sets bundle.category, which was unset and left Categories= empty so the app files under no menu category.

Rendered output:

[Desktop Entry]
Categories=Development;
Comment=SqlKit
Exec=SqlKit %u
StartupWMClass=SqlKit
Icon=SqlKit
Name=SqlKit
Terminal=false
Type=Application
MimeType=x-scheme-handler/sqlkit

Notes on the approach

  • StartupWMClass deliberately keeps bare {{exec}} with no %u — it must match the actual WM class or window-to-launcher grouping breaks.
  • Name keeps {{name}}, since productName is already SqlKit. No productName change, so the binary name, WM class and updater artifacts are untouched.
  • DeveloperTool maps to Development; on freedesktop and public.app-category.developer-tools on macOS (category.rs), so this also fills in the previously-unset App Store category.
  • deb + rpm, AppImage free. Both are published and share the bug. AppImage needs no entry of its own — its bundler calls debian::generate_data, so it inherits the deb template.

Separate observation, not addressed here

lib.rs listens for deep-link://new-url to handle links arriving while the app is already running, but tauri-plugin-single-instance isn't registered. On Linux and Windows that event is emitted through the single-instance integration, so that handler looks like it can't fire on those platforms today — a second sqlkit:// click spawns a new process instead of reaching the running one.

This PR doesn't touch that, since adding single-instance changes app behavior (no more multiple windows) and that's a product call. With %u in place the new process at least receives the token via argv and signs in. Happy to open a follow-up issue if it's worth tracking.

Verification

  1. Rendered the template through Handlebars with the exact context tauri-bundler supplies (categories, comment, exec, icon, name, mime_type) — output above.
  2. Parsed that output as a freedesktop key/value file, asserting Exec is SqlKit %u, StartupWMClass stays bare, MimeType is intact, Categories is ;-terminated.
  3. Validated tauri.conf.json against the official schema for the resolved tauri 2.11.3 — passes. BundleConfig, DebConfig and RpmConfig all set additionalProperties: false, confirming category and desktopTemplate are recognized keys rather than silently ignored.

If you add a preview/build label I'm glad to help confirm on the resulting .deb that sqlkit://auth?... signs in from a closed state.

The bundled desktop entry advertises SqlKit as the sqlkit:// handler but
never forwards the URL, so signing in on Linux silently does nothing when
the app is not already running.

tauri-bundler derives MimeType=x-scheme-handler/sqlkit from the deep-link
config, so the desktop routes sqlkit:// links to SqlKit. Its template then
emits a bare `Exec={{exec}}` with no field code, so the URL is dropped
instead of being appended to argv. tauri-plugin-deep-link builds its URL
list from std::env::args() at init, so get_current() returns None, the
cold-start branch in lib.rs never fires, and the sqlkit://auth event that
App.vue listens for is never emitted. The token, username and email from
the callback are lost.

Add a custom desktopTemplate with `Exec={{exec}} %u`. The plugin's own
runtime-registration template already uses `%u`, so this aligns the
bundled entry with what the plugin expects. StartupWMClass keeps the bare
{{exec}} so window grouping still matches the binary, and Name keeps
{{name}} since productName is already capitalized.

Also set bundle.category, which was unset and left Categories= empty, so
the app files under no menu category. DeveloperTool maps to Development;
on freedesktop and public.app-category.developer-tools on macOS.

Wired into deb and rpm since both are published; AppImage inherits the
deb template because its bundler reuses debian::generate_data.
@codecov

codecov Bot commented Sep 15, 2026

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

@Blankll Blankll left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, thanks your contribution! @anandghegde

@Blankll
Blankll merged commit 8a8f870 into geek-fun:master Sep 15, 2026
5 checks passed
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.

2 participants