Skip to content

Commit

Permalink
Initial rough draft of adding the animation delay
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan Hanson committed Apr 13, 2020
1 parent 3a82783 commit ea40004
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 73 deletions.
12 changes: 4 additions & 8 deletions Rectangle.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
9824704B22B189250037B409 /* StandardWindowMover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9824704622B189240037B409 /* StandardWindowMover.swift */; };
9824704C22B189250037B409 /* WindowMover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9824704722B189240037B409 /* WindowMover.swift */; };
9824704D22B189250037B409 /* WindowCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9824704822B189250037B409 /* WindowCalculation.swift */; };
9824704E22B189250037B409 /* QuantizedWindowMover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9824704922B189250037B409 /* QuantizedWindowMover.swift */; };
9824704F22B189250037B409 /* BestEffortWindowMover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9824704A22B189250037B409 /* BestEffortWindowMover.swift */; };
9824705122B28D7A0037B409 /* LeftRightHalfCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9824705022B28D7A0037B409 /* LeftRightHalfCalculation.swift */; };
985B9BF522B93EEC00A2E8F0 /* ApplicationToggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985B9BF422B93EEC00A2E8F0 /* ApplicationToggle.swift */; };
Expand Down Expand Up @@ -147,7 +146,6 @@
9824704622B189240037B409 /* StandardWindowMover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StandardWindowMover.swift; sourceTree = "<group>"; };
9824704722B189240037B409 /* WindowMover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowMover.swift; sourceTree = "<group>"; };
9824704822B189250037B409 /* WindowCalculation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowCalculation.swift; sourceTree = "<group>"; };
9824704922B189250037B409 /* QuantizedWindowMover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QuantizedWindowMover.swift; sourceTree = "<group>"; };
9824704A22B189250037B409 /* BestEffortWindowMover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BestEffortWindowMover.swift; sourceTree = "<group>"; };
9824705022B28D7A0037B409 /* LeftRightHalfCalculation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightHalfCalculation.swift; sourceTree = "<group>"; };
985B9BF422B93EEC00A2E8F0 /* ApplicationToggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationToggle.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -315,7 +313,6 @@
isa = PBXGroup;
children = (
9824704A22B189250037B409 /* BestEffortWindowMover.swift */,
9824704922B189250037B409 /* QuantizedWindowMover.swift */,
9824704622B189240037B409 /* StandardWindowMover.swift */,
9824704722B189240037B409 /* WindowMover.swift */,
98B3559723CE025700E410E0 /* CenteringFixedSizedWindowMover.swift */,
Expand Down Expand Up @@ -725,7 +722,6 @@
9824704B22B189250037B409 /* StandardWindowMover.swift in Sources */,
9821402722B3888100ABFB3F /* ChangeSizeCalculation.swift in Sources */,
98B3559823CE025700E410E0 /* CenteringFixedSizedWindowMover.swift in Sources */,
9824704E22B189250037B409 /* QuantizedWindowMover.swift in Sources */,
9824703B22B139780037B409 /* CUtil.swift in Sources */,
988D067D22EB4E17004EABD7 /* AlmostMaximizeCalculation.swift in Sources */,
98C1008C2305F1FA006E5344 /* SubsequentExecutionMode.swift in Sources */,
Expand Down Expand Up @@ -1005,7 +1001,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 29;
CURRENT_PROJECT_VERSION = 30;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = NO;
INFOPLIST_FILE = Rectangle/Info.plist;
Expand All @@ -1014,7 +1010,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
MARKETING_VERSION = 0.25;
MARKETING_VERSION = 0.25.1;
PRODUCT_BUNDLE_IDENTIFIER = com.knollsoft.Rectangle;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand All @@ -1031,7 +1027,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 29;
CURRENT_PROJECT_VERSION = 30;
DEVELOPMENT_TEAM = XSYZ3E4B7D;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = Rectangle/Info.plist;
Expand All @@ -1040,7 +1036,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
MARKETING_VERSION = 0.25;
MARKETING_VERSION = 0.25.1;
PRODUCT_BUNDLE_IDENTIFIER = com.knollsoft.Rectangle;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down
15 changes: 13 additions & 2 deletions Rectangle/AccessibilityElement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,22 @@ class AccessibilityElement {
}
return CGRect(x: position.x, y: position.y, width: size.width, height: size.height)
}

func setRectOf(_ rect: CGRect) {

func setRectOf(_ rect: CGRect, completion: ((Bool) -> ())?) {
set(size: rect.size)
if let completion = completion {
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(Defaults.animationDelay.value)) {
self.set(position: rect.origin)
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(Defaults.animationDelay.value)) {
self.set(size: rect.size)
completion(rect == self.rectOfElement())
}
}
} else {
set(size: rect.size)
set(position: rect.origin)
set(size: rect.size)
}
}

func isResizable() -> Bool {
Expand Down
1 change: 1 addition & 0 deletions Rectangle/Defaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Defaults {
static let centeredDirectionalMove = OptionalBoolDefault(key: "centeredDirectionalMove")
static let ignoredSnapAreas = IntDefault(key: "ignoredSnapAreas")
static let traverseSingleScreen = OptionalBoolDefault(key: "traverseSingleScreen")
static let animationDelay = IntDefault(key: "animationDelay")
}

class BoolDefault {
Expand Down
63 changes: 44 additions & 19 deletions Rectangle/WindowManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,15 @@ class WindowManager {
private let windowHistory: WindowHistory
private let gapSize = Defaults.gapSize.value

private let standardWindowMover = StandardWindowMover()
private let bestEffortWindowMover = BestEffortWindowMover()
private let centeringFixedSizedMover = CenteringFixedSizedWindowMover()

init(windowCalculationFactory: WindowCalculationFactory, windowHistory: WindowHistory) {
self.windowCalculationFactory = windowCalculationFactory
self.windowHistory = windowHistory
standardWindowMoverChain = [
StandardWindowMover(),
// QuantizedWindowMover(), // This was used in Spectacle, but doesn't seem to help on any windows I've tried. It just makes some actions feel more jenky
BestEffortWindowMover()
]

fixedSizeWindowMoverChain = [
CenteringFixedSizedWindowMover(),
BestEffortWindowMover()
]
standardWindowMoverChain = [standardWindowMover, bestEffortWindowMover]
fixedSizeWindowMoverChain = [centeringFixedSizedMover, bestEffortWindowMover]
}

func execute(_ parameters: ExecutionParameters) {
Expand All @@ -44,10 +40,15 @@ class WindowManager {

if action == .restore {
if let restoreRect = windowHistory.restoreRects[windowId] {
frontmostWindowElement.setRectOf(restoreRect)
if Defaults.animationDelay.value > 0 {
frontmostWindowElement.setRectOf(restoreRect, completion: nil)
} else {
frontmostWindowElement.setRectOf(restoreRect) { success in
self.windowHistory.lastRectangleActions.removeValue(forKey: windowId)
}
}
return
}
windowHistory.lastRectangleActions.removeValue(forKey: windowId)
return
}

var screens: UsableScreens?
Expand Down Expand Up @@ -108,14 +109,38 @@ class WindowManager {
let visibleFrameOfDestinationScreen = NSRectToCGRect(calcResult.screen.visibleFrame)

let useFixedSizeMover = !frontmostWindowElement.isResizable() && action.resizes
let windowMoverChain = useFixedSizeMover
? fixedSizeWindowMoverChain
: standardWindowMoverChain

for windowMover in windowMoverChain {
windowMover.moveWindowRect(newNormalizedRect, frameOfScreen: usableScreens.frameOfCurrentScreen, visibleFrameOfScreen: visibleFrameOfDestinationScreen, frontmostWindowElement: frontmostWindowElement, action: action)

if Defaults.animationDelay.value > 0 {
if useFixedSizeMover {
centeringFixedSizedMover.moveWindowRect(newNormalizedRect, frameOfScreen: usableScreens.frameOfCurrentScreen, visibleFrameOfScreen: visibleFrameOfDestinationScreen, frontmostWindowElement: frontmostWindowElement, action: action) {_ in
self.bestEffortWindowMover.moveWindowRect(newNormalizedRect, frameOfScreen: usableScreens.frameOfCurrentScreen, visibleFrameOfScreen: visibleFrameOfDestinationScreen, frontmostWindowElement: frontmostWindowElement, action: action) {_ in

self.windowMovementComplete(frontmostWindowElement: frontmostWindowElement, calcResult: calcResult, lastRectangleAction: lastRectangleAction, windowId: windowId, usableScreens: usableScreens, newNormalizedRect: newNormalizedRect, action: action, visibleFrameOfDestinationScreen: visibleFrameOfDestinationScreen)
}
}
} else {
standardWindowMover.moveWindowRect(newNormalizedRect, frameOfScreen: usableScreens.frameOfCurrentScreen, visibleFrameOfScreen: visibleFrameOfDestinationScreen, frontmostWindowElement: frontmostWindowElement, action: action) {_ in
self.bestEffortWindowMover.moveWindowRect(newNormalizedRect, frameOfScreen: usableScreens.frameOfCurrentScreen, visibleFrameOfScreen: visibleFrameOfDestinationScreen, frontmostWindowElement: frontmostWindowElement, action: action) {_ in

self.windowMovementComplete(frontmostWindowElement: frontmostWindowElement, calcResult: calcResult, lastRectangleAction: lastRectangleAction, windowId: windowId, usableScreens: usableScreens, newNormalizedRect: newNormalizedRect, action: action, visibleFrameOfDestinationScreen: visibleFrameOfDestinationScreen)
}
}
}
}
else {
let windowMoverChain = useFixedSizeMover
? fixedSizeWindowMoverChain
: standardWindowMoverChain

for windowMover in windowMoverChain {
windowMover.moveWindowRect(newNormalizedRect, frameOfScreen: usableScreens.frameOfCurrentScreen, visibleFrameOfScreen: visibleFrameOfDestinationScreen, frontmostWindowElement: frontmostWindowElement, action: action, completion: nil)
}

windowMovementComplete(frontmostWindowElement: frontmostWindowElement, calcResult: calcResult, lastRectangleAction: lastRectangleAction, windowId: windowId, usableScreens: usableScreens, newNormalizedRect: newNormalizedRect, action: action, visibleFrameOfDestinationScreen: visibleFrameOfDestinationScreen)
}
}

private func windowMovementComplete(frontmostWindowElement: AccessibilityElement, calcResult: WindowCalculationResult, lastRectangleAction: RectangleAction?, windowId: Int, usableScreens: UsableScreens, newNormalizedRect: CGRect, action: WindowAction, visibleFrameOfDestinationScreen: CGRect) {
let resultingRect = frontmostWindowElement.rectOfElement()

var newCount = 1
Expand Down
4 changes: 2 additions & 2 deletions Rectangle/WindowMover/BestEffortWindowMover.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Foundation
*/

class BestEffortWindowMover: WindowMover {
func moveWindowRect(_ windowRect: CGRect, frameOfScreen: CGRect, visibleFrameOfScreen: CGRect, frontmostWindowElement: AccessibilityElement?, action: WindowAction?) {
func moveWindowRect(_ windowRect: CGRect, frameOfScreen: CGRect, visibleFrameOfScreen: CGRect, frontmostWindowElement: AccessibilityElement?, action: WindowAction?, completion: ((Bool)->())?) {
guard let currentWindowRect: CGRect = frontmostWindowElement?.rectOfElement() else { return }

var adjustedWindowRect: CGRect = currentWindowRect
Expand All @@ -39,7 +39,7 @@ class BestEffortWindowMover: WindowMover {

adjustedWindowRect = AccessibilityElement.normalizeCoordinatesOf(adjustedWindowRect, frameOfScreen: frameOfScreen)
if !currentWindowRect.equalTo(adjustedWindowRect) {
frontmostWindowElement?.setRectOf(adjustedWindowRect)
frontmostWindowElement?.setRectOf(adjustedWindowRect, completion: completion)
}
}
}
4 changes: 2 additions & 2 deletions Rectangle/WindowMover/CenteringFixedSizedWindowMover.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Foundation

class CenteringFixedSizedWindowMover: WindowMover {

func moveWindowRect(_ windowRect: CGRect, frameOfScreen: CGRect, visibleFrameOfScreen: CGRect, frontmostWindowElement: AccessibilityElement?, action: WindowAction?) {
func moveWindowRect(_ windowRect: CGRect, frameOfScreen: CGRect, visibleFrameOfScreen: CGRect, frontmostWindowElement: AccessibilityElement?, action: WindowAction?, completion: ((Bool)->())?) {
guard let currentWindowRect: CGRect = frontmostWindowElement?.rectOfElement() else { return }

var adjustedWindowRect: CGRect = currentWindowRect
Expand All @@ -28,7 +28,7 @@ class CenteringFixedSizedWindowMover: WindowMover {
}

if !adjustedWindowRect.equalTo(currentWindowRect) {
frontmostWindowElement?.setRectOf(adjustedWindowRect)
frontmostWindowElement?.setRectOf(adjustedWindowRect, completion: completion)
}
}
}
37 changes: 0 additions & 37 deletions Rectangle/WindowMover/QuantizedWindowMover.swift

This file was deleted.

4 changes: 2 additions & 2 deletions Rectangle/WindowMover/StandardWindowMover.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
import Foundation

class StandardWindowMover: WindowMover {
func moveWindowRect(_ windowRect: CGRect, frameOfScreen: CGRect, visibleFrameOfScreen: CGRect, frontmostWindowElement: AccessibilityElement?, action: WindowAction?) {
func moveWindowRect(_ windowRect: CGRect, frameOfScreen: CGRect, visibleFrameOfScreen: CGRect, frontmostWindowElement: AccessibilityElement?, action: WindowAction?, completion: ((Bool)->())?) {
let previousWindowRect: CGRect? = frontmostWindowElement?.rectOfElement()
if previousWindowRect?.isNull == true {
return
}
frontmostWindowElement?.setRectOf(windowRect)
frontmostWindowElement?.setRectOf(windowRect, completion: completion)
}
}
2 changes: 1 addition & 1 deletion Rectangle/WindowMover/WindowMover.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
import Foundation

protocol WindowMover {
func moveWindowRect(_ windowRect: CGRect, frameOfScreen: CGRect, visibleFrameOfScreen: CGRect, frontmostWindowElement: AccessibilityElement?, action: WindowAction?)
func moveWindowRect(_ windowRect: CGRect, frameOfScreen: CGRect, visibleFrameOfScreen: CGRect, frontmostWindowElement: AccessibilityElement?, action: WindowAction?, completion: ((Bool) -> ())?)
}

0 comments on commit ea40004

Please sign in to comment.