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
2 changes: 1 addition & 1 deletion .github/workflows/dev-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: 🧪 Set Version and Build number
run: |
# CHANGE EVERY RELEASE:
APP_VERSION="🧪 1.4.1"
APP_VERSION="🧪 1.4.3"
APP_BUILD=$(git rev-list --count HEAD)
FROM_TAG=$(git describe --tags --abbrev=0 --exclude='prerelease')

Expand Down
13 changes: 10 additions & 3 deletions Loop/Core/Observers/KeybindTrigger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,10 @@ final class KeybindTrigger {
private func performKeybind(keyCode: CGKeyCode, type: CGEventType, isARepeat: Bool, flags: CGEventFlags, isLoopOpen: Bool) -> PerformKeybindResult {
let flagKeys = sideDependentTriggerKey ? flags.keyCodes : flags.keyCodes.baseModifiers
let allPressedKeys: Set<CGKeyCode> = pressedKeys.union(flagKeys)

let actionKeys: Set<CGKeyCode> = Set(allPressedKeys.subtracting(triggerKey).map(\.baseModifier))
let containsTrigger = allPressedKeys.isSuperset(of: triggerKey)
let allPressedKeysBaseModifiers: Set<CGKeyCode> = Set(allPressedKeys.map(\.baseModifier))

if isLoopOpen {
if pressedKeys.contains(.kVK_Escape) {
Expand All @@ -175,10 +177,9 @@ final class KeybindTrigger {
if containsTrigger {
// Try an match directly with the action keys first, then fallback to just the key code.
// This prevents failures when the user is tapping the keys in rapid succession.
let initalMatch = windowActionCache.actionsByKeybind[actionKeys]
let fallbackMatch = windowActionCache.actionsByKeybind[[keyCode]]
let match = windowActionCache.actionsByKeybind[actionKeys] ?? windowActionCache.actionsByKeybind[[keyCode]]

if let action = initalMatch ?? fallbackMatch {
if let action = match {
if !isARepeat || action.canRepeat {
openLoop(startingAction: action, overrideExistingTriggerDelayTimerAction: true)
}
Expand All @@ -196,6 +197,12 @@ final class KeybindTrigger {
)
return .opening
}
} else if let bypassedAction = windowActionCache.bypassedActionsByKeybind[allPressedKeysBaseModifiers] {
if !isARepeat || bypassedAction.canRepeat {
openLoop(startingAction: bypassedAction, overrideExistingTriggerDelayTimerAction: true)
}

return checkIfLoopOpen() ? .consume : .opening
} else {
if allPressedKeys.isEmpty {
doubleClickTimer.handleKeyUp()
Expand Down
73 changes: 31 additions & 42 deletions Loop/Core/WindowDragManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Defaults
import Scribe
import SwiftUI

@MainActor
final class WindowDragManager {
static let shared = WindowDragManager()
private init() {}
Expand Down Expand Up @@ -42,7 +43,6 @@ final class WindowDragManager {
!Defaults[.stashManagerStashedWindows].isEmpty
}

@MainActor
func addObservers() {
accessibilityCheckerTask = Task(priority: .background) { [weak self] in
for await status in AccessibilityManager.shared.stream(initial: true) {
Expand Down Expand Up @@ -90,7 +90,7 @@ final class WindowDragManager {
return
}

Task { @MainActor in
Task {
guard let initialMousePosition else {
initialMousePosition = currentMousePosition
return
Expand All @@ -110,9 +110,6 @@ final class WindowDragManager {
}

if let window = draggingWindow, let initialFrame = initialWindowFrame, hasWindowResized(window.frame, initialFrame) {
StashManager.shared.onWindowDragged(window.cgWindowID)
WindowRecords.eraseRecords(for: window)

if hasWindowMoved(window.frame, initialFrame) {
if Defaults[.restoreWindowFrameOnDrag] {
restoreInitialWindowSize(window)
Expand All @@ -131,28 +128,33 @@ final class WindowDragManager {
processSnapAction()
}
}

StashManager.shared.onWindowDragged(window.cgWindowID)
WindowRecords.eraseRecords(for: window)
}
}
}

private func leftMouseUp(_: CGEvent) {
Task { @MainActor in
guard Defaults[.windowSnapping] else {
return
}

Task {
previewController.close()

if let window = draggingWindow,
let screen = NSScreen.screenWithMouse,
let initialFrame = initialWindowFrame,
hasWindowMoved(window.frame, initialFrame) {
if Defaults[.windowSnapping] {
attemptWindowSnap(window)
}
WindowEngine.resize(window, to: .init(direction), on: screen)
}

previewController.close()
draggingWindow = nil

resetDragState()
}
}

@MainActor
private func setCurrentDraggingWindow() {
guard determineDraggedWindowTask == nil else {
return
Expand All @@ -163,9 +165,8 @@ final class WindowDragManager {
determineDraggedWindowTask = nil
}

guard
let draggingWindow = try? WindowUtility.windowAtPosition(currentMousePosition),
!draggingWindow.isAppExcluded
guard let draggingWindow = try? WindowUtility.windowAtPosition(currentMousePosition),
!draggingWindow.isAppExcluded
else {
didFailToResolveDraggedWindow = true
return
Expand Down Expand Up @@ -263,41 +264,29 @@ final class WindowDragManager {
await AccentColorController.shared.refresh()
}

direction = WindowDirection.getSnapDirection(
let newDirection = WindowDirection.getSnapDirection(
mouseLocation: currentMousePosition,
currentDirection: direction,
currentDirection: oldDirection,
screenFrame: screenFrame,
ignoredFrame: ignoredFrame
)

Log.info("Window snapping direction changed: \(direction.debugDescription)", category: .windowDragManager)
// Only update if direction actually changed
if newDirection != oldDirection {
direction = newDirection

previewController.open(screen: screen, window: draggingWindow, startingAction: nil)
previewController.setAction(to: WindowAction(direction))
} else {
direction = .noAction
previewController.close()
}

if direction != oldDirection {
if Defaults[.hapticFeedback] {
NSHapticFeedbackManager.defaultPerformer.perform(
NSHapticFeedbackManager.FeedbackPattern.alignment,
performanceTime: NSHapticFeedbackManager.PerformanceTime.now
)
}
}
}
Log.info("Window snapping direction changed: \(newDirection.debugDescription)", category: .windowDragManager)

private func attemptWindowSnap(_ window: Window) {
guard let screen = NSScreen.screenWithMouse else {
return
}
previewController.open(screen: screen, window: draggingWindow, startingAction: nil)
previewController.setAction(to: WindowAction(newDirection))

let snapDirection = direction
DispatchQueue.main.async {
WindowEngine.resize(window, to: .init(snapDirection), on: screen)
self.direction = .noAction
if newDirection != .noAction, Defaults[.hapticFeedback] {
NSHapticFeedbackManager.defaultPerformer.perform(.alignment, performanceTime: .now)
}
}
} else if !(oldDirection == .noAction || oldDirection == .noSelection) {
direction = .noAction
previewController.close()
}
}
}
Loading