Skip to content

Commit 5a66805

Browse files
committed
fix: implement proper cursor count tracking to prevent cursor staying hidden
- Add cursorHideCount tracking to prevent race conditions in Thaw Bar interactions - Replace direct CG calls with count-managed hide/show operations - Add proper categorized logging for mouse helper operations - Prevents cursor staying hidden for users experiencing concurrent operations Signed-off-by: Toni Förster <toni.foerster@icloud.com>
1 parent 3efd6ed commit 5a66805

1 file changed

Lines changed: 29 additions & 9 deletions

File tree

Thaw/Utilities/MouseHelpers.swift

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,18 @@
66
import CoreGraphics
77
import 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.
1019
enum 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

Comments
 (0)