fix: restore positive resize increments when clearing aspect lock

This commit is contained in:
2026-10-18 02:11:16 +02:00
parent 3e782aff31
commit dd02383c0b
5 changed files with 23 additions and 7 deletions
+1
View File
@@ -298,6 +298,7 @@ def check_cli_instances(root, app, fixtures):
"queue preserves video size and mouse target", action="queue", visible=True)
window = opened[first_pid]["window"]
if (not window["resizable"] or window["aspectWidth"] != 0 or window["aspectHeight"] != 0
or window["resizeIncrementWidth"] <= 0 or window["resizeIncrementHeight"] <= 0
or window["minWidth"] > 660 or window["minHeight"] > 300
or window["maxWidth"] <= window["width"] + 80
or window["maxHeight"] <= window["height"] + 80
+2
View File
@@ -111,6 +111,8 @@ private enum CLIInstanceCheck {
"contentMinWidth": window.contentMinSize.width, "contentMinHeight": window.contentMinSize.height,
"contentMaxWidth": window.contentMaxSize.width, "contentMaxHeight": window.contentMaxSize.height,
"aspectWidth": window.aspectRatio.width, "aspectHeight": window.aspectRatio.height,
"resizeIncrementWidth": window.resizeIncrements.width,
"resizeIncrementHeight": window.resizeIncrements.height,
"resizable": window.styleMask.contains(.resizable),
]
if let surface = surface(in: content) {
+2
View File
@@ -157,6 +157,8 @@ The full suite requires a graphical macOS session and a working audio device; it
The startup checks verify that playing video remains attached, unhidden and sized to its native drag surface, including with the queue open; playback-state checks alone do not establish renderer visibility.
Queue-open resize checks also require positive native resize increments: clearing AppKit's aspect ratio alone leaves zero increments after aspect-locked video. Physical edge-drag resizing still needs manual verification.
`make benchmark-playback` measures cold source startup, cached/uncached seeks, and sustained native/Cast playback with repeatable loopback fixtures. It requires the same macOS session/audio device and fixture-generation FFmpeg; results exclude live extraction, WAN/TLS, and physical-receiver latency.
The [benchmark runner](Checks/playback-benchmark.py) accepts `--compare-native <baseline-binary>` for alternating native-only comparisons; add `--seek-work` to isolate cache-miss seeks when both binaries support that mode. Preserve the baseline executable before rebuilding.
+7 -1
View File
@@ -20,6 +20,7 @@ final class CompactWindowController: NSObject {
let minSize: NSSize
let contentMinSize: NSSize
let aspectRatio: NSSize
let resizeIncrements: NSSize
let styleMask: NSWindow.StyleMask
let titleVisibility: NSWindow.TitleVisibility
let titlebarAppearsTransparent: Bool
@@ -34,6 +35,7 @@ final class CompactWindowController: NSObject {
minSize = window.minSize
contentMinSize = window.contentMinSize
aspectRatio = window.aspectRatio
resizeIncrements = window.resizeIncrements
styleMask = window.styleMask
titleVisibility = window.titleVisibility
titlebarAppearsTransparent = window.titlebarAppearsTransparent
@@ -310,7 +312,11 @@ final class CompactWindowController: NSObject {
window.minSize = snapshot.minSize
window.contentMinSize = snapshot.contentMinSize
window.setFrame(snapshot.frame, display: true)
if snapshot.aspectRatio == .zero {
window.resizeIncrements = snapshot.resizeIncrements
} else {
window.aspectRatio = snapshot.aspectRatio
}
self.snapshot = nil
}
@@ -380,7 +386,7 @@ final class CompactWindowController: NSObject {
frame.origin.x = min(max(window.frame.minX, usable.minX), usable.maxX - frame.width)
frame.origin.y = min(max(window.frame.minY, usable.minY), usable.maxY - frame.height)
}
window.aspectRatio = .zero
window.resizeIncrements = NSSize(width: 1, height: 1)
animateFrame(frame, of: window, animated: animated) { [weak self, weak window] in
guard let self, let window else { return }
if Self.canFitAspect(aspect, available: usable.size) {
+10 -5
View File
@@ -36,7 +36,8 @@ final class PlayerModel: ObservableObject {
didSet {
guard showsQueue != oldValue, let window, !isFullScreen,
!isCompact, !compactWindow.isTransitioning else { return }
window.aspectRatio = .zero
// Setting aspectRatio to zero leaves AppKit's resize increments at zero.
window.resizeIncrements = NSSize(width: 1, height: 1)
var frame = window.frame
frame.size.width += showsQueue ? 260 : -260
if let screen = window.screen?.visibleFrame {
@@ -706,7 +707,7 @@ final class PlayerModel: ObservableObject {
youtubeHeight = nil
youtubeQuality = nil
needsVideoFit = false
window?.aspectRatio = .zero
window?.resizeIncrements = NSSize(width: 1, height: 1)
commandError = nil
isSeeking = false
window?.representedURL = nil
@@ -979,7 +980,7 @@ final class PlayerModel: ObservableObject {
}
needsVideoFit = false
guard state.has_video, aspect.isFinite, aspect > 0 else {
window.aspectRatio = .zero
window.resizeIncrements = NSSize(width: 1, height: 1)
return
}
let screen = (window.screen ?? NSScreen.main)?.visibleFrame ?? window.frame
@@ -988,10 +989,14 @@ final class PlayerModel: ObservableObject {
let size = NSSize(width: width + sidebarWidth, height: width / aspect)
// ponytail: extreme ratios retain letterboxing; compact controls if exact fitting is needed.
guard size.width >= window.minSize.width, size.height >= window.minSize.height else {
window.aspectRatio = .zero
window.resizeIncrements = NSSize(width: 1, height: 1)
return
}
window.aspectRatio = showsQueue ? .zero : NSSize(width: aspect, height: 1)
if showsQueue {
window.resizeIncrements = NSSize(width: 1, height: 1)
} else {
window.aspectRatio = NSSize(width: aspect, height: 1)
}
let frame = NSRect(
x: min(max(window.frame.midX - size.width / 2, screen.minX), screen.maxX - size.width),
y: min(max(window.frame.midY - size.height / 2, screen.minY), screen.maxY - size.height),