aerospace fork
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120import AppKitimport Common
@MainActorprivate var moveWithMouseTask: Task<(), any Error>? = nil
func movedObs(_: AXObserver, ax: AXUIElement, notif: CFString, _: UnsafeMutableRawPointer?) { let windowId = ax.containingWindowId() let notif = notif as String Task.startUnstructured { @MainActor in guard let token: RunSessionGuard = .isServerEnabled else { return } guard let windowId, let window = Window.get(byId: windowId), try await isManipulatedWithMouse(window) else { scheduleCancellableCompleteRefreshSession(.ax(notif)) return } moveWithMouseTask?.cancel() moveWithMouseTask = Task.startUnstructured { try checkCancellation() try await runLightSession(.ax(notif), token) { try await moveWithMouse(window) } } }}
@MainActorprivate func moveWithMouse(_ window: Window) async throws { // todo cover with tests resetClosedWindowsCache() switch window.windowParentCases { case .floatingWindowsContainer: try await moveFloatingWindow(window) case .macosFullscreenWindowsContainer, .macosMinimizedWindowsContainer, .macosPopupWindowsContainer, .macosHiddenAppsWindowsContainer: return // Unconventional windows can't be moved with mouse case .tilingContainer: moveTilingWindow(window) case .unbound: return }}
@MainActorprivate func moveFloatingWindow(_ window: Window) async throws { guard let targetWorkspace = try await window.getCenter(.cancellable)?.monitorApproximation.activeWorkspace else { return } guard let parent = window.parent else { return } if targetWorkspace != parent { window.bindAsFloatingWindow(to: targetWorkspace) }}
@MainActorprivate func moveTilingWindow(_ window: Window) { currentlyManipulatedWithMouseWindowId = window.windowId window.lastAppliedLayoutPhysicalRect = nil let mouseLocation = mouseLocation let targetWorkspace = mouseLocation.monitorApproximation.activeWorkspace let swapTarget = mouseLocation .findWindowRecursively(in: targetWorkspace.rootTilingContainer, virtual: false, fullscreenCoversAll: false)? .takeIf { $0 != window } if targetWorkspace != window.nodeWorkspace { // Move window to a different monitor let index: Int = if let swapTarget, let parent = swapTarget.parent as? TilingContainer, let targetRect = swapTarget.lastAppliedLayoutPhysicalRect { mouseLocation.getProjection(parent.orientation) >= targetRect.center.getProjection(parent.orientation) ? swapTarget.ownIndex.orDie() + 1 : swapTarget.ownIndex.orDie() } else { 0 } window.bind( to: swapTarget?.parent ?? targetWorkspace.rootTilingContainer, adaptiveWeight: WEIGHT_AUTO, index: index, ) } else if let swapTarget { swapWindows(mruDominant: window, swapTarget) }}
@MainActorfunc swapWindows(mruDominant window1: Window, _ window2: Window) { if window1 == window2 { return }
let binding2 = window2.unbindFromParent() let binding1 = window1.unbindFromParent()
window2.bind(to: binding1.parent, adaptiveWeight: binding1.adaptiveWeight, index: binding1.index) window1.bind(to: binding2.parent, adaptiveWeight: binding2.adaptiveWeight, index: binding2.index)}
extension CGPoint { @MainActor func findWindowRecursively( in tree: TilingContainer, virtual: Bool, fullscreenCoversAll: Bool, ) -> Window? { if fullscreenCoversAll { if let window = tree.mostRecentWindowRecursive, window.isFullscreen { return window } } return _findWindowRecursively(in: tree, virtual: virtual) }
@MainActor private func _findWindowRecursively(in tree: TilingContainer, virtual: Bool) -> Window? { let point = self let target: TreeNode? = switch tree.layout { case .tiles, .masterStack: tree.children.first(where: { (virtual ? $0.lastAppliedLayoutVirtualRect : $0.lastAppliedLayoutPhysicalRect)?.contains(point) == true }) case .accordion: tree.mostRecentChild } guard let target else { return nil } return switch target.tilingTreeNodeCasesOrDie() { case .window(let window): window case .tilingContainer(let container): _findWindowRecursively(in: container, virtual: virtual) } }}