Screen backdrop (schema v5/v6) + five-scene catalog + webcam polish: live desktop/game capture as a permanent non-deletable bottom layer (Source.IsBackdrop), auto full-screen game detection (Win32FullScreenDetector) else primary display, GraphicsCapturePicker re-designation, refcounted shared ScreenCaptureManager, Live-only backdrop by policy (HasBackdrop + v5-v6 backfill + EnforceBackdropPolicy, checkbox gone), SceneCatalog (Starting/Live/BRB/Chat/Ending) with + button re-adding missing scenes, webcam mid-session transparent-container fix (GetPreviewBitmap propagation), Chat half-screen-area cap, 'Add Webcam' always opens the picker (SwapWebcamIdentityAsync, no silent resurrect), WindowsRuntimeMarshal frame-read + 5s-throttled errors, docs updated, tests (65 passing)

This commit is contained in:
2026-08-07 14:15:50 -07:00
parent e037ba027b
commit ad9b3e1e48
27 changed files with 2232 additions and 116 deletions
+39 -7
View File
@@ -6,16 +6,21 @@ namespace ytLive.Tests;
/// <summary>
/// The webcam size safeguard: no scene placement may exceed half the 1920×1080
/// master frame (960×540), nor drop below 10% of it (192×108). Enforced at
/// resize (MainWindow) and defensively again on every layout load.
/// master frame (960×540) — except the Chat scene, where it may reach half the
/// screen AREA (~1358×764 @16:9) — nor drop below 10% of the frame (192×108).
/// The cap is picked by canonical scene name. Enforced at resize (MainWindow)
/// and defensively again on every layout load.
/// </summary>
public class WebcamSafeguardTests
{
private const string DefaultScene = "Starting";
private const string ChatScene = "Chat";
[Fact]
public void Oversize_Webcam_Is_Capped_To_Half_The_Frame()
{
var webcam = new WebcamSceneConfig { Width = 1920, Height = 1080 };
MainViewModel.ClampWebcamToBounds(webcam);
MainViewModel.ClampWebcamToBounds(webcam, DefaultScene);
Assert.Equal(MainViewModel.WebcamMaxWidth, webcam.Width);
Assert.Equal(MainViewModel.WebcamMaxHeight, webcam.Height);
}
@@ -24,7 +29,7 @@ public class WebcamSafeguardTests
public void Wide_Webcam_Scales_To_Fit_Both_Dimensions()
{
var webcam = new WebcamSceneConfig { Width = 1000, Height = 500 };
MainViewModel.ClampWebcamToBounds(webcam);
MainViewModel.ClampWebcamToBounds(webcam, DefaultScene);
Assert.Equal(960, webcam.Width);
Assert.Equal(480, webcam.Height);
}
@@ -33,7 +38,7 @@ public class WebcamSafeguardTests
public void Tiny_Webcam_Is_Brought_Up_To_The_Minimum()
{
var webcam = new WebcamSceneConfig { Width = 10, Height = 10 };
MainViewModel.ClampWebcamToBounds(webcam);
MainViewModel.ClampWebcamToBounds(webcam, DefaultScene);
Assert.Equal(MainViewModel.WebcamMinWidth, webcam.Width);
Assert.Equal(MainViewModel.WebcamMinWidth, webcam.Height);
}
@@ -42,7 +47,7 @@ public class WebcamSafeguardTests
public void Short_Wide_Webcam_Meets_Both_Minimums()
{
var webcam = new WebcamSceneConfig { Width = 100, Height = 20 };
MainViewModel.ClampWebcamToBounds(webcam);
MainViewModel.ClampWebcamToBounds(webcam, DefaultScene);
Assert.True(webcam.Width >= MainViewModel.WebcamMinWidth);
Assert.Equal(MainViewModel.WebcamMinHeight, webcam.Height);
}
@@ -51,12 +56,39 @@ public class WebcamSafeguardTests
public void Round_Border_Size_Tracks_The_Shorter_Clamped_Dimension()
{
var webcam = new WebcamSceneConfig { Width = 1920, Height = 500 };
MainViewModel.ClampWebcamToBounds(webcam);
MainViewModel.ClampWebcamToBounds(webcam, DefaultScene);
Assert.Equal(960, webcam.Width);
Assert.Equal(250, webcam.Height);
Assert.Equal(250, webcam.RoundBorderSize);
}
[Fact]
public void Chat_Webcam_May_Reach_Half_The_Screen_Area()
{
var webcam = new WebcamSceneConfig { Width = 1920, Height = 1080 };
MainViewModel.ClampWebcamToBounds(webcam, ChatScene);
Assert.Equal(MainViewModel.WebcamChatMaxWidth, webcam.Width);
Assert.Equal(MainViewModel.WebcamChatMaxHeight, webcam.Height);
}
[Fact]
public void Chat_Webcam_At_The_Default_Size_Is_Not_Grown_Or_Shrunk()
{
var webcam = new WebcamSceneConfig { Width = 480, Height = 270 };
MainViewModel.ClampWebcamToBounds(webcam, ChatScene);
Assert.Equal(480, webcam.Width);
Assert.Equal(270, webcam.Height);
}
[Fact]
public void Renamed_Chat_Scene_Loses_The_Larger_Cap()
{
var webcam = new WebcamSceneConfig { Width = 1920, Height = 1080 };
MainViewModel.ClampWebcamToBounds(webcam, "chit-chat");
Assert.Equal(MainViewModel.WebcamMaxWidth, webcam.Width);
Assert.Equal(MainViewModel.WebcamMaxHeight, webcam.Height);
}
[Fact]
public void Round_Then_Back_To_Rect_Restores_The_Original_Aspect()
{