Claude Desktop (Linux, official apt package): quick-entry global shortcut fails whenever the app lacks focus (window open-but-unfocused, or closed to tray) — reproduces even with the X11 ozone workaround
Title: Claude Desktop (Linux, official apt package): quick-entry global shortcut fails whenever the app lacks focus (window open-but-unfocused, or closed to tray) — reproduces even with the X11 ozone workaround
Environment
- Claude Desktop version: 1.34493.1 (official
.deb,downloads.claude.ai/claude-desktop/apt/stable) - OS: Debian 13 (trixie)
- Desktop: GNOME Shell 48.7, Mutter 48.7
- Session: Wayland (
XDG_SESSION_TYPE=wayland) - xdg-desktop-portal 1.20.3, xdg-desktop-portal-gnome 48.0-2
- Electron 42.9.2
Bug 1 — global shortcut cannot be registered at all under native Wayland
Setting any global shortcut (e.g. Ctrl+Alt+Space) in Settings fails with "already in use," even though nothing is actually bound (confirmed empty ~/.local/share/xdg-desktop-portal permission store, and zero org.freedesktop.portal.GlobalShortcuts D-Bus traffic captured during a registration attempt). Reproduces on latest version. This matches a known, closed-as-blocked-upstream Electron bug: electron/electron#51875 — globalShortcut.register() on Wayland never performs the required Registry.Register(app_id) portal handshake before calling GlobalShortcuts.CreateSession, so the portal rejects the session and register() silently returns false. That report tested 40.6.1–42.3.3 (latest at time of filing) and is closed as blocked on a Chromium-level fix; we're on 42.9.2 and independently reproduced the identical symptom (empty permission store, zero portal traffic), though we can't confirm the upstream report itself was ever verified past 42.3.3.
Workaround for Bug 1: forcing --ozone-platform=x11 on the launch command (a .desktop file Exec= override) makes the shortcut register successfully via the older X11 globalShortcut path. Note: ELECTRON_OZONE_PLATFORM_HINT=x11 does not work — the app appears to call app.commandLine.appendSwitch('ozone-platform', 'wayland') unconditionally after argv parsing, silently overriding the env hint; only the literal --ozone-platform=x11 CLI flag takes effect.
Bug 2 — quick-entry fails whenever the app lacks focus, including under the X11 workaround
This is the same failure mode already reported for native Wayland in aaddrick/claude-desktop-debian#805 and #404 ("only works while the app has focus"), but we can confirm it is not specific to the Wayland portal path: with the X11 ozone workaround applied (Bug 1) and the shortcut successfully registered via X11 globalShortcut, quick-entry still fails to respond as soon as the app loses focus — reproduced both with the main window open-but-unfocused, and with it closed to tray entirely (process/tray icon alive throughout in both cases; also reproduced from a cold launch that never showed a window at all). Since this happens independent of ozone platform, it points to an app-level bug in the quick-entry handler's own logic (e.g. gating on window focus state) rather than anything specific to the Wayland GlobalShortcutsPortal gap in Bug 1.
We were unable to get further diagnostic detail: the app explicitly refuses to launch with any debugging/network-override flag present ("Claude: refusing to start — a debugging or network-override switch is present on the command line."), which blocks attaching Chrome DevTools or the Node inspector to see the actual JS-level handler behavior. #404's fix (aaddrick/claude-desktop-debian#690) only patches that project's own launcher wrapper scripts and wouldn't address this, since the bug isn't in the OS-level registration path.
Ask: Bug 1 likely needs an app-level default-to-X11-on-Wayland (or the portal handshake) until Chromium fixes the upstream issue. Bug 2 needs internal visibility into the quick-entry handler's focus-gating logic — this looks like the actual root cause behind #805/#404 too, since it now reproduces independent of ozone platform.
Investigation notes
Filing this after a fairly deep debugging session, summarized here in case it saves time:
- Confirmed the OS-side portal machinery is healthy independent of Claude:
org.freedesktop.portal.GlobalShortcutsis present,xdg-desktop-portal/xdg-desktop-portal-gnomeare running and restart cleanly, andorg.gnome.Settings.GlobalShortcutsProvideractivates successfully over D-Bus. No AppArmor restriction (the shipped profile runsflags=(unconfined)). No conflicting GNOME/Mutter keybindings on any combo we tried. - Captured live D-Bus traffic (
dbus-monitor --session) around a Settings→save of the shortcut under native Wayland: zeroGlobalShortcuts-related calls at all, and~/.local/share/xdg-desktop-portal's permission store never gains an entry — the registration attempt isn't reaching the portal, consistent with Electron#51875 above rather than a real key conflict. - Verified the
--ozone-platform=x11workaround by inspecting live process argv (ps//proc/<pid>/cmdline):ELECTRON_OZONE_PLATFORM_HINT=x11is silently ignored (process still launches with--ozone-platform=wayland), while the literal CLI flag is honored. - For bug 2, reproduced cleanly from a cold launch (app started directly to tray, no window ever shown) with the shortcut still failing silently — ruling out any "leftover main-window reference" theory tied to a specific close action. Separately confirmed it also fails with the main window still open but simply not focused, which rules out window-existence/closure as the trigger and points squarely at focus state.
- Attempted to attach both
--remote-debugging-portand--inspectto get real console output from the app's own JS (not just Chromium's internal VLOG stream, which we tried first and correctly yields nothing app-relevant).--inspectwas silently swallowed;--remote-debugging-porttriggered an explicit refusal to start ("Claude: refusing to start — a debugging or network-override switch is present on the command line.") — presumably an intentional guard against DevTools-based token/session extraction, so we stopped there rather than trying to work around it.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗