Skip to content

Commit 9ef34bb

Browse files
authored
fix: Desaturate the selection color when the application looses focus (#16)
1 parent 7e1dd8a commit 9ef34bb

3 files changed

Lines changed: 28 additions & 6 deletions

File tree

Example/Example/Views/Cell.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,13 @@ struct Cell: View {
3636

3737
@Environment(\.isSelected) var isSelected
3838
@Environment(\.highlightState) var highlightState
39+
@Environment(\.selectionColor) var selectionColor
3940

4041
var item: Item
4142
var isPainted: Bool
4243

4344
var strokeColor: Color {
44-
return isSelected || highlightState == .forSelection ? Color.accentColor : Color.clear
45+
return isSelected || highlightState == .forSelection ? selectionColor : Color.clear
4546
}
4647

4748
var body: some View {

Sources/SelectableCollectionView/Views/CollectionViewContainer.swift

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#if os(macOS)
2222

2323
import Carbon
24+
import Combine
2425
import SwiftUI
2526

2627
import SelectableCollectionViewMacResources
@@ -83,6 +84,7 @@ public class CollectionViewContainer<Element: Hashable, Content: View>: NSView,
8384
private let scrollView: CustomScrollView
8485
private let collectionView: InteractiveCollectionView
8586
private var dataSource: DataSource? = nil
87+
private var cancellables: Set<AnyCancellable> = []
8688

8789
var provider: ((Element) -> Content?)? = nil
8890

@@ -105,7 +107,9 @@ public class CollectionViewContainer<Element: Hashable, Content: View>: NSView,
105107
else {
106108
return ShortcutItemView()
107109
}
108-
view.configure(AnyView(content), parentHasFocus: collectionView.isFirstResponder)
110+
view.configure(AnyView(content),
111+
parentHasFocus: collectionView.isFirstResponder,
112+
parentIsKey: collectionView.window?.isKeyWindow ?? false)
109113
view.element = item
110114
return view
111115
}
@@ -129,6 +133,18 @@ public class CollectionViewContainer<Element: Hashable, Content: View>: NSView,
129133

130134
collectionView.isSelectable = true
131135
collectionView.allowsMultipleSelection = true
136+
137+
// Observe application activity notifications to allow us to update the selection color.
138+
let notificationCenter = NotificationCenter.default
139+
notificationCenter
140+
.publisher(for: NSApplication.didBecomeActiveNotification)
141+
.combineLatest(notificationCenter
142+
.publisher(for: NSApplication.didResignActiveNotification))
143+
.receive(on: DispatchQueue.main)
144+
.sink { [weak self] _ in
145+
self?.updateSelection()
146+
}
147+
.store(in: &cancellables)
132148
}
133149

134150
required init?(coder: NSCoder) {
@@ -150,7 +166,9 @@ public class CollectionViewContainer<Element: Hashable, Content: View>: NSView,
150166
continue
151167
}
152168
let content = self.delegate?.collectionViewContainer(self, contentForElement: element)
153-
item.configure(AnyView(content), parentHasFocus: collectionView.isFirstResponder)
169+
item.configure(AnyView(content),
170+
parentHasFocus: collectionView.isFirstResponder,
171+
parentIsKey: collectionView.window?.isKeyWindow ?? false)
154172
}
155173

156174
// Update the selection

Sources/SelectableCollectionView/Views/ShortcutItemView.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class ShortcutItemView: NSCollectionViewItem {
5353
}
5454

5555
private var parentHasFocus: Bool = false
56+
private var parentIsKey: Bool = false
5657

5758
override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) {
5859
super.init(nibName: nil, bundle: Resources.bundle)
@@ -63,10 +64,11 @@ class ShortcutItemView: NSCollectionViewItem {
6364
}
6465

6566
private func host(_ content: AnyView) {
67+
6668
let modifiedContent = AnyView(content
6769
.environment(\.isSelected, isSelected)
6870
.environment(\.highlightState, .init(highlightState))
69-
.environment(\.selectionColor, parentHasFocus ? Color(nsColor: .selectedContentBackgroundColor) : Color(nsColor: .unemphasizedSelectedContentBackgroundColor)))
71+
.environment(\.selectionColor, parentHasFocus && parentIsKey ? Color(nsColor: .selectedContentBackgroundColor) : Color(nsColor: .unemphasizedSelectedContentBackgroundColor)))
7072
if let hostingView = hostingView {
7173
hostingView.rootView = modifiedContent
7274
} else {
@@ -81,14 +83,15 @@ class ShortcutItemView: NSCollectionViewItem {
8183
#warning("TODO: Not sure if this is necessary")
8284
override func prepareForReuse() {
8385
super.prepareForReuse()
84-
configure(AnyView(EmptyView()), parentHasFocus: false)
86+
configure(AnyView(EmptyView()), parentHasFocus: false, parentIsKey: false)
8587
}
8688

8789
#warning("TODO: Called by the data source")
8890
#warning("TODO: This should take an item")
89-
func configure(_ content: AnyView, parentHasFocus: Bool) {
91+
func configure(_ content: AnyView, parentHasFocus: Bool, parentIsKey: Bool) {
9092
self.content = content
9193
self.parentHasFocus = parentHasFocus
94+
self.parentIsKey = parentIsKey
9295
host(content)
9396
}
9497

0 commit comments

Comments
 (0)