WaylandKeybinds: Discord global mute, deafen and push-to-talk that keep working when GNOME drops the key release

Home: git.evandro.dev.br/evandro/vencord-wayland-keybinds, on my self-hosted Gitea. GitHub only carries this copy for reach.

WaylandKeybinds is a Vencord plugin for the Discord desktop app on Linux. Discord already hands your keybinds to GNOME through the GlobalShortcuts portal, but GNOME loses the key release whenever a modifier is let go first, and Discord's mute and deafen only act on the release. The plugin fixes this inside Discord's own Keybinds screen: whatever key you choose there becomes global, like Discord on Windows.

Timeline of one Ctrl+Shift+F10 hold with Ctrl+Shift let go first: GNOME sends a press and key repeats but no release; Discord alone never toggles and ignores the next press; with WaylandKeybinds the mute toggles on the press and silence after a re-registration means the key was released

Measured on GNOME 50 with Discord 1.0.168: every press toggled the mute exactly once, 11 to 14 ms after GNOME's signal, including a 6-second hold that GNOME repeated 57 times.

Why Discord's keybinds break on GNOME

  • GNOME's compositor looks up a shortcut's release using the modifiers still held at that moment. Let Ctrl or Shift go before the main key and the release never matches, so the portal never sends Deactivated (process_event).
  • Mute, deafen and most other toggles fire on the key release only.
  • Discord's native module ignores further presses until it sees a release, so after one lost release the next gesture disappears too.
  • GNOME describes the trigger as Press <Shift><Control>F10 while Discord expects CTRL+SHIFT+F10, so every working shortcut is flagged as different from the system one.

What the plugin does

  • Toggle actions (mute, deafen, streamer mode and the rest) fire on the press.
  • One second after a press it re-registers the shortcut, which clears Discord's stuck state, then listens for 300 ms. While the keys are held, GNOME's key repeat answers within a few milliseconds; silence means they were released. That is how push-to-talk stops even when the release is lost. A real release still stops it at once.
  • It reads GNOME's trigger format, so the Keybinds screen stops warning about a mismatch.
  • It changes nothing unless Discord registers the keybind through the Wayland portal. It runs in the renderer only: no native code, no new dependency, no DOM clicks.

Install

You need a Vencord source checkout, because user plugins are compiled into your build.

cd /path/to/Vencord
git clone https://git.evandro.dev.br/evandro/vencord-wayland-keybinds.git src/userplugins/waylandKeybinds.discordDesktop
pnpm build
pnpm inject

Restart Discord. The plugin is on by default; you can find it as WaylandKeybinds in Vencord's plugin list. Its info panel shows whether the fix is active, how many keybinds GNOME has registered, and a button that opens Discord's Keybinds page.

Important

Keep the folder name waylandKeybinds.discordDesktop. The suffix limits the plugin to the Discord desktop app, the only place where Discord's native keybind module exists.

Use

  1. Open Discord User Settings → System → Keybinds and click Add a Keybind.
  2. Pick an action (Toggle Mute, Toggle Deafen, Push to Talk…) and press your combination.
  3. GNOME asks once to allow the shortcut. Click Add.

Change the keys whenever you want on the same screen; GNOME asks again for the new combination.

Tip

For push-to-talk, a single key without modifiers (Pause, F13 to F24) keeps both press and release reliable.

On Wayland, Discord records only combinations the portal can represent: one main key plus optional modifiers. Mouse buttons cannot be global shortcuts there.

Compatibility

Component Tested with
Discord 1.0.168 (Electron 44)
Vencord 1.15.15
GNOME 50.5 (mutter 18, xdg-desktop-portal-gnome 50)
KDE Plasma, Hyprland Not tested. The portal path is the same, the release behavior may differ.

Limits

  • Release detection relies on GNOME's key repeat (500 ms, then every 30 ms by default). With key repeat turned off, push-to-talk ends about 1.3 s after the press even while you hold it.
  • When the release is lost, push-to-talk stops up to about 1.3 s after you let go.
  • The live checks covered toggle mute; push-to-talk is covered by the state-machine tests.
  • Soundboard hold stays off the portal on Linux. That is Discord's own choice.
  • The patches target Discord's minified code and can break with Discord updates. Run check-patches.mjs before you rebuild.

Development

From the root of your Vencord checkout:

# one test case per independent path of every function in logic.ts
pnpm exec esbuild src/userplugins/waylandKeybinds.discordDesktop/logic.test.ts \
  --bundle --platform=node --format=esm --outfile=/tmp/wk-test.mjs
node --test /tmp/wk-test.mjs

# apply the patches to the Discord build that discord.com serves right now
node src/userplugins/waylandKeybinds.discordDesktop/check-patches.mjs

The design notes, measurements and acceptance criteria (in Portuguese) are in specs/2026-11-01-wayland-keybinds.md.


Made by Evandro · git.evandro.dev.br/evandro · evandro.dev.br

S
Description
Vencord plugin: Discord global keybinds (mute, deafen, push-to-talk) that keep working on GNOME Wayland
Readme GPL-3.0
75 KiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 82.2%
JavaScript 12.2%
CSS 5.6%