diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
index 54ae2d4..62c5a67 100644
--- a/MainWindow.xaml.cs
+++ b/MainWindow.xaml.cs
@@ -201,6 +201,10 @@ public partial class MainWindow : Window
if (form.IsDrawerOpen) form.CloseDrawerCommand.Execute(null);
if (ypp.IsDrawerOpen) ypp.CloseDrawerCommand.Execute(null);
if (test.IsDrawerOpen) test.CloseDrawerCommand.Execute(null);
+ // The Settings (gear) and Socials drawers live in the same host but were left out of this
+ // guard, so clicking anywhere else left them open (reported 2026-11-05).
+ _viewModel.CloseSettingsDrawerIfOpen();
+ _viewModel.CloseSocialsDrawer();
}
if (_previewPane.IsClickInsidePreview(original)) return;
if (_leftPanel.IsClickInside(original)) return;
diff --git a/ViewModels/MainViewModel.Settings.cs b/ViewModels/MainViewModel.Settings.cs
index eed7027..2b68d26 100644
--- a/ViewModels/MainViewModel.Settings.cs
+++ b/ViewModels/MainViewModel.Settings.cs
@@ -34,8 +34,9 @@ public partial class MainViewModel
SettingsDrawerOpen = true;
}
- /// Called by the other drawers when they open, so settings yields to them.
- private void CloseSettingsDrawerIfOpen()
+ /// Called by the other drawers when they open, so settings yields to them — and by the
+ /// window's click-outside guard, so the gear tab retracts like every other drawer (2026-11-05).
+ internal void CloseSettingsDrawerIfOpen()
{
if (_settingsDrawerOpen) SettingsDrawerOpen = false;
}
diff --git a/ytLive.Tests/DrawerOutsideClickTests.cs b/ytLive.Tests/DrawerOutsideClickTests.cs
new file mode 100644
index 0000000..a4bba72
--- /dev/null
+++ b/ytLive.Tests/DrawerOutsideClickTests.cs
@@ -0,0 +1,75 @@
+using System;
+using System.IO;
+using System.Windows;
+using System.Windows.Input;
+using Microsoft.Data.Sqlite;
+using Xunit;
+using ytLive.ViewModels;
+
+namespace ytLive.Tests;
+
+///
+/// 2026-11-05 report: "the gear-icon tab and the socials tab do not retract when I click off the div,
+/// like the other tabs." Both drawers live in the same host as Stream Settings / YPP / TEST, but the
+/// window's click-outside guard only knew about the other three.
+///
+[Collection("RealApp")]
+public sealed class DrawerOutsideClickTests
+{
+ private readonly RealAppHost _app;
+
+ public DrawerOutsideClickTests(RealAppHost app) => _app = app;
+
+ [Fact]
+ public void ClickingOutside_RetractsTheSettingsAndSocialsDrawers()
+ {
+ _app.Run(() =>
+ {
+ var tempDb = Path.Combine(Path.GetTempPath(), $"ytLlive-drawers-{Guid.NewGuid():N}.db");
+ MainViewModel.LayoutPathOverride = tempDb;
+ var window = new MainWindow();
+ var vm = (MainViewModel)window.DataContext;
+ try
+ {
+ window.Show();
+ window.UpdateLayout();
+
+ // Open the gear drawer, then click somewhere that is not the drawer host.
+ vm.ToggleSettingsDrawer();
+ Assert.True(vm.SettingsDrawerOpen);
+
+ RaiseOutsideClick(window);
+ Assert.False(vm.SettingsDrawerOpen);
+
+ // …and clicking INSIDE the drawer must not close it, or the panel would be unusable.
+ vm.ToggleSettingsDrawer();
+ Assert.True(vm.SettingsDrawerOpen);
+ var pane = (System.Windows.Controls.UserControl)window.FindName("PreviewPane")!;
+ var host = (FrameworkElement)pane.FindName("TextPullOutHost")!;
+ RaiseClickOn(host);
+ Assert.True(vm.SettingsDrawerOpen);
+ }
+ finally
+ {
+ window.Close();
+ MainViewModel.LayoutPathOverride = null;
+ SqliteConnection.ClearAllPools();
+ try { File.Delete(tempDb); } catch { /* best-effort cleanup */ }
+ }
+ });
+ }
+
+ /// A left-button-down that originates on the window itself — outside the preview, the left
+ /// panel and the drawer host, which is exactly the case the guard handles.
+ private static void RaiseOutsideClick(Window window) => RaiseClickOn(window);
+
+ private static void RaiseClickOn(UIElement target)
+ {
+ var args = new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, MouseButton.Left)
+ {
+ RoutedEvent = UIElement.PreviewMouseLeftButtonDownEvent,
+ Source = target,
+ };
+ target.RaiseEvent(args);
+ }
+}