From 66ff7d50434aa7f1191270679f76de6e3ca289a8 Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Fri, 6 Feb 2026 19:44:57 +0700 Subject: [PATCH] fix: improve native tab bar appearance and dark mode handling Use performAsCurrentDrawingAppearance for correct colors during appearance transitions, track window key state for tab styling, and use accent-tinted selection instead of border-based highlight. --- OpenTable/Views/Editor/NativeTabBarView.swift | 4 +- .../Views/Editor/NativeTabItemView.swift | 59 +++++++++++++++---- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/OpenTable/Views/Editor/NativeTabBarView.swift b/OpenTable/Views/Editor/NativeTabBarView.swift index 9a5d0dd9c..7a6df522b 100644 --- a/OpenTable/Views/Editor/NativeTabBarView.swift +++ b/OpenTable/Views/Editor/NativeTabBarView.swift @@ -325,7 +325,9 @@ final class NativeTabBarView: NSView { override func viewDidChangeEffectiveAppearance() { super.viewDidChangeEffectiveAppearance() - layer?.backgroundColor = NSColor.windowBackgroundColor.cgColor + effectiveAppearance.performAsCurrentDrawingAppearance { + self.layer?.backgroundColor = NSColor.windowBackgroundColor.cgColor + } // Re-render tab items to update colors for snapshot in tabSnapshots { tabViews[snapshot.id]?.update( diff --git a/OpenTable/Views/Editor/NativeTabItemView.swift b/OpenTable/Views/Editor/NativeTabItemView.swift index 74b97e8b7..b8168b7c7 100644 --- a/OpenTable/Views/Editor/NativeTabItemView.swift +++ b/OpenTable/Views/Editor/NativeTabItemView.swift @@ -21,6 +21,7 @@ final class NativeTabItemView: NSView { private var tabType: TabType private var isSelected: Bool = false private var isHovered: Bool = false + private var isWindowKey: Bool = true // MARK: - Callbacks @@ -191,6 +192,43 @@ final class NativeTabItemView: NSView { statusIconLeadingConstraint?.isActive = true } + // MARK: - Window Key State + + override func viewDidMoveToWindow() { + super.viewDidMoveToWindow() + + NotificationCenter.default.removeObserver( + self, name: NSWindow.didBecomeKeyNotification, object: nil + ) + NotificationCenter.default.removeObserver( + self, name: NSWindow.didResignKeyNotification, object: nil + ) + + guard let window = window else { return } + isWindowKey = window.isKeyWindow + + NotificationCenter.default.addObserver( + self, selector: #selector(windowKeyStateChanged), + name: NSWindow.didBecomeKeyNotification, object: window + ) + NotificationCenter.default.addObserver( + self, selector: #selector(windowKeyStateChanged), + name: NSWindow.didResignKeyNotification, object: window + ) + + updateAppearance() + } + + @objc private func windowKeyStateChanged(_ notification: Notification) { + isWindowKey = window?.isKeyWindow ?? true + updateAppearance() + } + + override func viewDidChangeEffectiveAppearance() { + super.viewDidChangeEffectiveAppearance() + updateAppearance() + } + // MARK: - Drag Source private func setupDragSource() { @@ -239,18 +277,15 @@ final class NativeTabItemView: NSView { closeButton.isHidden = !isHovered || isPinned // Background - if isSelected { - layer?.backgroundColor = NSColor.controlBackgroundColor.cgColor - layer?.borderColor = NSColor.separatorColor.cgColor - layer?.borderWidth = 0.5 - } else if isHovered { - layer?.backgroundColor = NSColor.controlBackgroundColor.withAlphaComponent(0.5).cgColor - layer?.borderColor = nil - layer?.borderWidth = 0 - } else { - layer?.backgroundColor = nil - layer?.borderColor = nil - layer?.borderWidth = 0 + effectiveAppearance.performAsCurrentDrawingAppearance { + if self.isSelected { + self.layer?.backgroundColor = NSColor.controlAccentColor + .withAlphaComponent(0.15).cgColor + } else if self.isHovered { + self.layer?.backgroundColor = NSColor.quaternaryLabelColor.cgColor + } else { + self.layer?.backgroundColor = nil + } } }