feat(windows): wire screen-audio sharing into the WinForms client

The core already supported SCREEN_AUDIO capture on Windows (post-M3 WASAPI
loopback via VOICECAT_HAS_LOOPBACK) and the C# Interop layer was complete
(VcStreamKind.ScreenAudio, StartStream/StopStream/SetRemoteStream). Only the
UI was missing -- no core, proto, or C ABI changes needed.

Adds a 'Share Screen Audio' toggle to the voice panel, independent of mic
voice (can share without joining voice). Disconnect/teardown now stops the
screen stream cleanly. New smoke test exercises the full StartStream ->
StreamStarted -> StopStream -> StreamStopped path through P/Invoke.
This commit is contained in:
2026-06-17 22:47:28 +02:00
parent 2185d9d15c
commit a88656f2fa
4 changed files with 140 additions and 0 deletions

View File

@@ -36,6 +36,7 @@ partial class MainForm
private FlowLayoutPanel flpVoiceTop = null!;
private FlowLayoutPanel flpVoiceBottom = null!;
private Button btnMicToggle = null!;
private Button btnScreenShareToggle = null!;
private CheckBox chkMute = null!;
private CheckBox chkDeafen = null!;
private RadioButton radioVad = null!;
@@ -81,6 +82,7 @@ partial class MainForm
flpVoiceTop = new FlowLayoutPanel();
flpVoiceBottom = new FlowLayoutPanel();
btnMicToggle = new Button();
btnScreenShareToggle = new Button();
chkMute = new CheckBox();
chkDeafen = new CheckBox();
radioVad = new RadioButton();
@@ -227,6 +229,20 @@ partial class MainForm
btnMicToggle.Margin = new Padding(0, 2, 6, 0);
btnMicToggle.TabIndex = 0;
// Screen-audio share — independent of mic voice (can share without joining voice and
// vice versa). The core's WASAPI loopback path (VOICECAT_HAS_LOOPBACK, always on for
// the windows-client preset) captures the default render endpoint; see docs/voice.md
// §9. Whole-device loopback inherently re-captures this app's own incoming voice mix —
// an accepted self-echo characteristic, not a bug.
btnScreenShareToggle.Text = "Share Screen &Audio";
btnScreenShareToggle.AccessibleName = "Share screen audio";
btnScreenShareToggle.AccessibleDescription =
"Start or stop sharing your computer's audio (desktop/system audio) with the channel. " +
"Independent of the microphone. Captures everything playing through your default speakers.";
btnScreenShareToggle.AutoSize = true;
btnScreenShareToggle.Margin = new Padding(0, 2, 12, 0);
btnScreenShareToggle.TabIndex = 10;
chkMute.Text = "&Mute mic";
chkMute.AutoSize = true;
chkMute.Enabled = false;
@@ -276,6 +292,7 @@ partial class MainForm
flpVoiceTop.AutoSize = false;
flpVoiceTop.Padding = new Padding(4, 2, 4, 0);
flpVoiceTop.Controls.Add(btnMicToggle);
flpVoiceTop.Controls.Add(btnScreenShareToggle);
flpVoiceTop.Controls.Add(chkMute);
flpVoiceTop.Controls.Add(chkDeafen);
flpVoiceTop.Controls.Add(lblMode);