Skip to content

Commit 6dde91b

Browse files
committed
Fix data race bug: floating windows could stuck in a corner
#1987 AeroSpace has idempotent architecture: hideInCorner can be called multiple times. isHiddenInCorner serves as guard against writing invalid values to prevUnhiddenProportionalPositionInsideWorkspaceRect. We should make sure that there are no suspension points between the guard check and the prevUnhiddenProportionalPositionInsideWorkspaceRect assignment. Kudos to the community for finding this bug and the root cause. Specifically to: - https://github.com/fbuetler (#1875 (comment)) - https://github.com/tweezerticle (#1875 (comment)) - https://github.com/buacanning (#1985) (cherry picked from commit 90a7c67)
1 parent 8a49e10 commit 6dde91b

1 file changed

Lines changed: 9 additions & 7 deletions

File tree

Sources/AppBundle/tree/MacWindow.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,17 @@ final class MacWindow: Window {
125125
@MainActor
126126
func hideInCorner(_ corner: OptimalHideCorner) async throws {
127127
guard let nodeMonitor else { return }
128-
// Don't accidentally override prevUnhiddenEmulationPosition in case of subsequent
129-
// `hideEmulation` calls
128+
// Don't accidentally override prevUnhiddenEmulationPosition in case of subsequent `hideInCorner` calls
130129
if !isHiddenInCorner {
131130
guard let windowRect = try await getAxRect() else { return }
132-
let topLeftCorner = windowRect.topLeftCorner
133-
let monitorRect = windowRect.center.monitorApproximation.rect // Similar to layoutFloatingWindow. Non idempotent
134-
let absolutePoint = topLeftCorner - monitorRect.topLeftCorner
135-
prevUnhiddenProportionalPositionInsideWorkspaceRect =
136-
CGPoint(x: absolutePoint.x / monitorRect.width, y: absolutePoint.y / monitorRect.height)
131+
// Check for isHiddenInCorner for the second time because of the suspension point above
132+
if !isHiddenInCorner {
133+
let topLeftCorner = windowRect.topLeftCorner
134+
let monitorRect = windowRect.center.monitorApproximation.rect // Similar to layoutFloatingWindow. Non idempotent
135+
let absolutePoint = topLeftCorner - monitorRect.topLeftCorner
136+
prevUnhiddenProportionalPositionInsideWorkspaceRect =
137+
CGPoint(x: absolutePoint.x / monitorRect.width, y: absolutePoint.y / monitorRect.height)
138+
}
137139
}
138140
let p: CGPoint
139141
switch corner {

0 commit comments

Comments
 (0)