diff --git a/Loop/Window Management/Window Manipulation/ResizeContext.swift b/Loop/Window Management/Window Manipulation/ResizeContext.swift index 237db048..2787e39a 100644 --- a/Loop/Window Management/Window Manipulation/ResizeContext.swift +++ b/Loop/Window Management/Window Manipulation/ResizeContext.swift @@ -131,6 +131,13 @@ final class ResizeContext { } private func recomputeTargetFrame() { + // Clear the recompute guard *before* resolving so this method is re-entrancy safe: + // if `WindowFrameResolver.getFrame` ever reads `getTargetFrame()` on this same + // context while it is still being computed, the guard is already clear and the + // re-entrant call returns the cached frame instead of recomputing and recursing + // until the stack overflows. + needsRecompute = false + let result = WindowFrameResolver.getFrame(resizeContext: self) let normalized = CGRect( @@ -152,7 +159,6 @@ final class ResizeContext { normalized: normalized, padded: paddedFrame ) - needsRecompute = false log.info("Computed target frame - raw: \(cachedTargetFrame.raw), normalized: \(cachedTargetFrame.normalized) padded: \(cachedTargetFrame.padded), for action: \(action)") } diff --git a/Loop/Window Management/Window Manipulation/WindowFrameResolver.swift b/Loop/Window Management/Window Manipulation/WindowFrameResolver.swift index bfb5ef69..f0efe634 100644 --- a/Loop/Window Management/Window Manipulation/WindowFrameResolver.swift +++ b/Loop/Window Management/Window Manipulation/WindowFrameResolver.swift @@ -201,7 +201,12 @@ extension WindowFrameResolver { ) } else if direction.willMove { - let frameToResizeFrom = context.getTargetFrame().raw + // Read the last applied frame (falling back to the cached target) instead of + // `context.getTargetFrame()`. `getTargetFrame()` would recompute this very + // context and re-enter here, recursing until the stack overflows. Matching the + // grow/shrink branches above also keeps moves anchored to the window's actual + // position rather than a theoretical (possibly clamped-away) target frame. + let frameToResizeFrom = context.lastAppliedFrame ?? context.cachedTargetFrame.raw result = calculatePositionAdjustment(for: action, frameToResizeFrom: frameToResizeFrom)