Skip to content

Commit 95570fb

Browse files
committed
fix: infer connection for macOS native tab bar "+" button (#576)
When the user clicks the macOS native tab bar "+" (not the app toolbar button), SwiftUI creates a new window with payload=nil. This caused the new window to have no connection context, triggering tab restoration from disk which clears session.tables across all windows. Infer the connectionId from the key window via WindowLifecycleMonitor and create a proper new-tab payload so the new tab inherits the correct connection.
1 parent 905aff8 commit 95570fb

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

TablePro/ContentView.swift

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,24 @@ struct ContentView: View {
3636
private let storage = ConnectionStorage.shared
3737

3838
init(payload: EditorTabPayload?) {
39-
self.payload = payload
39+
// When payload is nil (macOS native tab bar "+" button), infer
40+
// the connectionId from the key window so the new tab inherits
41+
// the correct connection instead of showing an empty state.
42+
var effectivePayload = payload
43+
if effectivePayload == nil, let keyWindow = NSApp.keyWindow,
44+
let connectionId = WindowLifecycleMonitor.shared.connectionIdFromWindow(keyWindow) {
45+
effectivePayload = EditorTabPayload(
46+
connectionId: connectionId,
47+
tabType: .query,
48+
isNewTab: true
49+
)
50+
}
51+
self.payload = effectivePayload
52+
4053
let defaultTitle: String
41-
if let tableName = payload?.tableName {
54+
if let tableName = effectivePayload?.tableName {
4255
defaultTitle = tableName
43-
} else if let connectionId = payload?.connectionId,
56+
} else if let connectionId = effectivePayload?.connectionId,
4457
let connection = DatabaseManager.shared.activeSessions[connectionId]?.connection {
4558
let langName = PluginManager.shared.queryLanguageName(for: connection.type)
4659
defaultTitle = "\(langName) Query"
@@ -52,15 +65,15 @@ struct ContentView: View {
5265
// For Cmd+T (new tab), the session already exists. Resolve synchronously
5366
// to avoid the "Connecting..." flash while waiting for async onChange.
5467
var resolvedSession: ConnectionSession?
55-
if let connectionId = payload?.connectionId {
68+
if let connectionId = effectivePayload?.connectionId {
5669
resolvedSession = DatabaseManager.shared.activeSessions[connectionId]
5770
}
5871
_currentSession = State(initialValue: resolvedSession)
5972

6073
if let session = resolvedSession {
6174
_rightPanelState = State(initialValue: RightPanelState())
6275
_sessionState = State(initialValue: SessionStateFactory.create(
63-
connection: session.connection, payload: payload
76+
connection: session.connection, payload: effectivePayload
6477
))
6578
} else {
6679
_rightPanelState = State(initialValue: nil)

TablePro/Core/Services/Infrastructure/WindowLifecycleMonitor.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ internal final class WindowLifecycleMonitor {
119119
return entries[windowId]?.connectionId
120120
}
121121

122+
/// Look up the connectionId for a given NSWindow by matching its reference.
123+
internal func connectionIdFromWindow(_ window: NSWindow) -> UUID? {
124+
purgeStaleEntries()
125+
return entries.values.first { $0.window === window }?.connectionId
126+
}
127+
122128
/// Check if any windows are registered for a connection.
123129
internal func hasWindows(for connectionId: UUID) -> Bool {
124130
purgeStaleEntries()

0 commit comments

Comments
 (0)