Skip to content

Commit bd9df70

Browse files
committed
Support resizing floating windows.
1 parent e90b73c commit bd9df70

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

Sources/AppBundle/command/impl/ResizeCommand.swift

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,79 @@ struct ResizeCommand: Command { // todo cover with tests
88
check(Thread.current.isMainThread)
99
guard let target = args.resolveTargetOrReportError(env, io) else { return false }
1010

11+
if let window = target.windowOrNil, window.isFloating {
12+
guard let size = window.getSize(), let topLeftCorner = window.getTopLeftCorner() else { return false }
13+
14+
let computeTopLeftCorner = { (newSize: CGSize) -> CGPoint in
15+
let newX = if topLeftCorner.x + newSize.width > target.workspace.workspaceMonitor.width {
16+
max(0, topLeftCorner.x - (topLeftCorner.x + newSize.width - target.workspace.workspaceMonitor.width))
17+
} else {
18+
topLeftCorner.x
19+
}
20+
21+
let newY = if topLeftCorner.y + newSize.height > target.workspace.workspaceMonitor.height {
22+
max(0, topLeftCorner.y - (topLeftCorner.y + newSize.height - target.workspace.workspaceMonitor.height))
23+
} else {
24+
topLeftCorner.y
25+
}
26+
27+
return CGPoint(x: newX, y: newY)
28+
}
29+
30+
let newTopLeftCorner: CGPoint
31+
let newSize: CGSize
32+
let isWidthDominant = size.width >= size.height
33+
34+
switch args.dimension.val {
35+
case .width:
36+
let diff: CGFloat = switch args.units.val {
37+
case .set(let unit): CGFloat(unit) - size.width
38+
case .add(let unit): CGFloat(unit)
39+
case .subtract(let unit): -CGFloat(unit)
40+
}
41+
let width = size.width + diff
42+
newSize = CGSize(width: width, height: size.height)
43+
newTopLeftCorner = computeTopLeftCorner(newSize)
44+
45+
case .height:
46+
let diff: CGFloat = switch args.units.val {
47+
case .set(let unit): CGFloat(unit) - size.height
48+
case .add(let unit): CGFloat(unit)
49+
case .subtract(let unit): -CGFloat(unit)
50+
}
51+
let height = size.height + diff
52+
newSize = CGSize(width: size.width, height: height)
53+
newTopLeftCorner = computeTopLeftCorner(newSize)
54+
55+
case .smart:
56+
let diff: CGFloat = switch args.units.val {
57+
case .set(let unit): CGFloat(unit) - (isWidthDominant ? size.width : size.height)
58+
case .add(let unit): CGFloat(unit)
59+
case .subtract(let unit): -CGFloat(unit)
60+
}
61+
newSize = if isWidthDominant {
62+
CGSize(width: size.width + diff, height: size.height + diff * (size.height / size.width))
63+
} else {
64+
CGSize(width: size.width + diff * (size.width / size.height), height: size.height + diff)
65+
}
66+
newTopLeftCorner = computeTopLeftCorner(newSize)
67+
68+
case .smartOpposite:
69+
let diff: CGFloat = switch args.units.val {
70+
case .set(let unit): CGFloat(unit) - (isWidthDominant ? size.height : size.width)
71+
case .add(let unit): CGFloat(unit)
72+
case .subtract(let unit): -CGFloat(unit)
73+
}
74+
newSize = if isWidthDominant {
75+
CGSize(width: size.width + diff * (size.width / size.height), height: size.height + diff)
76+
} else {
77+
CGSize(width: size.width + diff, height: size.height + diff * (size.height / size.width))
78+
}
79+
newTopLeftCorner = computeTopLeftCorner(newSize)
80+
}
81+
return window.setFrame(newTopLeftCorner, newSize)
82+
}
83+
1184
let candidates = target.windowOrNil?.parentsWithSelf
1285
.filter { ($0.parent as? TilingContainer)?.layout == .tiles }
1386
?? []

0 commit comments

Comments
 (0)