Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
jordanbaird committed Jan 7, 2025
1 parent d567f1e commit 7d31eb6
Show file tree
Hide file tree
Showing 14 changed files with 44 additions and 61 deletions.
18 changes: 9 additions & 9 deletions Ice/Events/EventManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ extension EventManager {

// Get the window that the user has clicked into.
guard
let mouseLocation = MouseCursor.location(in: .coreGraphics),
let mouseLocation = MouseCursor.locationCoreGraphics,
let windowUnderMouse = WindowInfo.getOnScreenWindows(excludeDesktopWindows: false)
.filter({ $0.layer < CGWindowLevelForKey(.cursorWindow) })
.first(where: { $0.frame.contains(mouseLocation) && $0.title?.isEmpty == false }),
Expand Down Expand Up @@ -257,7 +257,7 @@ extension EventManager {
guard
let appState,
isMouseInsideEmptyMenuBarSpace,
let mouseLocation = MouseCursor.location(in: .appKit)
let mouseLocation = MouseCursor.locationAppKit
else {
return
}
Expand Down Expand Up @@ -453,12 +453,12 @@ extension EventManager {
}
if appState.menuBarManager.isMenuBarHiddenBySystem || appState.isActiveSpaceFullscreen {
if
let mouseLocation = MouseCursor.location(in: .coreGraphics),
let mouseLocation = MouseCursor.locationCoreGraphics,
let menuBarWindow = WindowInfo.getMenuBarWindow(for: screen.displayID)
{
return menuBarWindow.frame.contains(mouseLocation)
}
} else if let mouseLocation = MouseCursor.location(in: .appKit) {
} else if let mouseLocation = MouseCursor.locationAppKit {
return mouseLocation.y > screen.visibleFrame.maxY && mouseLocation.y <= screen.frame.maxY
}
return false
Expand All @@ -468,7 +468,7 @@ extension EventManager {
/// the bounds of the current application menu.
var isMouseInsideApplicationMenu: Bool {
guard
let mouseLocation = MouseCursor.location(in: .coreGraphics),
let mouseLocation = MouseCursor.locationCoreGraphics,
let screen = bestScreen,
let appState,
var applicationMenuFrame = appState.menuBarManager.getApplicationMenuFrame(for: screen.displayID)
Expand All @@ -485,7 +485,7 @@ extension EventManager {
var isMouseInsideMenuBarItem: Bool {
guard
let screen = bestScreen,
let mouseLocation = MouseCursor.location(in: .coreGraphics)
let mouseLocation = MouseCursor.locationCoreGraphics
else {
return false
}
Expand All @@ -501,7 +501,7 @@ extension EventManager {
var isMouseInsideNotch: Bool {
guard
let screen = bestScreen,
let mouseLocation = MouseCursor.location(in: .appKit),
let mouseLocation = MouseCursor.locationAppKit,
let frameOfNotch = screen.frameOfNotch
else {
return false
Expand All @@ -523,7 +523,7 @@ extension EventManager {
var isMouseInsideIceBar: Bool {
guard
let appState,
let mouseLocation = MouseCursor.location(in: .appKit)
let mouseLocation = MouseCursor.locationAppKit
else {
return false
}
Expand All @@ -541,7 +541,7 @@ extension EventManager {
let appState,
let visibleSection = appState.menuBarManager.section(withName: .visible),
let iceIconFrame = visibleSection.controlItem.windowFrame,
let mouseLocation = MouseCursor.location(in: .appKit)
let mouseLocation = MouseCursor.locationAppKit
else {
return false
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -1057,7 +1057,7 @@ extension MenuBarItemManager {
guard let appState else {
throw EventError(code: .invalidAppState, item: item)
}
guard let cursorLocation = MouseCursor.location(in: .coreGraphics) else {
guard let cursorLocation = MouseCursor.locationCoreGraphics else {
throw EventError(code: .invalidCursorLocation, item: item)
}
guard let initialFrame = getCurrentFrame(for: item) else {
Expand Down Expand Up @@ -1140,7 +1140,7 @@ extension MenuBarItemManager {
guard let source = CGEventSource(stateID: .hidSystemState) else {
throw EventError(code: .invalidEventSource, item: item)
}
guard let cursorLocation = MouseCursor.location(in: .coreGraphics) else {
guard let cursorLocation = MouseCursor.locationCoreGraphics else {
throw EventError(code: .invalidCursorLocation, item: item)
}
guard let currentFrame = getCurrentFrame(for: item) else {
Expand Down
2 changes: 1 addition & 1 deletion Ice/UI/IceBar/IceBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ final class IceBarPanel: NSPanel {
}
return getOrigin(for: .iceIcon)
case .mousePointer:
guard let location = MouseCursor.location(in: .appKit) else {
guard let location = MouseCursor.locationAppKit else {
return getOrigin(for: .iceIcon)
}

Expand Down
47 changes: 23 additions & 24 deletions Ice/Utilities/BindingExposable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,9 @@

import SwiftUI

/// A type that acts as a lens that exposes bindings to the writable properties
/// of a base object.
@dynamicMemberLookup
struct ExposedBindings<Base: BindingExposable> {
/// The base object whose bindings are exposed.
fileprivate let base: Base

/// Returns a binding to the property at the given key path.
subscript<Value>(dynamicMember keyPath: ReferenceWritableKeyPath<Base, Value>) -> Binding<Value> {
Binding(
get: { base[keyPath: keyPath] },
set: { base[keyPath: keyPath] = $0 }
)
}

/// Returns a lens that exposes the bindings of the object
/// at the given key path.
subscript<T: BindingExposable>(dynamicMember keyPath: KeyPath<Base, T>) -> ExposedBindings<T> {
ExposedBindings<T>(base: base[keyPath: keyPath])
}
}

/// A type that exposes its writable properties as bindings.
protocol BindingExposable {
/// A type that acts as a lens that exposes bindings to the writable properties
/// of this type.
/// A lens that exposes bindings to the writable properties of this type.
typealias Bindings = ExposedBindings<Self>

/// A lens that exposes bindings to the writable properties of this instance.
Expand All @@ -42,3 +19,25 @@ extension BindingExposable {
Bindings(base: self)
}
}

/// A lens that exposes bindings to the writable properties of a base object.
@dynamicMemberLookup
struct ExposedBindings<Base: BindingExposable> {
/// The object whose bindings are exposed.
private let base: Base

/// Creates a lens that exposes the bindings of the given object.
init(base: Base) {
self.base = base
}

/// Returns a binding to the property at the given key path.
subscript<Value>(dynamicMember keyPath: ReferenceWritableKeyPath<Base, Value>) -> Binding<Value> {
Binding(get: { base[keyPath: keyPath] }, set: { base[keyPath: keyPath] = $0 })
}

/// Returns a lens that exposes the bindings of the object at the given key path.
subscript<T: BindingExposable>(dynamicMember keyPath: KeyPath<Base, T>) -> ExposedBindings<T> {
ExposedBindings<T>(base: base[keyPath: keyPath])
}
}
34 changes: 9 additions & 25 deletions Ice/Utilities/MouseCursor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@ import CoreGraphics

/// A namespace for mouse cursor operations.
enum MouseCursor {
/// A coordinate space for mouse cursor operations.
enum CoordinateSpace {
/// The coordinate space used by the `AppKit` framework.
///
/// The origin of this coordinate space is at the bottom left corner of the screen.
case appKit
/// Returns the location of the mouse cursor in the coordinate space used by
/// the `AppKit` framework, with the origin at the bottom left of the screen.
static var locationAppKit: CGPoint? {
CGEvent(source: nil)?.unflippedLocation
}

/// The coordinate space used by the `CoreGraphics` framework.
///
/// The origin of this coordinate space is at the top left corner of the screen.
case coreGraphics
/// Returns the location of the mouse cursor in the coordinate space used by
/// the `CoreGraphics` framework, with the origin at the top left of the screen.
static var locationCoreGraphics: CGPoint? {
CGEvent(source: nil)?.location
}

/// Hides the mouse cursor and increments the hide cursor count.
Expand Down Expand Up @@ -45,21 +44,6 @@ enum MouseCursor {
Logger.mouseCursor.error("CGWarpMouseCursorPosition failed with error \(result.logString)")
}
}

/// Returns the location of the mouse pointer.
///
/// - Parameter coordinateSpace: The coordinate space of the returned location. See
/// the constants defined in ``MouseCursor/CoordinateSpace`` for more information.
static func location(in coordinateSpace: CoordinateSpace) -> CGPoint? {
CGEvent(source: nil).map { event in
switch coordinateSpace {
case .appKit:
event.unflippedLocation
case .coreGraphics:
event.location
}
}
}
}

// MARK: - Logger
Expand Down

0 comments on commit 7d31eb6

Please sign in to comment.