From bbe8e5ee236f72a1efae0cffd4b09087a48ee0d7 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 5 Nov 2026 18:28:12 +0000 Subject: [PATCH] Hide the selected-tab overline in unfocused windows [patch] ImGuiPaletteMapper mapped TabDimmedSelectedOverline to the same opaque Primary High as TabSelectedOverline, so every dock node's selected tab carried the focused-window accent line and nothing showed which window had focus. Give the dimmed overline an alpha of 0, as ImGui's stock styles do, and test across every built-in theme that only the focused selected tab has an overline. Fixes #164 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017vfJW25U4pSY6LX1PUqHvi --- ThemeProvider.ImGui/ImGuiPaletteMapper.cs | 3 +++ ThemeProvider.Test/ImGuiPaletteMapperTests.cs | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/ThemeProvider.ImGui/ImGuiPaletteMapper.cs b/ThemeProvider.ImGui/ImGuiPaletteMapper.cs index 8f51942..2765652 100644 --- a/ThemeProvider.ImGui/ImGuiPaletteMapper.cs +++ b/ThemeProvider.ImGui/ImGuiPaletteMapper.cs @@ -128,6 +128,9 @@ public IReadOnlyDictionary MapTheme(ISemanticTheme theme) // Striped rows hold input frames, which are drawn in FrameBg with no border by default. A // translucent stripe lands between the row and frame colors, so a frame in an odd row stays visible. { ImGuiCol.TableRowBgAlt, 0.50f }, + // The overline marks the focused window's selected tab, so an unfocused window's selected tab + // draws none, as in ImGui's stock styles. Drawing it in both made every dock node look focused. + { ImGuiCol.TabDimmedSelectedOverline, 0f }, }; // Convert the semantic colors to ImGui Vector4 format diff --git a/ThemeProvider.Test/ImGuiPaletteMapperTests.cs b/ThemeProvider.Test/ImGuiPaletteMapperTests.cs index c98873b..b6d8628 100644 --- a/ThemeProvider.Test/ImGuiPaletteMapperTests.cs +++ b/ThemeProvider.Test/ImGuiPaletteMapperTests.cs @@ -254,6 +254,26 @@ public void MapTheme_SelectedTabsDifferFromTheirTabBar() } } + /// + /// ImGui draws TabSelectedOverline on the focused window's selected tab and TabDimmedSelectedOverline on + /// every unfocused one's. The overline is the cue for which window has focus, so only the focused one may + /// show it: the dimmed overline is transparent, as in ImGui's stock styles. + /// + [TestMethod] + public void MapTheme_OnlyTheFocusedSelectedTabHasAnOverline() + { + ImGuiPaletteMapper mapper = new(); + + foreach (ThemeRegistry.ThemeInfo info in ThemeRegistry.AllThemes) + { + IReadOnlyDictionary palette = mapper.MapTheme(info.CreateInstance()); + + Assert.AreEqual(1f, palette[ImGuiCol.TabSelectedOverline].W, $"{info.Name}: the focused tab's overline is not opaque"); + Assert.AreEqual(0f, palette[ImGuiCol.TabDimmedSelectedOverline].W, $"{info.Name}: an unfocused window's selected tab draws an overline"); + AssertDistinct(palette, ImGuiCol.TabDimmedSelectedOverline, ImGuiCol.TabSelectedOverline, info.Name); + } + } + private static void AssertDistinct(IReadOnlyDictionary palette, ImGuiCol first, ImGuiCol second, string themeName) => Assert.IsGreaterThan(1f / 255f, Vector4.Distance(palette[first], palette[second]), $"{themeName}: {first} is drawn in the {second} color");