fix: restore positive resize increments when clearing aspect lock
This commit is contained in:
@@ -298,6 +298,7 @@ def check_cli_instances(root, app, fixtures):
|
|||||||
"queue preserves video size and mouse target", action="queue", visible=True)
|
"queue preserves video size and mouse target", action="queue", visible=True)
|
||||||
window = opened[first_pid]["window"]
|
window = opened[first_pid]["window"]
|
||||||
if (not window["resizable"] or window["aspectWidth"] != 0 or window["aspectHeight"] != 0
|
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["minWidth"] > 660 or window["minHeight"] > 300
|
||||||
or window["maxWidth"] <= window["width"] + 80
|
or window["maxWidth"] <= window["width"] + 80
|
||||||
or window["maxHeight"] <= window["height"] + 80
|
or window["maxHeight"] <= window["height"] + 80
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ private enum CLIInstanceCheck {
|
|||||||
"contentMinWidth": window.contentMinSize.width, "contentMinHeight": window.contentMinSize.height,
|
"contentMinWidth": window.contentMinSize.width, "contentMinHeight": window.contentMinSize.height,
|
||||||
"contentMaxWidth": window.contentMaxSize.width, "contentMaxHeight": window.contentMaxSize.height,
|
"contentMaxWidth": window.contentMaxSize.width, "contentMaxHeight": window.contentMaxSize.height,
|
||||||
"aspectWidth": window.aspectRatio.width, "aspectHeight": window.aspectRatio.height,
|
"aspectWidth": window.aspectRatio.width, "aspectHeight": window.aspectRatio.height,
|
||||||
|
"resizeIncrementWidth": window.resizeIncrements.width,
|
||||||
|
"resizeIncrementHeight": window.resizeIncrements.height,
|
||||||
"resizable": window.styleMask.contains(.resizable),
|
"resizable": window.styleMask.contains(.resizable),
|
||||||
]
|
]
|
||||||
if let surface = surface(in: content) {
|
if let surface = surface(in: content) {
|
||||||
|
|||||||
@@ -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.
|
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.
|
`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.
|
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.
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ final class CompactWindowController: NSObject {
|
|||||||
let minSize: NSSize
|
let minSize: NSSize
|
||||||
let contentMinSize: NSSize
|
let contentMinSize: NSSize
|
||||||
let aspectRatio: NSSize
|
let aspectRatio: NSSize
|
||||||
|
let resizeIncrements: NSSize
|
||||||
let styleMask: NSWindow.StyleMask
|
let styleMask: NSWindow.StyleMask
|
||||||
let titleVisibility: NSWindow.TitleVisibility
|
let titleVisibility: NSWindow.TitleVisibility
|
||||||
let titlebarAppearsTransparent: Bool
|
let titlebarAppearsTransparent: Bool
|
||||||
@@ -34,6 +35,7 @@ final class CompactWindowController: NSObject {
|
|||||||
minSize = window.minSize
|
minSize = window.minSize
|
||||||
contentMinSize = window.contentMinSize
|
contentMinSize = window.contentMinSize
|
||||||
aspectRatio = window.aspectRatio
|
aspectRatio = window.aspectRatio
|
||||||
|
resizeIncrements = window.resizeIncrements
|
||||||
styleMask = window.styleMask
|
styleMask = window.styleMask
|
||||||
titleVisibility = window.titleVisibility
|
titleVisibility = window.titleVisibility
|
||||||
titlebarAppearsTransparent = window.titlebarAppearsTransparent
|
titlebarAppearsTransparent = window.titlebarAppearsTransparent
|
||||||
@@ -310,7 +312,11 @@ final class CompactWindowController: NSObject {
|
|||||||
window.minSize = snapshot.minSize
|
window.minSize = snapshot.minSize
|
||||||
window.contentMinSize = snapshot.contentMinSize
|
window.contentMinSize = snapshot.contentMinSize
|
||||||
window.setFrame(snapshot.frame, display: true)
|
window.setFrame(snapshot.frame, display: true)
|
||||||
window.aspectRatio = snapshot.aspectRatio
|
if snapshot.aspectRatio == .zero {
|
||||||
|
window.resizeIncrements = snapshot.resizeIncrements
|
||||||
|
} else {
|
||||||
|
window.aspectRatio = snapshot.aspectRatio
|
||||||
|
}
|
||||||
self.snapshot = nil
|
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.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)
|
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
|
animateFrame(frame, of: window, animated: animated) { [weak self, weak window] in
|
||||||
guard let self, let window else { return }
|
guard let self, let window else { return }
|
||||||
if Self.canFitAspect(aspect, available: usable.size) {
|
if Self.canFitAspect(aspect, available: usable.size) {
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ final class PlayerModel: ObservableObject {
|
|||||||
didSet {
|
didSet {
|
||||||
guard showsQueue != oldValue, let window, !isFullScreen,
|
guard showsQueue != oldValue, let window, !isFullScreen,
|
||||||
!isCompact, !compactWindow.isTransitioning else { return }
|
!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
|
var frame = window.frame
|
||||||
frame.size.width += showsQueue ? 260 : -260
|
frame.size.width += showsQueue ? 260 : -260
|
||||||
if let screen = window.screen?.visibleFrame {
|
if let screen = window.screen?.visibleFrame {
|
||||||
@@ -706,7 +707,7 @@ final class PlayerModel: ObservableObject {
|
|||||||
youtubeHeight = nil
|
youtubeHeight = nil
|
||||||
youtubeQuality = nil
|
youtubeQuality = nil
|
||||||
needsVideoFit = false
|
needsVideoFit = false
|
||||||
window?.aspectRatio = .zero
|
window?.resizeIncrements = NSSize(width: 1, height: 1)
|
||||||
commandError = nil
|
commandError = nil
|
||||||
isSeeking = false
|
isSeeking = false
|
||||||
window?.representedURL = nil
|
window?.representedURL = nil
|
||||||
@@ -979,7 +980,7 @@ final class PlayerModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
needsVideoFit = false
|
needsVideoFit = false
|
||||||
guard state.has_video, aspect.isFinite, aspect > 0 else {
|
guard state.has_video, aspect.isFinite, aspect > 0 else {
|
||||||
window.aspectRatio = .zero
|
window.resizeIncrements = NSSize(width: 1, height: 1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let screen = (window.screen ?? NSScreen.main)?.visibleFrame ?? window.frame
|
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)
|
let size = NSSize(width: width + sidebarWidth, height: width / aspect)
|
||||||
// ponytail: extreme ratios retain letterboxing; compact controls if exact fitting is needed.
|
// ponytail: extreme ratios retain letterboxing; compact controls if exact fitting is needed.
|
||||||
guard size.width >= window.minSize.width, size.height >= window.minSize.height else {
|
guard size.width >= window.minSize.width, size.height >= window.minSize.height else {
|
||||||
window.aspectRatio = .zero
|
window.resizeIncrements = NSSize(width: 1, height: 1)
|
||||||
return
|
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(
|
let frame = NSRect(
|
||||||
x: min(max(window.frame.midX - size.width / 2, screen.minX), screen.maxX - size.width),
|
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),
|
y: min(max(window.frame.midY - size.height / 2, screen.minY), screen.maxY - size.height),
|
||||||
|
|||||||
Reference in New Issue
Block a user