Skip to content

Commit

Permalink
Add CascadeActiveAppWindows refinements
Browse files Browse the repository at this point in the history
- the cascade goes to the quadrant in which the center of the active window is found
- width and height of the cascaded windows are limited so that they remain within the screen
  • Loading branch information
rudifa committed Jul 27, 2024
1 parent 7eb7d90 commit 765d017
Showing 1 changed file with 41 additions and 17 deletions.
58 changes: 41 additions & 17 deletions Rectangle/MultiWindow/MultiWindowManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class MultiWindowManager {
}
}

static private func allWindowsOnScreen(windowElement: AccessibilityElement? = nil, sortByPID: Bool = false) -> (screens: UsableScreens, windows: [AccessibilityElement])? {
private static func allWindowsOnScreen(windowElement: AccessibilityElement? = nil, sortByPID: Bool = false) -> (screens: UsableScreens, windows: [AccessibilityElement])? {
let screenDetection = ScreenDetection()

guard let windowElement = windowElement ?? AccessibilityElement.getFrontWindowElement(),
Expand All @@ -46,20 +46,20 @@ class MultiWindowManager {
var windows = AccessibilityElement.getAllWindowElements()
if sortByPID {
windows.sort(by: { (w1: AccessibilityElement, w2: AccessibilityElement) -> Bool in
return w1.pid ?? pid_t(0) > w2.pid ?? pid_t(0)
w1.pid ?? pid_t(0) > w2.pid ?? pid_t(0)
})
}

var actualWindows = [AccessibilityElement]()
for w in windows {
if Defaults.todo.userEnabled, TodoManager.isTodoWindow(w) { continue }
let screen = screenDetection.detectScreens(using: w)?.currentScreen
if screen == currentScreen
&& w.isWindow == true
&& w.isSheet != true
&& w.isMinimized != true
&& w.isHidden != true
&& w.isSystemDialog != true
if screen == currentScreen,
w.isWindow == true,
w.isSheet != true,
w.isMinimized != true,
w.isHidden != true,
w.isSystemDialog != true
{
actualWindows.append(w)
}
Expand Down Expand Up @@ -113,6 +113,21 @@ class MultiWindowManager {
}
}

private struct CascadeActiveAppWindows {
var right = false
var bottom = false
var n = 0
var size = CGSizeZero

init(windowFrame: CGRect, screenFrame: CGRect, n: Int, size: CGSize, delta: CGFloat) {
right = windowFrame.midX > screenFrame.midX
bottom = windowFrame.midY > screenFrame.midY
self.n = n
let m = CGSize(width: screenFrame.width - CGFloat(n - 1) * delta, height: screenFrame.height - CGFloat(n - 1) * delta)
self.size = CGSize(width: min(size.width, m.width), height: min(size.height, m.height))
}
}

static func cascadeActiveAppWindowsOnScreen(windowElement: AccessibilityElement? = nil) {
guard let (screens, windows) = allWindowsOnScreen(windowElement: windowElement, sortByPID: true),
let frontWindowElement = AccessibilityElement.getFrontWindowElement()
Expand All @@ -127,18 +142,19 @@ class MultiWindowManager {
// keep windows with a pid equal to the front window's pid
var filtered = windows.filter(hasFrontWindowPid(_:))

var firstSize: CGSize?
// parameters for cascading active app windows
var caaw: CascadeActiveAppWindows?

// move the first to become the last
if let first = filtered.first, hasFrontWindowPid(first) {
if let first = filtered.first {
// move the first to become the last (top)
filtered.removeFirst()
filtered.append(first)
firstSize = first.size
caaw = CascadeActiveAppWindows(windowFrame: first.frame, screenFrame: screenFrame, n: filtered.count, size: first.size!, delta: delta)
}

// cascade the filtered windows
for (ind, w) in filtered.enumerated() {
cascadeWindow(w, screenFrame: screenFrame, delta: delta, index: ind, size: firstSize)
cascadeWindow(w, screenFrame: screenFrame, delta: delta, index: ind, caaw: caaw)
}

// func returning true for a pid equal to the front window's pid
Expand All @@ -147,16 +163,24 @@ class MultiWindowManager {
}
}

private static func cascadeWindow(_ w: AccessibilityElement, screenFrame: CGRect, delta: CGFloat, index: Int, size: CGSize? = nil) {
private static func cascadeWindow(_ w: AccessibilityElement, screenFrame: CGRect, delta: CGFloat, index: Int, caaw: CascadeActiveAppWindows? = nil) {
var rect = w.frame

// TODO: save previous position in history

rect.origin.x = screenFrame.origin.x + delta * CGFloat(index)
rect.origin.y = screenFrame.origin.y + delta * CGFloat(index)
if let size {
rect.size.width = size.width
rect.size.height = size.height

if let caaw {
rect.size.width = caaw.size.width
rect.size.height = caaw.size.height

if caaw.right {
rect.origin.x = screenFrame.origin.x + screenFrame.size.width - caaw.size.width - delta * CGFloat(index)
}
if caaw.bottom {
rect.origin.y = screenFrame.origin.y + screenFrame.size.height - caaw.size.height - delta * CGFloat(caaw.n - 1 - index)
}
}

w.setFrame(rect)
Expand Down

0 comments on commit 765d017

Please sign in to comment.