fix: reload tint colors while running

This commit is contained in:
2026-10-22 16:07:22 +02:00
parent c48ef4c018
commit 1b171c7b52
18 changed files with 877 additions and 61 deletions
+60 -5
View File
@@ -6,6 +6,7 @@ import ApplicationServices
@MainActor
final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSearchFieldDelegate, NSTableViewDataSource, NSTableViewDelegate {
private let searchField = NSSearchField()
private var themeObservation: ThemeObservation?
private let searchSymbol = IconView(font: .systemFont(ofSize: 20))
private let commandBack = NSButton(title: "", target: nil, action: nil)
private let translationHeader = NSStackView()
@@ -400,6 +401,17 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
}
window.initialFirstResponder = searchField
launcherViews = [header, sectionLabel, scrollView, emptyLabel, footer]
themeObservation = ThemeObservation { [weak self, weak content] in
guard let self else { return }
self.searchField.applyTheme()
(self.searchField.currentEditor() as? NSTextView)?.insertionPointColor = ThemePalette.accent
self.searchSymbol.contentTintColor = ThemePalette.accent
self.commandBack.contentTintColor = ThemePalette.secondaryText
for label in [self.sectionLabel, self.statusLabel, self.emptyLabel] {
label.textColor = ThemePalette.secondaryText
}
content?.layer?.borderColor = ThemePalette.secondaryText.withAlphaComponent(0.22).cgColor
}
}
private func refreshApplications() {
@@ -1015,12 +1027,28 @@ final class ApplicationCell: NSTableCellView {
private static let opaqueMask = [NSColor.black.cgColor, NSColor.black.cgColor]
private static let fadedMask = [NSColor.black.cgColor, NSColor.clear.cgColor]
private static let timing = CAMediaTimingFunction(name: .easeOut)
static let applicationKind = NSAttributedString(string: "Application", attributes: [
private static var kindColor = ThemePalette.secondaryText
private static var cachedApplicationKind = NSAttributedString(string: "Application", attributes: [
.font: NSFont.systemFont(ofSize: LauncherRowView.textSize), .foregroundColor: ThemePalette.secondaryText
])
static let commandKind = NSAttributedString(string: "Command", attributes: applicationKind.attributes(at: 0, effectiveRange: nil))
static let favoriteKind = favorited(applicationKind)
static let favoriteCommandKind = favorited(commandKind)
private static var cachedCommandKind = NSAttributedString(string: "Command", attributes: cachedApplicationKind.attributes(at: 0, effectiveRange: nil))
private static var cachedFavoriteKind = favorited(cachedApplicationKind)
private static var cachedFavoriteCommandKind = favorited(cachedCommandKind)
static var applicationKind: NSAttributedString { refreshKinds(); return cachedApplicationKind }
static var commandKind: NSAttributedString { refreshKinds(); return cachedCommandKind }
static var favoriteKind: NSAttributedString { refreshKinds(); return cachedFavoriteKind }
static var favoriteCommandKind: NSAttributedString { refreshKinds(); return cachedFavoriteCommandKind }
private static func refreshKinds() {
guard kindColor != ThemePalette.secondaryText else { return }
kindColor = ThemePalette.secondaryText
cachedApplicationKind = NSAttributedString(string: "Application", attributes: [
.font: NSFont.systemFont(ofSize: LauncherRowView.textSize), .foregroundColor: kindColor
])
cachedCommandKind = NSAttributedString(string: "Command", attributes: cachedApplicationKind.attributes(at: 0, effectiveRange: nil))
cachedFavoriteKind = favorited(cachedApplicationKind)
cachedFavoriteCommandKind = favorited(cachedCommandKind)
}
private static func favorited(_ kind: NSAttributedString) -> NSAttributedString {
let font = kind.attribute(.font, at: 0, effectiveRange: nil) as! NSFont
@@ -1041,12 +1069,13 @@ final class ApplicationCell: NSTableCellView {
let locationLabel = NSTextField(labelWithString: "")
let kindLabel = NSTextField(labelWithString: "Application")
let numberHint = ShortcutIndicator(
"1", backgroundColor: ThemePalette.keyBackground,
"1", hasBackground: true,
fontSize: 10, keySize: 20
)
private let kindFade = CAGradientLayer()
private var numberHintVisible = false
private var hintGeneration = 0
private var themeObservation: ThemeObservation?
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
@@ -1094,10 +1123,28 @@ final class ApplicationCell: NSTableCellView {
numberHint.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8),
numberHint.centerYAnchor.constraint(equalTo: centerYAnchor),
])
themeObservation = ThemeObservation { [weak self] in self?.applyTheme() }
}
required init?(coder: NSCoder) { fatalError("Conjure creates application cells programmatically") }
private func applyTheme() {
Self.refreshKinds()
textField?.textColor = ThemePalette.text
locationLabel.textColor = ThemePalette.secondaryText
let kind = kindLabel.stringValue
let favorite = kindLabel.attributedStringValue.length > 0
&& kindLabel.attributedStringValue.attribute(.attachment, at: 0, effectiveRange: nil) != nil
if kind.hasSuffix("Application") {
kindLabel.attributedStringValue = favorite ? Self.favoriteKind : Self.applicationKind
} else if kind.hasSuffix("Command") {
kindLabel.attributedStringValue = favorite ? Self.favoriteCommandKind : Self.commandKind
} else {
kindLabel.textColor = ThemePalette.secondaryText
}
if imageView?.contentTintColor != nil { imageView?.contentTintColor = ThemePalette.accent }
}
override func layout() {
super.layout()
updateKindFadeGeometry()
@@ -1400,6 +1447,14 @@ final class LauncherRowView: NSTableRowView {
static let rowHeight: CGFloat = 38
static let textSize: CGFloat = 14
static let iconToTextSpacing: CGFloat = 12
private var themeObservation: ThemeObservation?
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
themeObservation = ThemeObservation { [weak self] in self?.needsDisplay = true }
}
required init?(coder: NSCoder) { fatalError("Conjure creates result rows programmatically") }
var topSpacing: CGFloat = 0 {
didSet { needsLayout = true; needsDisplay = true }
}