Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
jordanbaird committed Oct 5, 2024
1 parent 30827bc commit 668798b
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 66 deletions.
134 changes: 68 additions & 66 deletions Ice/Events/EventManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ import Combine
/// Manager for the various event monitors maintained by the app.
@MainActor
final class EventManager {
/// The shared app state.
private weak var appState: AppState?

/// Storage for internal observers.
private var cancellables = Set<AnyCancellable>()

// MARK: Monitors

/// Monitor for mouse down events.
private(set) lazy var mouseDownMonitor = UniversalEventMonitor(
mask: [.leftMouseDown, .rightMouseDown]
) { [weak self] event in
Expand All @@ -34,27 +37,31 @@ final class EventManager {
return event
}

/// Monitor for mouse up events.
private(set) lazy var mouseUpMonitor = UniversalEventMonitor(
mask: .leftMouseUp
) { [weak self] event in
self?.handleLeftMouseUp()
return event
}

/// Monitor for mouse dragged events.
private(set) lazy var mouseDraggedMonitor = UniversalEventMonitor(
mask: .leftMouseDragged
) { [weak self] event in
self?.handleLeftMouseDragged(with: event)
return event
}

/// Monitor for mouse moved events.
private(set) lazy var mouseMovedMonitor = UniversalEventMonitor(
mask: .mouseMoved
) { [weak self] event in
self?.handleShowOnHover()
return event
}

/// Monitor for scroll wheel events.
private(set) lazy var scrollWheelMonitor = UniversalEventMonitor(
mask: .scrollWheel
) { [weak self] event in
Expand All @@ -64,6 +71,7 @@ final class EventManager {

// MARK: All Monitors

/// All monitors maintained by the app.
private lazy var allMonitors = [
mouseDownMonitor,
mouseUpMonitor,
Expand All @@ -74,24 +82,26 @@ final class EventManager {

// MARK: Initializers

/// Creates an event manager with the given app state.
init(appState: AppState) {
self.appState = appState
}

/// Sets up the manager.
func performSetup() {
startAll()
configureCancellables()
}

/// Configures the internal observers for the manager.
private func configureCancellables() {
var c = Set<AnyCancellable>()

if let appState {
if let hiddenSection = appState.menuBarManager.section(withName: .hidden) {
// In fullscreen mode, the menu bar slides down from the top on hover.
// Observe the frame of the hidden section's control item, which we know
// will always be in the menu bar, and run the show-on-hover check when
// it changes.
// In fullscreen mode, the menu bar slides down from the top on hover. Observe
// the frame of the hidden section's control item, which we know will always be
// in the menu bar, and run the show-on-hover check when it changes.
Publishers.CombineLatest(
hiddenSection.controlItem.$windowFrame,
appState.$isActiveSpaceFullscreen
Expand Down Expand Up @@ -146,7 +156,7 @@ extension EventManager {

Task {
// Short delay helps the toggle action feel more natural.
try await Task.sleep(for: .milliseconds(50))
try? await Task.sleep(for: .milliseconds(50))

if NSEvent.modifierFlags == .control {
handleShowRightClickMenu()
Expand Down Expand Up @@ -198,46 +208,42 @@ extension EventManager {
}

Task {
do {
let initialSpaceID = Bridging.activeSpaceID
let initialSpaceID = Bridging.activeSpaceID

// Sleep for a bit to give the window under the mouse a chance to focus.
try await Task.sleep(for: .seconds(0.25))
// Sleep for a bit to give the window under the mouse a chance to focus.
try? await Task.sleep(for: .seconds(0.25))

// If clicking caused a space change, don't bother with the window check.
if Bridging.activeSpaceID != initialSpaceID {
shownSection.hide()
return
}
// If clicking caused a space change, don't bother with the window check.
if Bridging.activeSpaceID != initialSpaceID {
shownSection.hide()
return
}

// Get the window that the user has clicked into.
guard
let mouseLocation = MouseCursor.coreGraphicsLocation,
let windowUnderMouse = WindowInfo.getOnScreenWindows(excludeDesktopWindows: false)
.filter({ $0.layer < CGWindowLevelForKey(.cursorWindow) })
.first(where: { $0.frame.contains(mouseLocation) && $0.title?.isEmpty == false }),
let owningApplication = windowUnderMouse.owningApplication
else {
return
}

// Get the window that the user has clicked into.
// The dock is an exception to the following check.
if owningApplication.bundleIdentifier != "com.apple.dock" {
// Only continue if the user has clicked into an active window with
// a regular activation policy.
guard
let mouseLocation = MouseCursor.coreGraphicsLocation,
let windowUnderMouse = WindowInfo.getOnScreenWindows(excludeDesktopWindows: false)
.filter({ $0.layer < CGWindowLevelForKey(.cursorWindow) })
.first(where: { $0.frame.contains(mouseLocation) && $0.title?.isEmpty == false }),
let owningApplication = windowUnderMouse.owningApplication
owningApplication.isActive,
owningApplication.activationPolicy == .regular
else {
return
}

// The dock is an exception to the following check.
if owningApplication.bundleIdentifier != "com.apple.dock" {
// Only continue if the user has clicked into an active window with
// a regular activation policy.
guard
owningApplication.isActive,
owningApplication.activationPolicy == .regular
else {
return
}
}

// If all the above checks have passed, hide.
shownSection.hide()
} catch {
Logger.eventManager.error("ERROR: \(error)")
}

// If all the above checks have passed, hide.
shownSection.hide()
}
}

Expand Down Expand Up @@ -355,36 +361,32 @@ extension EventManager {
let delay = appState.settingsManager.advancedSettingsManager.showOnHoverDelay

Task {
do {
if hiddenSection.isHidden {
guard self.isMouseInsideEmptyMenuBarSpace else {
return
}
try await Task.sleep(for: .seconds(delay))
// Make sure the mouse is still inside.
guard self.isMouseInsideEmptyMenuBarSpace else {
return
}
hiddenSection.show()
} else {
guard
!self.isMouseInsideMenuBar,
!self.isMouseInsideIceBar
else {
return
}
try await Task.sleep(for: .seconds(delay))
// Make sure the mouse is still outside.
guard
!self.isMouseInsideMenuBar,
!self.isMouseInsideIceBar
else {
return
}
hiddenSection.hide()
if hiddenSection.isHidden {
guard self.isMouseInsideEmptyMenuBarSpace else {
return
}
try? await Task.sleep(for: .seconds(delay))
// Make sure the mouse is still inside.
guard self.isMouseInsideEmptyMenuBarSpace else {
return
}
hiddenSection.show()
} else {
guard
!self.isMouseInsideMenuBar,
!self.isMouseInsideIceBar
else {
return
}
try? await Task.sleep(for: .seconds(delay))
// Make sure the mouse is still outside.
guard
!self.isMouseInsideMenuBar,
!self.isMouseInsideIceBar
else {
return
}
} catch {
Logger.eventManager.error("ERROR: \(error)")
hiddenSection.hide()
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions Ice/Main/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ final class AppState: ObservableObject {
set { Bridging.setConnectionProperty(newValue, forKey: "SetsCursorInBackground") }
}

/// Configures the internal observers for the app state.
private func configureCancellables() {
var c = Set<AnyCancellable>()

Expand Down Expand Up @@ -171,6 +172,7 @@ final class AppState: ObservableObject {
cancellables = c
}

/// Sets up the app state.
func performSetup() {
configureCancellables()
permissionsManager.stopAllChecks()
Expand Down Expand Up @@ -296,5 +298,6 @@ extension AppState: BindingExposable { }

// MARK: - Logger
private extension Logger {
/// The logger to use for the app state.
static let appState = Logger(category: "AppState")
}

0 comments on commit 668798b

Please sign in to comment.