Merge origin/main into feat-hidden-titlebar-minimalism-reset

This commit is contained in:
Lawrence Chen 2026-03-18 04:05:43 -07:00
commit 1e908b2b75
No known key found for this signature in database
74 changed files with 19250 additions and 16071 deletions

View file

@ -2069,6 +2069,18 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
private var bonsplitTabDragUITestRecorder: DispatchSourceTimer?
private var gotoSplitUITestObservers: [NSObjectProtocol] = []
private var didSetupMultiWindowNotificationsUITest = false
private var didSetupDisplayResolutionUITestDiagnostics = false
private var displayResolutionUITestObservers: [NSObjectProtocol] = []
private struct UITestRenderDiagnosticsSnapshot {
let panelId: UUID
let drawCount: Int
let presentCount: Int
let lastPresentTime: Double
let windowVisible: Bool
let appIsActive: Bool
let desiredFocus: Bool
let isFirstResponder: Bool
}
var debugCloseMainWindowConfirmationHandler: ((NSWindow) -> Bool)?
// Keep debug-only windows alive when tests intentionally inject key mismatches.
private var debugDetachedContextWindows: [NSWindow] = []
@ -2369,6 +2381,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
if NSApp.windows.isEmpty {
self.openNewMainWindow(nil)
}
self.moveUITestWindowToTargetDisplayIfNeeded()
NSRunningApplication.current.activate(options: [.activateAllWindows, .activateIgnoringOtherApps])
self.writeUITestDiagnosticsIfNeeded(stage: "afterForceWindow")
}
@ -2406,6 +2419,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
let windows = NSApp.windows
let ids = windows.map { $0.identifier?.rawValue ?? "" }.joined(separator: ",")
let vis = windows.map { $0.isVisible ? "1" : "0" }.joined(separator: ",")
let screenIDs = windows.map { $0.screen?.cmuxDisplayID.map(String.init) ?? "" }.joined(separator: ",")
let targetDisplayID = env["CMUX_UI_TEST_TARGET_DISPLAY_ID"] ?? ""
payload["stage"] = stage
payload["pid"] = String(ProcessInfo.processInfo.processIdentifier)
@ -2414,6 +2429,16 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
payload["windowsCount"] = String(windows.count)
payload["windowIdentifiers"] = ids
payload["windowVisibleFlags"] = vis
payload["windowScreenDisplayIDs"] = screenIDs
payload["uiTestTargetDisplayID"] = targetDisplayID
if let rawDisplayID = UInt32(targetDisplayID) {
let screenPresent = NSScreen.screens.contains(where: { $0.cmuxDisplayID == rawDisplayID })
let movedWindow = windows.contains(where: { $0.screen?.cmuxDisplayID == rawDisplayID })
payload["targetDisplayPresent"] = screenPresent ? "1" : "0"
payload["targetDisplayMoveSucceeded"] = movedWindow ? "1" : "0"
}
appendUITestRenderDiagnosticsIfNeeded(&payload, environment: env)
appendUITestSocketDiagnosticsIfNeeded(&payload, environment: env)
guard let data = try? JSONSerialization.data(withJSONObject: payload) else { return }
try? data.write(to: URL(fileURLWithPath: path), options: .atomic)
@ -2426,6 +2451,160 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
}
return object
}
private func appendUITestSocketDiagnosticsIfNeeded(
_ payload: inout [String: String],
environment env: [String: String]
) {
guard env["CMUX_UI_TEST_SOCKET_SANITY"] == "1" else { return }
guard let config = socketListenerConfigurationIfEnabled() else {
payload["socketExpectedPath"] = env["CMUX_SOCKET_PATH"] ?? ""
payload["socketMode"] = "off"
payload["socketReady"] = "0"
payload["socketPingResponse"] = ""
payload["socketIsRunning"] = "0"
payload["socketAcceptLoopAlive"] = "0"
payload["socketPathMatches"] = "0"
payload["socketPathExists"] = "0"
payload["socketFailureSignals"] = "socket_disabled"
return
}
let socketPath = TerminalController.shared.activeSocketPath(preferredPath: config.path)
let health = TerminalController.shared.socketListenerHealth(expectedSocketPath: socketPath)
let pingResponse = health.isHealthy
? TerminalController.probeSocketCommand("ping", at: socketPath, timeout: 1.0)
: nil
let isReady = health.isHealthy && pingResponse == "PONG"
var failureSignals = health.failureSignals
if health.isHealthy && pingResponse != "PONG" {
failureSignals.append("ping_timeout")
}
payload["socketExpectedPath"] = socketPath
payload["socketMode"] = config.mode.rawValue
payload["socketReady"] = isReady ? "1" : "0"
payload["socketPingResponse"] = pingResponse ?? ""
payload["socketIsRunning"] = health.isRunning ? "1" : "0"
payload["socketAcceptLoopAlive"] = health.acceptLoopAlive ? "1" : "0"
payload["socketPathMatches"] = health.socketPathMatches ? "1" : "0"
payload["socketPathExists"] = health.socketPathExists ? "1" : "0"
payload["socketFailureSignals"] = failureSignals.joined(separator: ",")
}
private func appendUITestRenderDiagnosticsIfNeeded(
_ payload: inout [String: String],
environment env: [String: String]
) {
guard env["CMUX_UI_TEST_DISPLAY_RENDER_STATS"] == "1" else { return }
guard let renderState = currentUITestRenderDiagnostics() else {
payload["renderStatsAvailable"] = "0"
payload["renderPanelId"] = ""
payload["renderDrawCount"] = ""
payload["renderPresentCount"] = ""
payload["renderLastPresentTime"] = ""
payload["renderWindowVisible"] = ""
payload["renderAppIsActive"] = ""
payload["renderDesiredFocus"] = ""
payload["renderIsFirstResponder"] = ""
payload["renderDiagnosticsUpdatedAt"] = String(format: "%.6f", ProcessInfo.processInfo.systemUptime)
return
}
payload["renderStatsAvailable"] = "1"
payload["renderPanelId"] = renderState.panelId.uuidString
payload["renderDrawCount"] = String(renderState.drawCount)
payload["renderPresentCount"] = String(renderState.presentCount)
payload["renderLastPresentTime"] = String(format: "%.6f", renderState.lastPresentTime)
payload["renderWindowVisible"] = renderState.windowVisible ? "1" : "0"
payload["renderAppIsActive"] = renderState.appIsActive ? "1" : "0"
payload["renderDesiredFocus"] = renderState.desiredFocus ? "1" : "0"
payload["renderIsFirstResponder"] = renderState.isFirstResponder ? "1" : "0"
payload["renderDiagnosticsUpdatedAt"] = String(format: "%.6f", ProcessInfo.processInfo.systemUptime)
}
private func currentUITestRenderDiagnostics() -> UITestRenderDiagnosticsSnapshot? {
guard let tabManager,
let tabId = tabManager.selectedTabId,
let workspace = tabManager.tabs.first(where: { $0.id == tabId }) else {
return nil
}
let terminalPanel: TerminalPanel? = {
if let focusedPanelId = workspace.focusedPanelId,
let terminalPanel = workspace.terminalPanel(for: focusedPanelId) {
return terminalPanel
}
if let focusedTerminalPanel = workspace.focusedTerminalPanel {
return focusedTerminalPanel
}
return workspace.panels.values.compactMap { $0 as? TerminalPanel }.first
}()
guard let terminalPanel else { return nil }
let stats = terminalPanel.hostedView.debugRenderStats()
return UITestRenderDiagnosticsSnapshot(
panelId: terminalPanel.id,
drawCount: stats.drawCount,
presentCount: stats.presentCount,
lastPresentTime: stats.lastPresentTime,
windowVisible: stats.windowOcclusionVisible,
appIsActive: stats.appIsActive,
desiredFocus: stats.desiredFocus,
isFirstResponder: stats.isFirstResponder
)
}
private func moveUITestWindowToTargetDisplayIfNeeded(attempt: Int = 0) {
let env = ProcessInfo.processInfo.environment
guard let rawDisplayID = env["CMUX_UI_TEST_TARGET_DISPLAY_ID"],
let targetDisplayID = UInt32(rawDisplayID) else {
return
}
guard let screen = NSScreen.screens.first(where: { $0.cmuxDisplayID == targetDisplayID }) else {
if attempt < 20 {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { [weak self] in
self?.moveUITestWindowToTargetDisplayIfNeeded(attempt: attempt + 1)
}
}
self.writeUITestDiagnosticsIfNeeded(stage: "targetDisplayMissing")
return
}
guard let window = NSApp.windows.first else {
if attempt < 20 {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { [weak self] in
self?.moveUITestWindowToTargetDisplayIfNeeded(attempt: attempt + 1)
}
}
self.writeUITestDiagnosticsIfNeeded(stage: "targetDisplayNoWindow")
return
}
let visibleFrame = screen.visibleFrame
let width = min(window.frame.width, max(visibleFrame.width - 80, 480))
let height = min(window.frame.height, max(visibleFrame.height - 80, 360))
let frame = NSRect(
x: visibleFrame.midX - (width / 2),
y: visibleFrame.midY - (height / 2),
width: width,
height: height
).integral
window.setFrame(frame, display: true, animate: false)
window.makeKeyAndOrderFront(nil)
window.orderFrontRegardless()
if window.screen?.cmuxDisplayID != targetDisplayID, attempt < 20 {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { [weak self] in
self?.moveUITestWindowToTargetDisplayIfNeeded(attempt: attempt + 1)
}
return
}
self.writeUITestDiagnosticsIfNeeded(stage: "afterMoveToTargetDisplay")
}
#endif
func applicationDidBecomeActive(_ notification: Notification) {
@ -2493,6 +2672,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
setupGotoSplitUITestIfNeeded()
setupBonsplitTabDragUITestIfNeeded()
setupMultiWindowNotificationsUITestIfNeeded()
setupDisplayResolutionUITestDiagnosticsIfNeeded()
// UI tests sometimes don't run SwiftUI `.onAppear` soon enough (or at all) on the VM.
// The automation socket is a core testing primitive, so ensure it's started here when
@ -2509,11 +2689,71 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
socketPath: SocketControlSettings.socketPath(),
accessMode: mode
)
scheduleUITestSocketSanityCheckIfNeeded()
}
}
#endif
}
#if DEBUG
private func scheduleUITestSocketSanityCheckIfNeeded() {
let env = ProcessInfo.processInfo.environment
guard env["CMUX_UI_TEST_SOCKET_SANITY"] == "1" else { return }
DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) { [weak self] in
guard let self else { return }
guard let config = self.socketListenerConfigurationIfEnabled() else {
self.writeUITestDiagnosticsIfNeeded(stage: "socketSanityDisabled")
return
}
let expectedPath = TerminalController.shared.activeSocketPath(preferredPath: config.path)
let health = TerminalController.shared.socketListenerHealth(expectedSocketPath: expectedPath)
let pingResponse = health.isHealthy
? TerminalController.probeSocketCommand("ping", at: expectedPath, timeout: 1.0)
: nil
let isReady = health.isHealthy && pingResponse == "PONG"
if isReady {
self.writeUITestDiagnosticsIfNeeded(stage: "socketSanityReady")
return
}
self.writeUITestDiagnosticsIfNeeded(stage: "socketSanityRestart")
self.restartSocketListenerIfEnabled(source: "uiTest.socketSanity")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) { [weak self] in
self?.writeUITestDiagnosticsIfNeeded(stage: "socketSanityPostRestart")
}
}
}
private func setupDisplayResolutionUITestDiagnosticsIfNeeded() {
let env = ProcessInfo.processInfo.environment
guard env["CMUX_UI_TEST_DISPLAY_RENDER_STATS"] == "1" else { return }
guard !didSetupDisplayResolutionUITestDiagnostics else { return }
didSetupDisplayResolutionUITestDiagnostics = true
let center = NotificationCenter.default
let observe: (Notification.Name, String) -> Void = { [weak self] name, stage in
guard let self else { return }
let observer = center.addObserver(forName: name, object: nil, queue: .main) { [weak self] _ in
Task { @MainActor [weak self] in
self?.writeUITestDiagnosticsIfNeeded(stage: stage)
}
}
self.displayResolutionUITestObservers.append(observer)
}
observe(NSWindow.didResizeNotification, "displayUITest.windowDidResize")
observe(NSWindow.didMoveNotification, "displayUITest.windowDidMove")
observe(NSWindow.didChangeScreenNotification, "displayUITest.windowDidChangeScreen")
observe(NSWindow.didChangeBackingPropertiesNotification, "displayUITest.windowDidChangeBacking")
observe(.terminalSurfaceDidBecomeReady, "displayUITest.terminalSurfaceDidBecomeReady")
observe(.terminalPortalVisibilityDidChange, "displayUITest.terminalPortalVisibilityDidChange")
writeUITestDiagnosticsIfNeeded(stage: "displayUITest.setup")
}
#endif
private func prepareStartupSessionSnapshotIfNeeded() {
guard !didPrepareStartupSessionSnapshot else { return }
didPrepareStartupSessionSnapshot = true