@@ -21,12 +21,6 @@ class MenuBarItemManager: ObservableObject {
2121
2222 private var cancellables = Set < AnyCancellable > ( )
2323
24- var isMenuOpen : Bool {
25- WindowInfo . getAllWindows ( ) . contains { window in
26- window. layer == 101
27- }
28- }
29-
3024 init ( appState: AppState ) {
3125 self . appState = appState
3226 }
@@ -51,6 +45,7 @@ class MenuBarItemManager: ObservableObject {
5145 cancellables = c
5246 }
5347
48+ /// Caches the current menu bar items.
5449 private func cacheMenuBarItems( ) {
5550 guard tempShownItemsInfo. isEmpty else {
5651 Logger . itemManager. info ( " Items are temporarily shown, so deferring cache " )
@@ -69,8 +64,8 @@ class MenuBarItemManager: ObservableObject {
6964 update ( & cachedMenuBarItems) { cachedItems in
7065 cachedItems. removeAll ( )
7166 for item in items {
72- // audio video module cannot be hidden
73- guard item. info != . audioVideoModule else {
67+ // only items that can be hidden should be included
68+ guard item. canBeHidden else {
7469 continue
7570 }
7671
@@ -102,6 +97,7 @@ class MenuBarItemManager: ObservableObject {
10297 }
10398 }
10499
100+ /// Gets the destination to return the given item to after it is temporarily shown.
105101 private func getReturnDestination( for item: MenuBarItem , in items: [ MenuBarItem ] ) -> MoveDestination ? {
106102 let info = item. info
107103 if let index = items. firstIndex ( where: { $0. info == info } ) {
@@ -114,6 +110,8 @@ class MenuBarItemManager: ObservableObject {
114110 return nil
115111 }
116112
113+ /// Schedules a timer for the given interval, attempting to rehide the current
114+ /// temporarily shown items when the timer fires.
117115 private func runTempShownItemTimer( for interval: TimeInterval ) {
118116 tempShownItemsTimer? . invalidate ( )
119117 tempShownItemsTimer = . scheduledTimer( withTimeInterval: interval, repeats: false ) { [ weak self] timer in
@@ -127,7 +125,19 @@ class MenuBarItemManager: ObservableObject {
127125 }
128126 }
129127
130- func tempShowItem( _ item: MenuBarItem ) {
128+ /// Temporarily shows the given item.
129+ ///
130+ /// This method moves the given item to the right of the control item for
131+ /// the "hidden" section. The item is cached alongside a destination that
132+ /// it will be automatically returned to. If `true` is passed to the
133+ /// `clickWhenFinished` parameter, the item is clicked once its movement
134+ /// is finished.
135+ ///
136+ /// - Parameters:
137+ /// - item: An item to show.
138+ /// - clickWhenFinished: A Boolean value that indicates whether the item
139+ /// should be clicked once its movement has finished.
140+ func tempShowItem( _ item: MenuBarItem , clickWhenFinished: Bool ) {
131141 let items = MenuBarItem . getMenuBarItemsPrivateAPI ( onScreenOnly: false )
132142
133143 guard let destination = getReturnDestination ( for: item, in: items) else {
@@ -142,19 +152,31 @@ class MenuBarItemManager: ObservableObject {
142152 tempShownItemsInfo. append ( ( item, destination) )
143153
144154 Task {
145- MouseCursor . hide ( )
146- do {
147- try await slowMove ( item: item, to: . rightOfItem( hiddenControlItem) )
148- try await leftClick ( item: item)
149- } catch {
150- Logger . itemManager. error ( " ERROR: \( error) " )
155+ if clickWhenFinished {
156+ MouseCursor . hide ( )
157+ do {
158+ try await slowMove ( item: item, to: . rightOfItem( hiddenControlItem) )
159+ try await leftClick ( item: item)
160+ } catch {
161+ Logger . itemManager. error ( " ERROR: \( error) " )
162+ }
163+ MouseCursor . show ( )
164+ } else {
165+ do {
166+ try await move ( item: item, to: . rightOfItem( hiddenControlItem) )
167+ } catch {
168+ Logger . itemManager. error ( " ERROR: \( error) " )
169+ }
151170 }
152- MouseCursor . show ( )
153171 }
154172
155173 runTempShownItemTimer ( for: 20 )
156174 }
157175
176+ /// Rehides all temporarily shown items.
177+ ///
178+ /// If an item is currently showing its menu, this method waits for the menu
179+ /// to close before hiding the items.
158180 func rehideTempShownItems( ) async {
159181 if let menuWindow = WindowInfo . getAllWindows ( ) . first ( where: { $0. layer == 101 } ) {
160182 let menuCheckTask = Task . detached ( timeout: . seconds( 1 ) ) {
@@ -184,7 +206,11 @@ class MenuBarItemManager: ObservableObject {
184206 tempShownItemsTimer = nil
185207 }
186208
187- func removeTempShownItem( with info: MenuBarItemInfo ) {
209+ /// Removes a temporarily shown item from the cache.
210+ ///
211+ /// This has the effect of ensuring that the item will not be returned to
212+ /// its previous location.
213+ func removeTempShownItemFromCache( with info: MenuBarItemInfo ) {
188214 tempShownItemsInfo. removeAll ( where: { $0. item. info == info } )
189215 }
190216}
@@ -200,6 +226,7 @@ extension MenuBarItemManager {
200226 /// The menu bar item will be moved to the right of the given menu bar item.
201227 case rightOfItem( MenuBarItem )
202228
229+ /// A string to use for logging purposes.
203230 var logString : String {
204231 switch self {
205232 case . leftOfItem( let item) :
@@ -886,5 +913,4 @@ private extension CGEvent {
886913private extension Logger {
887914 static let itemManager = Logger ( category: " MenuBarItemManager " )
888915 static let move = Logger ( category: " Move " )
889- static let arrange = Logger ( category: " Arrange " )
890916}
0 commit comments