33// Ice
44//
55
6+ import AppKit
67import Combine
78import Foundation
89
@@ -27,6 +28,14 @@ final class GeneralSettingsManager: ObservableObject {
2728 /// in a separate bar below the menu bar.
2829 @Published var useIceBar = false
2930
31+ /// A Boolean value that indicates whether Ice Bar should be
32+ /// automatically enabled on built-in displays.
33+ @Published var autoEnableIceBarOnBuiltInDisplay = false
34+
35+ /// The screen width threshold (in pixels) below which Ice Bar is enabled.
36+ /// Ice Bar will be enabled when screen width < threshold.
37+ @Published var iceBarDisplayWidthThreshold : Double = 3000
38+
3039 /// The location where the Ice Bar appears.
3140 @Published var iceBarLocation : IceBarLocation = . dynamic
3241
@@ -78,12 +87,16 @@ final class GeneralSettingsManager: ObservableObject {
7887 func performSetup( ) {
7988 loadInitialState ( )
8089 configureCancellables ( )
90+ observeScreenChanges ( )
91+ updateIceBarForCurrentDisplay ( )
8192 }
8293
8394 private func loadInitialState( ) {
8495 Defaults . ifPresent ( key: . showIceIcon, assign: & showIceIcon)
8596 Defaults . ifPresent ( key: . customIceIconIsTemplate, assign: & customIceIconIsTemplate)
8697 Defaults . ifPresent ( key: . useIceBar, assign: & useIceBar)
98+ Defaults . ifPresent ( key: . autoEnableIceBarOnBuiltInDisplay, assign: & autoEnableIceBarOnBuiltInDisplay)
99+ Defaults . ifPresent ( key: . iceBarDisplayWidthThreshold, assign: & iceBarDisplayWidthThreshold)
87100 Defaults . ifPresent ( key: . showOnClick, assign: & showOnClick)
88101 Defaults . ifPresent ( key: . showOnHover, assign: & showOnHover)
89102 Defaults . ifPresent ( key: . showOnScroll, assign: & showOnScroll)
@@ -156,6 +169,24 @@ final class GeneralSettingsManager: ObservableObject {
156169 }
157170 . store ( in: & c)
158171
172+ $autoEnableIceBarOnBuiltInDisplay
173+ . receive ( on: DispatchQueue . main)
174+ . sink { [ weak self] autoEnable in
175+ Defaults . set ( autoEnable, forKey: . autoEnableIceBarOnBuiltInDisplay)
176+ if autoEnable {
177+ self ? . updateIceBarForCurrentDisplay ( )
178+ }
179+ }
180+ . store ( in: & c)
181+
182+ $iceBarDisplayWidthThreshold
183+ . receive ( on: DispatchQueue . main)
184+ . sink { [ weak self] threshold in
185+ Defaults . set ( threshold, forKey: . iceBarDisplayWidthThreshold)
186+ self ? . updateIceBarForCurrentDisplay ( )
187+ }
188+ . store ( in: & c)
189+
159190 $iceBarLocation
160191 . receive ( on: DispatchQueue . main)
161192 . sink { location in
@@ -215,6 +246,32 @@ final class GeneralSettingsManager: ObservableObject {
215246
216247 cancellables = c
217248 }
249+
250+ /// Updates the Ice Bar setting based on the current display configuration.
251+ private func updateIceBarForCurrentDisplay( ) {
252+ guard autoEnableIceBarOnBuiltInDisplay else {
253+ return
254+ }
255+
256+ // Get the main screen (where the menu bar is)
257+ guard let mainScreen = NSScreen . main else {
258+ return
259+ }
260+
261+ // Enable Ice Bar if screen width is less than threshold
262+ let screenWidth = mainScreen. frame. width
263+ useIceBar = screenWidth < iceBarDisplayWidthThreshold
264+ }
265+
266+ /// Sets up an observer for screen configuration changes.
267+ func observeScreenChanges( ) {
268+ NotificationCenter . default. publisher ( for: NSApplication . didChangeScreenParametersNotification)
269+ . receive ( on: DispatchQueue . main)
270+ . sink { [ weak self] _ in
271+ self ? . updateIceBarForCurrentDisplay ( )
272+ }
273+ . store ( in: & cancellables)
274+ }
218275}
219276
220277// MARK: GeneralSettingsManager: BindingExposable
0 commit comments