diff --git a/.github/workflows/dev-build.yml b/.github/workflows/dev-build.yml index 2ea8944d..82b2fd9f 100644 --- a/.github/workflows/dev-build.yml +++ b/.github/workflows/dev-build.yml @@ -88,6 +88,9 @@ jobs: -destination 'generic/platform=macOS' \ -archivePath dist/Loop.xcarchive \ -allowProvisioningUpdates \ + -skipMacroValidation \ + -skipPackagePluginValidation \ + -showBuildTimingSummary \ | xcbeautify - name: 🥡 Export Loop.app diff --git a/Loop/Core/WindowDragManager.swift b/Loop/Core/WindowDragManager.swift index b8332471..b43a72a2 100644 --- a/Loop/Core/WindowDragManager.swift +++ b/Loop/Core/WindowDragManager.swift @@ -20,6 +20,8 @@ final class WindowDragManager { private var draggingWindow: Window? private var initialWindowFrame: CGRect? private var direction: WindowDirection = .noAction + // Avoid repeated window resolution attempts during a non-window drag (e.g. in games). + private var didFailToResolveDraggedWindow: Bool = false private let previewController = PreviewController() @@ -33,6 +35,13 @@ final class WindowDragManager { NSEvent.mouseLocation.flipY(screen: NSScreen.screens[0]) } + // Avoid running global drag logic unless a feature actually depends on it. + private var shouldMonitorDragActions: Bool { + Defaults[.windowSnapping] || + Defaults[.restoreWindowFrameOnDrag] || + !Defaults[.stashManagerStashedWindows].isEmpty + } + @MainActor func addObservers() { accessibilityCheckerTask = Task(priority: .background) { [weak self] in @@ -64,9 +73,6 @@ final class WindowDragManager { leftMouseDraggedMonitor.start() leftMouseUpMonitor.start() - leftMouseDraggedMonitor.start() - leftMouseUpMonitor.start() - self.leftMouseDraggedMonitor = leftMouseDraggedMonitor self.leftMouseUpMonitor = leftMouseUpMonitor } @@ -80,6 +86,10 @@ final class WindowDragManager { } private func leftMouseDragged(event _: CGEvent) { + guard shouldMonitorDragActions else { + return + } + Task { @MainActor in guard let initialMousePosition else { initialMousePosition = currentMousePosition @@ -95,7 +105,7 @@ final class WindowDragManager { } // Process window (only ONCE during a window drag) - if draggingWindow == nil { + if draggingWindow == nil, !didFailToResolveDraggedWindow { setCurrentDraggingWindow() } @@ -135,11 +145,10 @@ final class WindowDragManager { } } - self.previewController.close() - self.draggingWindow = nil - previewController.close() draggingWindow = nil + + resetDragState() } } @@ -158,16 +167,28 @@ final class WindowDragManager { let draggingWindow = try? WindowUtility.windowAtPosition(currentMousePosition), !draggingWindow.isAppExcluded else { + didFailToResolveDraggedWindow = true return } self.draggingWindow = draggingWindow initialWindowFrame = draggingWindow.frame + didFailToResolveDraggedWindow = false Log.info("Determined window being dragged: \(draggingWindow.description)", category: .windowDragManager) } } + private func resetDragState() { + initialMousePosition = nil + didPassDragDistanceThreshold = false + didFailToResolveDraggedWindow = false + initialWindowFrame = nil + direction = .noAction + determineDraggedWindowTask?.cancel() + determineDraggedWindowTask = nil + } + private func hasWindowMoved(_ windowFrame: CGRect, _ initialFrame: CGRect) -> Bool { !initialFrame.topLeftPoint.approximatelyEqual(to: windowFrame.topLeftPoint) && !initialFrame.topRightPoint.approximatelyEqual(to: windowFrame.topRightPoint) &&