Skip to content

Commit

Permalink
refactor: update SystemWindowRelativeFocus for state tracking
Browse files Browse the repository at this point in the history
Refactor SystemWindowRelativeFocus to a final class to handle state
tracking for consumed windows and previous direction. Add new 
instance variables and methods to reset state and insert consumed 
windows. Update usages of SystemWindowRelativeFocus' methods to 
use instance methods instead of static methods.

Add consumed windows tracking to ensure windows are not reused.
Update SystemCommandRunner to initialize and use the new 
SystemWindowRelativeFocus instance.
  • Loading branch information
zenangst committed Jun 12, 2024
1 parent 6a3eb94 commit 514dba1
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 13 deletions.
29 changes: 25 additions & 4 deletions App/Sources/Core/Runners/System/SystemWindowRelativeFocus.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,26 @@ import AXEssibility
import Foundation
import Windows

enum SystemWindowRelativeFocus {
final class SystemWindowRelativeFocus {
enum Direction {
case up, down, left, right
}

static func run(_ direction: Direction, snapshot: UserSpace.Snapshot) throws {
var consumedWindows = Set<WindowModel>()
var previousDirection: Direction?

init() {}

func reset() {
consumedWindows.removeAll()
}

func run(_ direction: Direction, snapshot: UserSpace.Snapshot) throws {
if direction != previousDirection {
previousDirection = direction
consumedWindows.removeAll()
}

var windows = indexWindowsInStage(getWindows())
let frontMostApplication = snapshot.frontMostApplication
let frontMostAppElement = AppAccessibilityElement(frontMostApplication.ref.processIdentifier)
Expand All @@ -25,6 +39,7 @@ enum SystemWindowRelativeFocus {

if window.id == focusedWindow.id {
activeWindow = window
consumedWindows.insert(window)
windows.remove(at: offset)
break
}
Expand All @@ -35,6 +50,8 @@ enum SystemWindowRelativeFocus {
windows.removeFirst()
}

windows.removeAll(where: { consumedWindows.contains($0) })

guard let activeWindow = activeWindow else { return }

var matchedWindow: WindowModel?
Expand All @@ -51,6 +68,8 @@ enum SystemWindowRelativeFocus {

guard let matchedWindow else { return }

consumedWindows.insert(matchedWindow)

let processIdentifier = pid_t(matchedWindow.ownerPid.rawValue)
guard let runningApplication = NSRunningApplication(processIdentifier: processIdentifier) else { return }
let appElement = AppAccessibilityElement(processIdentifier)
Expand All @@ -64,13 +83,15 @@ enum SystemWindowRelativeFocus {
match?.performAction(.raise)
}

private static func getWindows() -> [WindowModel] {
// MARK: Private methods

private func getWindows() -> [WindowModel] {
let options: CGWindowListOption = [.optionOnScreenOnly, .excludeDesktopElements]
let windowModels: [WindowModel] = ((try? WindowsInfo.getWindows(options)) ?? [])
return windowModels
}

private static func indexWindowsInStage(_ models: [WindowModel]) -> [WindowModel] {
private func indexWindowsInStage(_ models: [WindowModel]) -> [WindowModel] {
let excluded = ["WindowManager", "Window Server"]
let minimumSize = CGSize(width: 150, height: 150)
let windows: [WindowModel] = models
Expand Down
22 changes: 13 additions & 9 deletions App/Sources/Core/Runners/SystemCommandRunner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import Windows
final class SystemCommandRunner: @unchecked Sendable {
var machPort: MachPortEventController?

private let applicationStore: ApplicationStore
private let applicationActivityMonitor: ApplicationActivityMonitor<UserSpace.Application>
private let applicationStore: ApplicationStore
private let relativeFocus: SystemWindowRelativeFocus
private let workspace: WorkspaceProviding

private var flagsChangedSubscription: AnyCancellable?
Expand All @@ -31,10 +32,13 @@ final class SystemCommandRunner: @unchecked Sendable {
.compactMap { $0 }
.sink { [weak self] flags in
guard let self else { return }
WindowStore.shared.state.interactive = flags != CGEventFlags.maskNonCoalesced
if WindowStore.shared.state.interactive == false {
self.frontMostIndex = 0
self.visibleMostIndex = 0
Task { @MainActor in
WindowStore.shared.state.interactive = flags != CGEventFlags.maskNonCoalesced
if WindowStore.shared.state.interactive == false {
self.frontMostIndex = 0
self.visibleMostIndex = 0
self.relativeFocus.reset()
}
}
}
}
Expand Down Expand Up @@ -71,13 +75,13 @@ final class SystemCommandRunner: @unchecked Sendable {
case .missionControl:
Dock.run(.missionControl)
case .moveFocusToNextWindowUpwards:
try SystemWindowRelativeFocus.run(.up, snapshot: snapshot)
try relativeFocus.run(.up, snapshot: snapshot)
case .moveFocusToNextWindowDownwards:
try SystemWindowRelativeFocus.run(.down, snapshot: snapshot)
try relativeFocus.run(.down, snapshot: snapshot)
case .moveFocusToNextWindowOnLeft:
try SystemWindowRelativeFocus.run(.left, snapshot: snapshot)
try relativeFocus.run(.left, snapshot: snapshot)
case .moveFocusToNextWindowOnRight:
try SystemWindowRelativeFocus.run(.right, snapshot: snapshot)
try relativeFocus.run(.right, snapshot: snapshot)
}
}
}
Expand Down

0 comments on commit 514dba1

Please sign in to comment.