Repository navigation
Conversation
e.g. create gnome keybind with following command: `bash -c 'echo run-shortcut:toggleMute | nc -U $XDG_RUNTIME_DIR/vesktop.sock'`
BooleanSetting no longer has a defaultValue field on latest main; this was left over from before the global-shortcuts branch was rebased and caused a type error.
The Modal composition API (ModalRoot/ModalHeader/ModalContent/ ModalCloseButton) was replaced upstream by a single <Modal> component with size/title props (see DeveloperOptions.tsx for the current pattern). Also drops an eslint-disable directive that's no longer triggered after the import merge in main.ts.
Replaces Electron's globalShortcut on Linux/Wayland with a direct org.freedesktop.portal.GlobalShortcuts binding via ashpd, working around a Chromium bug where relaunching silently degrades global shortcuts to focus-bound only. - packages/libvesktop ported from C++/node-addon-api to Rust/napi-rs 3 - GlobalShortcuts class binds via ashpd, unconditionally calling BindShortcuts on every launch instead of consulting ListShortcuts - getAccentColor/updateUnityLauncherCount/requestBackground are now async - Cross-compiled with cargo-zigbuild (glibc 2.17 floor), no Docker needed; Dockerfile kept as a documented, optional local fallback (Fedora-based) - src/main/globalShortcuts/*.ts wires it in, falling back to Electron's globalShortcut when the native module or Wayland session is unavailable
Member
|
5000 lines of aislop, incredible next time save your tokens |
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.
Summary
Global shortcuts registered through Electron's
globalShortcutmodule on Linux/Wayland+KDE only work while Vesktop has focus after the first relaunch, requiring the user to manually remove and re-add the shortcut in System Settings each time.Root cause
Traced via D-Bus tracing (
busctl monitor) and Chromium source to a real upstream bug inGlobalAcceleratorListenerLinux::OnListShortcuts():Shortcut IDs are derived from a hash of the accelerator group/profile ID (see
GetShortcutPrefix()in the same file), so they're stable across relaunches. On relaunch,ListShortcutsreturns the IDs from the previous session (the portal remembers them), so everymodified_idis alreadycontainsed, the loop never enters its body, andBindShortcuts()is never called for the new session. The shortcut then quietly degrades to focus-bound, while KDE's System Settings still shows it as "registered" (stale, from the old session). This can't be worked around from application code through Electron'sglobalShortcutAPI, since it's a bug in Electron/Chromium's own binding logic.Related, though not identical: electron/electron#52218 documents the adjacent problem that
globalShortcut.register()/isRegistered()can't distinguish bound/pending/denied on this same Wayland portal path at all, since nothing surfaces theBindShortcutsresponse to callers.Fix
Replaced Electron's
globalShortcuton Linux/Wayland with a directorg.freedesktop.portal.GlobalShortcutsbinding, implemented in a new RustGlobalShortcutsclass (viaashpd) insidepackages/libvesktop. It sidesteps the bug entirely by never consultingListShortcutsto decide whether to bind. Instead, every launch unconditionally callsBindShortcutsfor the current session using a stable, app-generated shortcut ID (the keybind's own UUID from settings), which KDE'skglobalaccelrecognizes and reuses the existing consent grant for, so there's no repeat prompt.Verified via D-Bus tracing across multiple consecutive relaunches. Shortcuts bind silently with no re-prompt, and fire correctly from an unfocused window consistently.
Why a native binding instead of Electron's API
This trades being at the mercy of Electron/Chromium's shortcut implementation (and whatever bugs land in it) for direct control over the actual portal protocol calls. We talk to
xdg-desktop-portalourselves, so when something like this bug shows up we can fix it immediately rather than waiting on and tracking an upstream Electron fix. It also opens the door to functionality Electron'sglobalShortcutdoesn't expose at all, like real keyup/keydown events (needed for correct push-to-talk as seen in #1290) instead of just a single fire-on-keydown callback.Unlike at the time when PR #326 was proposed, now Vesktop already has a native module dependency in tree. This PR simply adds (relatively minimal) new functionality to the module, and ports it to Rust (which arguably has a more ergonomic NAPI developer experience).
What changed
packages/libvesktopported from C++/node-addon-api to Rust/napi-rs 3getAccentColor,updateUnityLauncherCount,requestBackgroundare now async (deliberate breaking change)GlobalShortcutsclass, exposing a discriminated-unionShortcutsEventpayload over a threadsafe-function callbackcargo zigbuild, targeting an explicit glibc 2.17 floor for both x86_64/aarch64 without needing a container (verified viaobjdumpthat the built.so's max required glibc symbol is exactly 2.17)Dockerfilekept only as an optional, documented local fallback for a hermetic build (consider replacingprebuilds/*.nodebinaries with CI/Docker built binaries). Usesfedora:44since Fedora packageszig,rustup, and a currentnodejsnatively (Debian needs NodeSource for a current Node and has nozigpackage at all)src/main/globalShortcuts/nativeGlobalShortcuts.tslazy-loads the native module, falls back cleanly to Electron'sglobalShortcutif unavailablesrc/main/globalShortcuts/acceleratorToXdgTrigger.tsconverts Electron accelerator strings to XDG shortcuts spec trigger formatsrc/main/keyBinds.tsgated onshouldUseNativeGlobalShortcuts()(Linux+Wayland only)Prior art
tuxinal/venbindand feat: Add global shortcuts #326.Milkshiift/goofbind, a Rust/ashpdWayland global-shortcuts implementation descended from venbind, which ourGlobalShortcutsclass's portal-call sequencing (CreateSession→BindShortcuts→Activated/Deactivatedstreams) is modeled on.XDPGlobalShortcutsprototype (raw GDBus), an earlier attempt at the same native-portal approach this PR takes.