Push-to-Talk Functioning Incorrectly

(#65) Bug Awaiting confirmation voice

Summary

Expectation: Pressing the push-to-talk key enables input for the microphone, and releasing it disables input. Reality: Pressing the push-to-talk key does nothing, and releasing it frequently mutes the microphone entirely. Input otherwise remains on voice-activation, regardless of setting.

Steps to reproduce

  1. Enable Push-to-Talk activation in settings
  2. Bind any applicable key for PTT
  3. Join voice call3a. Attempt to speak — voice-activation remains active3b. Attempt to use PTT key — microphone mute will often (though not always) be activated on release

Environment (optional)

Version: desktop stable 0.0.8 (ab66ad7), Electron 39.2.7, 2026-02-14 23:14:53 UTC OS: Fedora Linux 6.18.6-200.fc43.x86_64 (x64)

6 comments

Sign in with Fluxer to comment and vote.
Comment by Rex
RexSystem 1 vote edited
Status changed from Fixed to Awaiting confirmation
This may be fixed in the current version. If it still happens for you, please say so here.
Comment by @mumixam
RexSystem 1 vote originally by @mumixam on GitHub
+1 same issue on windows 11 using desktop app and same issue using it via web on brave on Arch linux
Comment by @Maxim-inc
RexSystem 1 vote originally by @Maxim-inc on GitHub
+1 on windows 11. Additionally I can't bind my PTT to my mouse buttons like I prefer rather than sacrificing a keyboard key for PTT.
Comment by @aikaterna
RexSystem 1 vote originally by @aikaterna on GitHub
Adding onto this issue, I'm unable to use keys like CTRL, ALT, or shift for a keybind as they never register as a key while using the input. The input modal is asking for a keypress and when you press one of those buttons, the Reset button appears as if you typed in a key, but there's nothing in the box. stable (d90628a), 2026-02-16 10:10:38 UTC, Electron 39.2.7, macOS 14.7.6 (arm64), desktop stable 0.0.8 image
  • 550722895-84700829-9494-4045-8910-1eb979ace810.png

    550722895-84700829-9494-4045-8910-1eb979ace810.png

    373×207 | 14 kB

Comment by @MystikDev
RexSystem 1 vote edited originally by @MystikDev on GitHub
found a few bugs with the PTT and here are some potential fixes for the issues: Bug 1 (CRITICAL): KeybindRecorder is disabled on web browsers — users can never set a PTT key In VoiceTab.tsx line 88 and 251:
const isPttLimited = !isNativeDesktop || (isNativeMac && !inputMonitoringGranted);
// ...
<KeybindRecorder ... disabled={isPttLimited} />
On a web browser, !isNativeDesktop is true, so isPttLimited is always true, and the KeybindRecorder is disabled. The user can switch to PTT mode (the radio group still works), but they physically cannot record a keybind. Combined with the fact that the default PTT combo is {key: '', enabled: false, global: false} (an empty key), PTT is completely non-functional on web browsers because no key is ever bound. The disabled flag conflates two things: "can't set ANY key" and "can't use global shortcuts." On web, local (in-focus) PTT should still work — the warning banner already tells users it only works when the tab has focus. The recorder should be enabled. Fix in VoiceTab.tsx:
// Line 251: only disable the recorder when PTT is entirely impossible,
// not merely limited. On web, local PTT works fine.
<KeybindRecorder
  action="push_to_talk"
  value={pttKeybind.combo}
  defaultValue={defaultPttCombo}
  disabled={false}  // ← always allow key recording
  onChange={(combo) => {
    KeybindStore.setKeybind('push_to_talk', {
      ...combo,
      global: isNativeDesktop ? pttKeybind.combo.global : false,
    });
  }}
  // ...
/>
Bug 2 (HIGH): getMuteReason always returns 'self' instead of 'push_to_talk' In VoiceAudioManager.ts line 115-123:
export function getMuteReason(voiceState: VoiceState | null) {
  const selfMuted = voiceState?.self_mute ?? LocalVoiceStateStore.getSelfMute();
  if (KeybindStore.isPushToTalkEffective() && KeybindStore.isPushToTalkMuted(selfMuted))
    return 'push_to_talk';
  if (selfMuted) return 'self';
  return null;
}
Trace the logic: when PTT mutes the user, applyPushToTalkHold(false) → applyLocalMuteState(true, ...) → LocalVoiceStateStore.updateSelfMute(true) → syncVoiceState({self_mute: true}). So selfMuted becomes true. Then isPushToTalkMuted(true) hits line 567 in KeybindStore: if (userMuted) return false — because the parameter is intended to mean "user manually muted," but it's being passed the raw self_mute which includes PTT-induced muting. Result: mute reason is always 'self', never 'push_to_talk'. The UI shows "Unmute" instead of "Push-to-talk enabled — hold [key] to speak." Fix in VoiceAudioManager.ts: tsexport function getMuteReason(voiceState: VoiceState | null) { const isGuildMuted = voiceState?.mute ?? false; if (isGuildMuted) return 'guild'; const selfMuted = voiceState?.self_mute ?? LocalVoiceStateStore.getSelfMute(); // Use the manual-mute flag, not raw self_mute, because PTT also sets self_mute const userManuallyMuted = LocalVoiceStateStore.getHasUserSetMute() && LocalVoiceStateStore.getSelfMute(); if (KeybindStore.isPushToTalkEffective() && KeybindStore.isPushToTalkMuted(userManuallyMuted)) return 'push_to_talk'; if (selfMuted) return 'self'; return null; } The hasUserSetMute flag in LocalVoiceStateStore is exactly the distinction needed — it's only set to true when the user explicitly toggles mute via toggleSelfMute(), never when PTT calls updateSelfMute(). Bug 3 (MEDIUM): pushToTalkHeld is set to false immediately on key release, before the release delay fires In KeybindStore.ts line 613-627, handlePushToTalkRelease sets this.pushToTalkHeld = false immediately. But in KeybindManager.ts line 566-572, applyPushToTalkHold(false) (which actually mutes the mic) runs after pushToTalkReleaseDelay ms. During that delay window, the MobX-observable pushToTalkHeld is false while the mic is still live. Any UI reading isPushToTalkMuted() sees the user as PTT-muted when they're actually still transmitting. This causes a visual flicker in the mute indicator during the release delay. Fix — option A (in KeybindStore.ts): Don't set pushToTalkHeld = false in handlePushToTalkRelease. Let applyPushToTalkHold(false) (called after the delay) handle it via setPushToTalkHeld(false): tshandlePushToTalkRelease(nowMs: number = Date.now()): boolean { const pressDuration = nowMs - this.pushToTalkPressTime; if (this.pushToTalkLatching && pressDuration < LATCH_TAP_THRESHOLD_MS && !this.pushToTalkLatched) { runInAction(() => { this.pushToTalkLatched = true; }); return false; } // Don't set pushToTalkHeld = false here — let the delayed // applyPushToTalkHold(false) do it so UI stays consistent // during the release delay window. return true; } This works because applyPushToTalkHold in VoiceAudioManager.ts line 84 already calls KeybindStore.setPushToTalkHeld(held), so the state will be set to false when the delay fires. Bug 4 (MEDIUM): No UI to enable global PTT on desktop The PTT keybind defaults to global: false. VoiceTab preserves whatever global was previously set (global: pttKeybind.combo.global). refreshGlobalKeyHook in KeybindManager line 330 requires pttKeybind.combo.global to be true to start the system-wide key hook. But there's no toggle in VoiceTab to flip global to true. This means even on the native desktop app, PTT is local-only (only works when the app has focus) unless something else sets global: true. I don't see that happening anywhere. Fix in VoiceTab.tsx: Add a global shortcut toggle for desktop users, or auto-enable global for PTT on desktop: tsx{isPushToTalk && isNativeDesktop && !isPttLimited && ( <Switch label={<Trans>System-wide Push-to-Talk</Trans>} description={<Trans>Works even when Fluxer is not focused</Trans>} value={pttKeybind.combo.global ?? false} onChange={(value) => { KeybindStore.setKeybind('push_to_talk', { ...pttKeybind.combo, global: value, }); }} /> )} Alternatively, if you want it on by default for desktop, set it in the onChange when recording a new key: tsxonChange={(combo) => { KeybindStore.setKeybind('push_to_talk', { ...combo, global: isNativeDesktop && !isPttLimited, // auto-enable on capable desktops }); }} Bug 5 (LOW): PTT sound effects exist but are never played You have ptt-active.mp3 and ptt-inactive.mp3 in the sounds directory, but the PTT handler in KeybindManager.ts (line 554-573) never plays them. If you want audio feedback: ts// In the push_to_talk handler in KeybindManager.ts this.register('push_to_talk', ({type}) => { if (type === 'press') { // ... existing press logic ... if (shouldUnmute) { SoundActionCreators.playSound(SoundType.PttActive); // add this MediaEngineStore.applyPushToTalkHold(true); } } else { const shouldMute = KeybindStore.handlePushToTalkRelease(); if (shouldMute) { const delay = KeybindStore.pushToTalkReleaseDelay; this.pttReleaseTimer = setTimeout(() => { this.pttReleaseTimer = null; SoundActionCreators.playSound(SoundType.PttInactive); // add this MediaEngineStore.applyPushToTalkHold(false); }, delay); } } }); (You'd need to add PttActive/PttInactive to the SoundType enum and register the sound files.)
Comment by @wittzzarU
RexSystem 1 vote originally by @wittzzarU on GitHub
Adding onto this issue, I'm unable to use keys like CTRL, ALT, or shift for a keybind as they never register as a key while using the input. The input modal is asking for a keypress and when you press one of those buttons, the Reset button appears as if you typed in a key, but there's nothing in the box. stable (d90628a), 2026-02-16 10:10:38 UTC, Electron 39.2.7, macOS 14.7.6 (arm64), desktop stable 0.0.8 image
My friend uses alt for ptt on discord and he really doesn't like not being able to ptt on fluxer. I hope this gets fixed.
  • 550722895-84700829-9494-4045-8910-1eb979ace810.png

    550722895-84700829-9494-4045-8910-1eb979ace810.png

    373×207 | 14 kB