From 540ec13a632170f7b3b4dd767091cb4fb513c061 Mon Sep 17 00:00:00 2001 From: Talon Date: Sat, 20 Jun 2026 15:16:17 +0200 Subject: [PATCH] feat(windows): add Ctrl+Shift hotkeys for voice, screen share, mute, deafen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ctrl+Shift+V — join/leave voice Ctrl+Shift+S — screen share toggle Ctrl+Shift+M — mute/unmute mic Ctrl+Shift+D — deafen/undeafen Focus-scoped (same as PTT). Shortcuts display in the Voice menu for the two menu-backed actions. Hotkeys are suppressed when a text box has focus. Co-Authored-By: Claude Sonnet 4.6 --- .../windows/VoiceCat.App/Forms/MainForm.cs | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/clients/windows/VoiceCat.App/Forms/MainForm.cs b/clients/windows/VoiceCat.App/Forms/MainForm.cs index 269a39d..5c99163 100644 --- a/clients/windows/VoiceCat.App/Forms/MainForm.cs +++ b/clients/windows/VoiceCat.App/Forms/MainForm.cs @@ -84,8 +84,9 @@ public partial class MainForm : Form btnRefreshDevices.Click += (_, _) => LoadInputDevices(); cboInputDevice.SelectedIndexChanged += CboInputDevice_SelectedIndexChanged; - // PTT (focus-scoped — works only while this form has focus; documented limitation) + // PTT and global hotkeys (focus-scoped — work only while this form has focus) KeyDown += MainForm_KeyDown; + KeyDown += MainForm_HotkeyDown; KeyUp += MainForm_KeyUp; Deactivate += (_, _) => { @@ -140,10 +141,12 @@ public partial class MainForm : Form _miJoinVoice = new ToolStripMenuItem("&Join Voice"); _miJoinVoice.Click += BtnMicToggle_Click; + _miJoinVoice.ShortcutKeyDisplayString = "Ctrl+Shift+V"; voiceMenu.DropDownItems.Add(_miJoinVoice); _miScreenShare = new ToolStripMenuItem("Share Screen &Audio"); _miScreenShare.Click += BtnScreenShareToggle_Click; + _miScreenShare.ShortcutKeyDisplayString = "Ctrl+Shift+S"; voiceMenu.DropDownItems.Add(_miScreenShare); menuStrip.Items.Add(voiceMenu); @@ -726,6 +729,33 @@ public partial class MainForm : Form e.Handled = true; } + private void MainForm_HotkeyDown(object? sender, KeyEventArgs e) + { + if (!e.Control || !e.Shift) return; + if (ActiveControl is TextBox or RichTextBox) return; + switch (e.KeyCode) + { + case Keys.V: + BtnMicToggle_Click(null, EventArgs.Empty); + e.Handled = true; + break; + case Keys.S: + BtnScreenShareToggle_Click(null, EventArgs.Empty); + e.Handled = true; + break; + case Keys.M: + chkMute.Checked = !chkMute.Checked; + ApplySelfMute(); + e.Handled = true; + break; + case Keys.D: + chkDeafen.Checked = !chkDeafen.Checked; + ApplySelfMute(); + e.Handled = true; + break; + } + } + private void MainForm_KeyUp(object? sender, KeyEventArgs e) { if (!radioPtt.Checked || e.KeyCode != _pttKey || _micStreamId == 0) return;