Ariver
2026-06-28 8fbe7d9123cdb618de5ecf3cd1b0fb81199a2dac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import AppKit
import AlignerCore
 
@MainActor
final class Round0DebugOverlayController {
    static let overlayTitle = "Aligner Round0 Debug Overlay"
    static let settingsTitle = "Aligner Round0 Debug Settings"
 
    private let overlayHost: QuickSwitchOverlayHost
    private var settingsWindow: NSWindow?
 
    init() {
        overlayHost = QuickSwitchOverlayHost(
            title: Self.overlayTitle,
            contentView: Self.makeOverlayView()
        )
    }
 
    func show(includeSettingsChild: Bool) {
        overlayHost.show(context: OverlayContext(entryPoint: .quickSwitch))
 
        if includeSettingsChild {
            attachSettingsChild()
        }
    }
 
    func hide() {
        if let settingsWindow {
            overlayHost.detachChild(settingsWindow)
            settingsWindow.orderOut(nil)
        }
        settingsWindow = nil
        overlayHost.hide(reason: .userClosed)
    }
 
    private func attachSettingsChild() {
        if settingsWindow == nil {
            settingsWindow = Self.makeSettingsWindow()
        }
 
        guard let settingsWindow else { return }
        settingsWindow.center()
        overlayHost.attachChild(settingsWindow)
        settingsWindow.orderFrontRegardless()
    }
 
    private static func makeOverlayView() -> NSView {
        let root = NSVisualEffectView()
        root.material = .hudWindow
        root.blendingMode = .behindWindow
        root.state = .active
        root.translatesAutoresizingMaskIntoConstraints = false
 
        let label = NSTextField(labelWithString: "Round0 Debug Overlay")
        label.font = .systemFont(ofSize: 24, weight: .semibold)
        label.textColor = .white
        label.alignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false
 
        root.addSubview(label)
        NSLayoutConstraint.activate([
            label.centerXAnchor.constraint(equalTo: root.centerXAnchor),
            label.centerYAnchor.constraint(equalTo: root.centerYAnchor)
        ])
 
        return root
    }
 
    private static func makeSettingsWindow() -> NSWindow {
        let window = NSWindow(
            contentRect: NSRect(x: 0, y: 0, width: 360, height: 180),
            styleMask: [.titled, .closable],
            backing: .buffered,
            defer: false
        )
        window.title = settingsTitle
        window.isReleasedWhenClosed = false
 
        let label = NSTextField(wrappingLabelWithString: "Round0 Settings Child Window")
        label.font = .systemFont(ofSize: 17, weight: .semibold)
        label.alignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false
 
        let content = NSView()
        content.addSubview(label)
        NSLayoutConstraint.activate([
            label.centerXAnchor.constraint(equalTo: content.centerXAnchor),
            label.centerYAnchor.constraint(equalTo: content.centerYAnchor),
            label.leadingAnchor.constraint(greaterThanOrEqualTo: content.leadingAnchor, constant: 24),
            label.trailingAnchor.constraint(lessThanOrEqualTo: content.trailingAnchor, constant: -24)
        ])
        window.contentView = content
        return window
    }
}
 
struct Round0DebugLaunchOptions {
    let skipPermissions: Bool
    let showOverlay: Bool
    let showSettingsChild: Bool
    let autoHideAfter: TimeInterval?
    let quitAfter: TimeInterval?
 
    static func parse(arguments: [String]) -> Round0DebugLaunchOptions {
        Round0DebugLaunchOptions(
            skipPermissions: arguments.contains("--round0-skip-permissions"),
            showOverlay: arguments.contains("--round0-debug-overlay"),
            showSettingsChild: arguments.contains("--round0-debug-settings-child"),
            autoHideAfter: timeInterval(for: "--round0-debug-auto-hide-after", in: arguments),
            quitAfter: timeInterval(for: "--round0-debug-quit-after", in: arguments)
        )
    }
 
    private static func timeInterval(for key: String, in arguments: [String]) -> TimeInterval? {
        let prefix = "\(key)="
        guard let argument = arguments.first(where: { $0.hasPrefix(prefix) }) else {
            return nil
        }
 
        return TimeInterval(argument.dropFirst(prefix.count))
    }
}