Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/dev-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ jobs:
-destination 'generic/platform=macOS' \
-archivePath dist/Loop.xcarchive \
-allowProvisioningUpdates \
-skipMacroValidation \
-skipPackagePluginValidation \
-showBuildTimingSummary \
| xcbeautify

- name: 🥡 Export Loop.app
Expand Down
35 changes: 28 additions & 7 deletions Loop/Core/WindowDragManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -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
Expand Down Expand Up @@ -64,9 +73,6 @@ final class WindowDragManager {
leftMouseDraggedMonitor.start()
leftMouseUpMonitor.start()

leftMouseDraggedMonitor.start()
leftMouseUpMonitor.start()

self.leftMouseDraggedMonitor = leftMouseDraggedMonitor
self.leftMouseUpMonitor = leftMouseUpMonitor
}
Expand All @@ -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
Expand All @@ -95,7 +105,7 @@ final class WindowDragManager {
}

// Process window (only ONCE during a window drag)
if draggingWindow == nil {
if draggingWindow == nil, !didFailToResolveDraggedWindow {
setCurrentDraggingWindow()
}

Expand Down Expand Up @@ -135,11 +145,10 @@ final class WindowDragManager {
}
}

self.previewController.close()
self.draggingWindow = nil

previewController.close()
draggingWindow = nil

resetDragState()
}
}

Expand All @@ -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) &&
Expand Down