Menu ▾ ▴

#166 Linux: Wayland-safe global shortcut via the XDG GlobalShortcuts portal

closed
nobody
2026-07-24
2026-07-22
Anonymous
No

Originally created by: kristofferR

On Wayland, tauri-plugin-global-shortcut cannot register the summon hotkey; today the failure is caught and the Settings checkbox reverts (commands.rs store path, hotkey.rs startup reconcile). The org.freedesktop.portal.GlobalShortcuts portal (GNOME 45+, KDE Plasma 5.27+, Hyprland) fixes this properly. ashpd 0.12 — already a Linux dependency — ships the portal wrapper unconditionally, so no new dependencies.

Design

  • Dispatch: on Linux try the portal first (X11 and Wayland), fall back to the existing plugin, and if both fail keep today's checkbox-revert semantics with a combined error message. Activation is keyed on our shortcut id ("summon"), never the trigger, so users rebinding it in system settings keeps working — a free step toward the configurable shortcut (Ref [#52]).
  • New src-tauri/src/hotkey_portal.rs (Linux-only): is_active() / enable(app) / disable() around a keeper task. enable (blocking, idempotent): create session (5 s timeout, same pattern as linux.rs::system_prefers_dark) → subscribe receive_activated() before binding → bind_shortcuts with preferred trigger CTRL+SHIFT+m and a generous 120 s response timeout (GNOME may show an approval dialog) → verify the response contains our id → spawn the keeper via tauri::async_runtime::spawn.
  • Keeper task: on Activated matching our session + id → tray::toggle_main (already off-main-safe). On stream end (portal restart) → re-bind loop every 30 s forever, mirroring watch_portal_color_scheme, with deduped logging. Exception: an explicit bind denial during background rebind must not retry (GNOME dialog spam) — flip the setting off + save instead. On disable → Session::close().
  • hotkey.rs: factor the plugin body into plugin_sync; Linux sync_global_hotkey = portal .or_else plugin; document that it may block on a dialog and must never run on the main thread on Linux. Startup reconcile moves off-main on Linux (spawned, revert-on-error async) so a portal dialog can never freeze setup. apply_global_hotkey wraps in spawn_blocking on Linux.
  • The settings store path already runs in spawn_blocking under the settings worker — a long dialog wait there is correct serialization.

Testing

  • Unit: activation matching, bind-response validation, combined-error formatting (style of existing linux.rs tests).
  • Manual (KDE/Wayland): silent bind + summon works; rebind in System Settings still summons; disable removes it; relaunch re-binds without a dialog; systemctl --user restart xdg-desktop-portal recovers within ~30 s; portal stopped on Wayland → checkbox reverts with the combined error. Portal presence check: busctl --user get-property org.freedesktop.portal.Desktop /org/freedesktop/portal/desktop org.freedesktop.portal.GlobalShortcuts version.

Part of [#171].

Related

Tickets: #171
Tickets: #195
Tickets: #52

Discussion

  • Anonymous

    Anonymous - 2026-07-24

    Originally posted by: kristofferR

    Implemented and merged in [#195]: Carrier now uses XDG GlobalShortcuts on Linux with host registration, denial-aware fallback, activation tokens, and retry handling. Closing as complete.

     

    Related

    Tickets: #195

  • Anonymous

    Anonymous - 2026-07-24

    Ticket changed by: kristofferR

    • status: open --> closed
     

Log in to post a comment.