66import CoreGraphics
77import OSLog
88
9+ // MARK: - Logger Extension
10+
11+ private extension Logger {
12+ private static let subsystem = Bundle . main. bundleIdentifier ?? " "
13+
14+ /// Logger for mouse helper operations.
15+ static let mouseHelpers = Logger ( subsystem: subsystem, category: " MouseHelpers " )
16+ }
17+
918/// A namespace for mouse helper operations.
1019enum MouseHelpers {
20+ private static var cursorHideCount = 0
1121 /// Returns the location of the mouse cursor in the coordinate
1222 /// space used by `AppKit`, with the origin at the bottom left
1323 /// of the screen.
@@ -24,18 +34,28 @@ enum MouseHelpers {
2434
2535 /// Hides the mouse cursor and increments the hide cursor count.
2636 static func hideCursor( ) {
27- let result = CGDisplayHideCursor ( CGMainDisplayID ( ) )
28- if result != . success {
29- Logger . default. error ( " CGDisplayHideCursor failed with error \( result. logString, privacy: . public) " )
37+ cursorHideCount += 1
38+ if cursorHideCount == 1 {
39+ let result = CGDisplayHideCursor ( CGMainDisplayID ( ) )
40+ if result != . success {
41+ Logger . mouseHelpers. error ( " CGDisplayHideCursor failed with error \( result. logString, privacy: . public) " )
42+ cursorHideCount = 0 // Reset on failure
43+ }
3044 }
3145 }
3246
3347 /// Decrements the hide cursor count and shows the mouse cursor
3448 /// if the count is `0`.
3549 static func showCursor( ) {
36- let result = CGDisplayShowCursor ( CGMainDisplayID ( ) )
37- if result != . success {
38- Logger . default. error ( " CGDisplayShowCursor failed with error \( result. logString, privacy: . public) " )
50+ if cursorHideCount > 0 {
51+ cursorHideCount -= 1
52+ if cursorHideCount == 0 {
53+ let result = CGDisplayShowCursor ( CGMainDisplayID ( ) )
54+ if result != . success {
55+ Logger . mouseHelpers. error ( " CGDisplayShowCursor failed with error \( result. logString, privacy: . public) " )
56+ // Don't reset count on failure to prevent imbalance
57+ }
58+ }
3959 }
4060 }
4161
@@ -47,7 +67,7 @@ enum MouseHelpers {
4767 static func warpCursor( to point: CGPoint ) {
4868 let result = CGWarpMouseCursorPosition ( point)
4969 if result != . success {
50- Logger . default . error ( " CGWarpMouseCursorPosition failed with error \( result. logString, privacy: . public) " )
70+ Logger . mouseHelpers . error ( " CGWarpMouseCursorPosition failed with error \( result. logString, privacy: . public) " )
5171 }
5272 }
5373
@@ -58,7 +78,7 @@ enum MouseHelpers {
5878 static func associateMouseAndCursor( _ connected: Bool ) {
5979 let result = CGAssociateMouseAndMouseCursorPosition ( connected ? 1 : 0 )
6080 if result != . success {
61- Logger . default . error ( " CGAssociateMouseAndMouseCursorPosition failed with error \( result. logString, privacy: . public) " )
81+ Logger . mouseHelpers . error ( " CGAssociateMouseAndMouseCursorPosition failed with error \( result. logString, privacy: . public) " )
6282 }
6383 }
6484
@@ -72,7 +92,7 @@ enum MouseHelpers {
7292 if let button {
7393 return CGEventSource . buttonState ( stateID, button: button)
7494 }
75- for n : UInt32 in 0 ... 31 {
95+ for n : UInt32 in 0 ... 31 {
7696 guard
7797 let button = CGMouseButton ( rawValue: n) ,
7898 CGEventSource . buttonState ( stateID, button: button)
0 commit comments