From 9f8a2428a8e2cac359a68c8e3d3013e28e7e53f0 Mon Sep 17 00:00:00 2001 From: Steve Mendes Reis Date: Sun, 1 Nov 2026 13:25:42 +0100 Subject: [PATCH 1/2] fix: draw text-only focused workspaces without a fill in theme previews The sample bar in theme cards, the Theme page, setup and package pages filled the focused workspace for every indicator but `underline`, including `none`. Gruvbox and Notch use `none`, so their previews showed a block the bar never draws, and Gruvbox's orange block hid its orange focused number. The sample bar now fills the cell only for the `background` indicator, the default, as the bar does. Closes #400 --- Sources/StableBar/ThemeCard.swift | 3 ++- Tests/StableBarTests/ThemeCardTests.swift | 29 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Sources/StableBar/ThemeCard.swift b/Sources/StableBar/ThemeCard.swift index c373742..798a474 100644 --- a/Sources/StableBar/ThemeCard.swift +++ b/Sources/StableBar/ThemeCard.swift @@ -173,7 +173,8 @@ struct ThemeSampleBar: View { .padding(.top, look.defaults.paddingTop ?? appearance.paddingVertical) .padding(.bottom, look.defaults.paddingBottom ?? appearance.paddingVertical) .background { - if focused && workspace?.indicator != .underline { + // As on the bar: no indicator means the background one, and `none` leaves the focused label alone. + if focused && (workspace?.indicator ?? .background) == .background { RoundedRectangle(cornerRadius: style.cornerRadius ?? max(appearance.cornerRadius - 4, 0)) .fill(style.background?.shapeStyle ?? AnyShapeStyle(appearance.accent)) } diff --git a/Tests/StableBarTests/ThemeCardTests.swift b/Tests/StableBarTests/ThemeCardTests.swift index 124f902..fec9b38 100644 --- a/Tests/StableBarTests/ThemeCardTests.swift +++ b/Tests/StableBarTests/ThemeCardTests.swift @@ -52,6 +52,35 @@ final class ThemeCardTests: XCTestCase { } } + @MainActor func testSampleBarFillsTheFocusedWorkspaceOnlyForTheBackgroundIndicator() throws { + let fixture = try ThemeGalleryFixture() + defer { fixture.close() } + // Only the accent is magenta, so magenta pixels can only come from the focused workspace's fill. + for (indicator, fills) in [(#""indicator":"none","#, false), (#""indicator":"background","#, true), ("", true)] { + let choice = try fixture.theme(##""" + {"defaults":{"foreground":"#ffffff","accent":"#ff00ff","accentText":"#00ff00"}, + "workspaceDefaults":{\##(indicator)"style":{"states":{"focused":{"foreground":"#00ff00"}}}}} + """##, install: false) + let look = try ThemePreview(choice: choice, themesDirectory: fixture.themes).configuration(for: .dark) + let renderer = ImageRenderer(content: ThemeSampleBar(look: look).frame(width: 580)) + let bitmap = NSBitmapImageRep(cgImage: try XCTUnwrap(renderer.cgImage)) + var accentPixels = 0 + for y in 0.. 0.8, + color.redComponent > 0.8 && color.blueComponent > 0.8 && color.greenComponent < 0.2 { + accentPixels += 1 + } + } + } + if fills { + XCTAssertGreaterThan(accentPixels, 50, "The \(indicator.isEmpty ? "default" : indicator) indicator fills the focused workspace") + } else { + XCTAssertEqual(accentPixels, 0, "A text-only focused workspace has nothing behind it, as on the bar") + } + } + } + @MainActor func testEveryBundledThemeCardFitsTheProposedWidth() throws { let fixture = try ThemeGalleryFixture() defer { fixture.close() } From 984e0d89ee659e06d44613874472de9ba7bf724e Mon Sep 17 00:00:00 2001 From: Steve Mendes Reis Date: Sun, 1 Nov 2026 13:25:42 +0100 Subject: [PATCH 2/2] build: draw the Theme page as a scene The screens bot now draws Settings > Theme with every bundled theme's card. --- scenes/settings-theme.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 scenes/settings-theme.json diff --git a/scenes/settings-theme.json b/scenes/settings-theme.json new file mode 100644 index 0000000..51aa24a --- /dev/null +++ b/scenes/settings-theme.json @@ -0,0 +1,6 @@ +{ + "$schema": "../scene.schema.json", + "configuration": "../Resources/config.json", + "draw": "settings", + "section": "theme" +}