fix: stabilize aspect locked queue window resizing
This commit is contained in:
@@ -197,6 +197,8 @@ final class CompactWindowController: NSObject {
|
||||
// NSObject forwarding returns untyped Any; accesses remain on AppKit's main thread.
|
||||
nonisolated(unsafe) weak var original: (any NSWindowDelegate)?
|
||||
private weak var owner: CompactWindowController?
|
||||
private var resizeStartSize: NSSize?
|
||||
private var resizeWidthDriven: Bool?
|
||||
|
||||
init(owner: CompactWindowController, original: (any NSWindowDelegate)?) {
|
||||
self.owner = owner
|
||||
@@ -212,6 +214,19 @@ final class CompactWindowController: NSObject {
|
||||
let responds = MainActor.assumeIsolated { original?.responds(to: selector) ?? false }
|
||||
return responds ? original : nil
|
||||
}
|
||||
|
||||
func windowWillStartLiveResize(_ notification: Notification) {
|
||||
resizeStartSize = (notification.object as? NSWindow)?.frame.size
|
||||
resizeWidthDriven = nil
|
||||
original?.windowWillStartLiveResize?(notification)
|
||||
}
|
||||
|
||||
func windowDidEndLiveResize(_ notification: Notification) {
|
||||
resizeStartSize = nil
|
||||
resizeWidthDriven = nil
|
||||
original?.windowDidEndLiveResize?(notification)
|
||||
}
|
||||
|
||||
func windowWillResize(_ sender: NSWindow, to proposedSize: NSSize) -> NSSize {
|
||||
let proposed = original?.windowWillResize?(sender, to: proposedSize) ?? proposedSize
|
||||
guard let owner, !owner.isCompact, !owner.isTransitioning,
|
||||
@@ -220,8 +235,16 @@ final class CompactWindowController: NSObject {
|
||||
layout.aspect.isFinite, layout.aspect > 0 else { return proposed }
|
||||
// The sidebar stays fixed-width; only the video area is aspect-locked.
|
||||
let chrome = sender.frame.height - sender.contentRect(forFrameRect: sender.frame).height
|
||||
let widthDriven = abs(proposed.width - sender.frame.width) >=
|
||||
abs(proposed.height - sender.frame.height) * layout.aspect
|
||||
let start = resizeStartSize ?? sender.frame.size
|
||||
let widthChange = abs(proposed.width - start.width)
|
||||
let heightChange = abs(proposed.height - start.height) * layout.aspect
|
||||
// Latch the user's axis once. Comparing against each corrected frame
|
||||
// makes our own aspect adjustment look like a new drag on the other axis.
|
||||
if resizeStartSize != nil, resizeWidthDriven == nil,
|
||||
widthChange > 0 || heightChange > 0 {
|
||||
resizeWidthDriven = widthChange >= heightChange
|
||||
}
|
||||
let widthDriven = resizeWidthDriven ?? (widthChange >= heightChange)
|
||||
let minimumHeight = max(sender.minSize.height - chrome,
|
||||
(sender.minSize.width - layout.sidebarWidth) / layout.aspect)
|
||||
let height = max(minimumHeight, widthDriven
|
||||
|
||||
Reference in New Issue
Block a user