diff --git a/Ice/Events/EventManager.swift b/Ice/Events/EventManager.swift index af632329..efa167e4 100644 --- a/Ice/Events/EventManager.swift +++ b/Ice/Events/EventManager.swift @@ -212,7 +212,7 @@ extension EventManager { // Get the window that the user has clicked into. guard - let mouseLocation = MouseCursor.location(flipped: true), + let mouseLocation = MouseCursor.coreGraphicsLocation, let windowUnderMouse = WindowInfo.getOnScreenWindows(excludeDesktopWindows: false) .filter({ $0.layer < CGWindowLevelForKey(.cursorWindow) }) .first(where: { $0.frame.contains(mouseLocation) }), @@ -247,7 +247,7 @@ extension EventManager { guard let appState, isMouseInsideEmptyMenuBarSpace, - let mouseLocation = MouseCursor.location(flipped: false) + let mouseLocation = MouseCursor.appKitLocation else { return } @@ -447,12 +447,12 @@ extension EventManager { } if appState.menuBarManager.isMenuBarHiddenBySystem || appState.isActiveSpaceFullscreen { if - let mouseLocation = MouseCursor.location(flipped: true), + let mouseLocation = MouseCursor.coreGraphicsLocation, let menuBarWindow = WindowInfo.getMenuBarWindow(for: screen.displayID) { return menuBarWindow.frame.contains(mouseLocation) } - } else if let mouseLocation = MouseCursor.location(flipped: false) { + } else if let mouseLocation = MouseCursor.appKitLocation { return mouseLocation.y > screen.visibleFrame.maxY && mouseLocation.y <= screen.frame.maxY } return false @@ -462,7 +462,7 @@ extension EventManager { /// the bounds of the current application menu. var isMouseInsideApplicationMenu: Bool { guard - let mouseLocation = MouseCursor.location(flipped: true), + let mouseLocation = MouseCursor.coreGraphicsLocation, let screen = bestScreen, let appState, var applicationMenuFrame = appState.menuBarManager.getApplicationMenuFrame(for: screen.displayID) @@ -479,7 +479,7 @@ extension EventManager { var isMouseInsideMenuBarItem: Bool { guard let screen = bestScreen, - let mouseLocation = MouseCursor.location(flipped: true) + let mouseLocation = MouseCursor.coreGraphicsLocation else { return false } @@ -495,7 +495,7 @@ extension EventManager { var isMouseInsideNotch: Bool { guard let screen = bestScreen, - let mouseLocation = MouseCursor.location(flipped: false), + let mouseLocation = MouseCursor.appKitLocation, let frameOfNotch = screen.frameOfNotch else { return false @@ -517,7 +517,7 @@ extension EventManager { var isMouseInsideIceBar: Bool { guard let appState, - let mouseLocation = MouseCursor.location(flipped: false) + let mouseLocation = MouseCursor.appKitLocation else { return false } @@ -535,7 +535,7 @@ extension EventManager { let appState, let visibleSection = appState.menuBarManager.section(withName: .visible), let iceIconFrame = visibleSection.controlItem.windowFrame, - let mouseLocation = MouseCursor.location(flipped: false) + let mouseLocation = MouseCursor.appKitLocation else { return false } diff --git a/Ice/MenuBar/MenuBarItemManager.swift b/Ice/MenuBar/MenuBarItemManager.swift index b5f77d63..9684bd80 100644 --- a/Ice/MenuBar/MenuBarItemManager.swift +++ b/Ice/MenuBar/MenuBarItemManager.swift @@ -922,7 +922,7 @@ extension MenuBarItemManager { guard let appState else { throw EventError(code: .invalidAppState, item: item) } - guard let cursorLocation = MouseCursor.location(flipped: true) else { + guard let cursorLocation = MouseCursor.coreGraphicsLocation else { throw EventError(code: .invalidCursorLocation, item: item) } guard let initialFrame = getCurrentFrame(for: item) else { @@ -1001,7 +1001,7 @@ extension MenuBarItemManager { guard let source = CGEventSource(stateID: .hidSystemState) else { throw EventError(code: .invalidEventSource, item: item) } - guard let cursorLocation = MouseCursor.location(flipped: true) else { + guard let cursorLocation = MouseCursor.coreGraphicsLocation else { throw EventError(code: .invalidCursorLocation, item: item) } guard let currentFrame = getCurrentFrame(for: item) else { diff --git a/Ice/UI/IceBar/IceBar.swift b/Ice/UI/IceBar/IceBar.swift index 002f6e5c..5677d04f 100644 --- a/Ice/UI/IceBar/IceBar.swift +++ b/Ice/UI/IceBar/IceBar.swift @@ -117,7 +117,7 @@ final class IceBarPanel: NSPanel { } return getOrigin(for: .iceIcon) case .mousePointer: - guard let location = MouseCursor.location(flipped: false) else { + guard let location = MouseCursor.appKitLocation else { return getOrigin(for: .iceIcon) } diff --git a/Ice/Utilities/MouseCursor.swift b/Ice/Utilities/MouseCursor.swift index 2791ed7b..8dfa0cd6 100644 --- a/Ice/Utilities/MouseCursor.swift +++ b/Ice/Utilities/MouseCursor.swift @@ -7,6 +7,24 @@ import CoreGraphics /// A namespace for mouse cursor operations. enum MouseCursor { + /// The location of the mouse pointer in the coordinate system used by the + /// `CoreGraphics` framework. + /// + /// The coordinate system of the returned location is relative to the top + /// left corner of the screen. + static var coreGraphicsLocation: CGPoint? { + CGEvent(source: nil)?.location + } + + /// The location of the mouse pointer in the coordinate system used by the + /// `AppKit` framework. + /// + /// The coordinate system of the returned location is relative to the bottom + /// left corner of the screen. + static var appKitLocation: CGPoint? { + CGEvent(source: nil)?.unflippedLocation + } + /// Hides the mouse cursor and increments the hide cursor count. static func hide() { let result = CGDisplayHideCursor(CGMainDisplayID()) @@ -32,24 +50,6 @@ enum MouseCursor { Logger.mouseCursor.error("CGWarpMouseCursorPosition failed with error \(result.logString)") } } - - /// Returns the location of the mouse pointer. - /// - /// If `flipped` is `true`, the coordinate system of the returned location - /// is relative to the top left corner of the screen, and is compatible with - /// the coordinate system used by the `CoreGraphics` framework. Otherwise, - /// the coordinate system of the returned location is relative to the bottom - /// left corner of the screen, and is compatible with coordinate system used - /// by the `AppKit` framework. - static func location(flipped: Bool) -> CGPoint? { - CGEvent(source: nil).map { event in - if flipped { - event.location - } else { - event.unflippedLocation - } - } - } } // MARK: - Logger