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;