feat: animate the start-screen URL field
Use a scoped 250 ms fade and top-anchored scale transition with animated recent-row reflow. Respect Reduce Motion, preserve the fixed window size, and exercise native focus, draft retention and rapid reversals.
This commit is contained in:
@@ -37,6 +37,8 @@ private enum WindowDragCheck {
|
||||
static var implementations: [(Method, IMP)] = []
|
||||
static var target: NSWindow?
|
||||
static var dragDepth = 0
|
||||
static var urlWindowFrame = NSRect.zero
|
||||
static let urlDraft = "https://www.youtube.com/watch?v=aqz-KE-bpKQ"
|
||||
static let names = ["video", "title", "playback padding", "play button", "volume slider",
|
||||
"start whitespace", "start button", "start artwork", "URL text field",
|
||||
"queue whitespace", "queue footer", "queue row", "queue button",
|
||||
@@ -76,6 +78,17 @@ private enum WindowDragCheck {
|
||||
return nil
|
||||
}
|
||||
|
||||
static func clickStartURL(in window: NSWindow) {
|
||||
for type in [NSEvent.EventType.leftMouseDown, .leftMouseUp] {
|
||||
let event = NSEvent.mouseEvent(with: type, location: NSPoint(x: 400, y: 272),
|
||||
modifierFlags: [], timestamp: ProcessInfo.processInfo.systemUptime,
|
||||
windowNumber: window.windowNumber, context: nil,
|
||||
eventNumber: probe * 100 + phase * 2 + (type == .leftMouseDown ? 0 : 1),
|
||||
clickCount: 1, pressure: type == .leftMouseDown ? 1 : 0)!
|
||||
NSApp.postEvent(NSEvent(cgEvent: event.cgEvent!)!, atStart: false)
|
||||
}
|
||||
}
|
||||
|
||||
static func point(in window: NSWindow) -> NSPoint? {
|
||||
let content = window.contentView!
|
||||
let w = content.bounds.width
|
||||
@@ -150,11 +163,13 @@ private enum WindowDragCheck {
|
||||
model.setVolume(0)
|
||||
model.setPlayback(playing: false)
|
||||
window.makeKeyAndOrderFront(nil)
|
||||
window.makeMain()
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
}
|
||||
if phase == 0 {
|
||||
guard NSApp.isActive, window.isKeyWindow else {
|
||||
guard NSApp.isActive, window.isKeyWindow, window.isMainWindow else {
|
||||
window.makeKeyAndOrderFront(nil)
|
||||
window.makeMain()
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
return
|
||||
}
|
||||
@@ -162,13 +177,8 @@ private enum WindowDragCheck {
|
||||
switch probe {
|
||||
case 5: model.closeFile()
|
||||
case 8:
|
||||
for type in [NSEvent.EventType.leftMouseDown, .leftMouseUp] {
|
||||
let event = NSEvent.mouseEvent(with: type, location: NSPoint(x: 400, y: 272),
|
||||
modifierFlags: [], timestamp: ProcessInfo.processInfo.systemUptime,
|
||||
windowNumber: window.windowNumber, context: nil, eventNumber: type == .leftMouseDown ? 1 : 2,
|
||||
clickCount: 1, pressure: type == .leftMouseDown ? 1 : 0)!
|
||||
NSApp.postEvent(NSEvent(cgEvent: event.cgEvent!)!, atStart: false)
|
||||
}
|
||||
urlWindowFrame = window.frame
|
||||
clickStartURL(in: window)
|
||||
case 9:
|
||||
model.open(fixtures.appendingPathComponent("cache.mp4"))
|
||||
model.showsQueue = true
|
||||
@@ -205,10 +215,37 @@ private enum WindowDragCheck {
|
||||
guard drags - previousDrags == expected else {
|
||||
finish("\(names[probe]): expected \(expected) native drag requests, got \(drags - previousDrags)"); return
|
||||
}
|
||||
if probe == 8 {
|
||||
guard let editor = window.firstResponder as? NSTextView, editor.isFieldEditor else {
|
||||
finish("Revealing the URL field did not focus its editor"); return
|
||||
}
|
||||
editor.insertText(urlDraft, replacementRange: NSRange(location: NSNotFound, length: 0))
|
||||
clickStartURL(in: window)
|
||||
phase = 7
|
||||
return
|
||||
}
|
||||
probe += 1
|
||||
if probe == names.count { finish(); return }
|
||||
phase = 0
|
||||
return
|
||||
} else if probe == 8 && phase == 7 {
|
||||
guard (window.firstResponder as? NSTextView)?.isFieldEditor != true else {
|
||||
finish("Collapsing the URL field retained keyboard focus"); return
|
||||
}
|
||||
clickStartURL(in: window) // Reverse the collapse before its animation completes.
|
||||
} else if probe == 8 && phase == 8 {
|
||||
guard let editor = window.firstResponder as? NSTextView, editor.isFieldEditor else { return }
|
||||
guard editor.string == urlDraft else { finish("Reopening the URL field lost its draft"); return }
|
||||
clickStartURL(in: window)
|
||||
} else if probe == 8 && phase == 9 {
|
||||
guard nativeView(in: window.contentView!, matching: { ($0 as? NSTextField)?.isEditable == true }) == nil else { return }
|
||||
guard (window.firstResponder as? NSTextView)?.isFieldEditor != true,
|
||||
window.frame == urlWindowFrame, drags == previousDrags else {
|
||||
finish("URL-field transitions retained focus, resized or dragged the start window"); return
|
||||
}
|
||||
probe += 1
|
||||
phase = 0
|
||||
return
|
||||
}
|
||||
phase += 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user