Skip to content

Commit b00da7b

Browse files
committed
fix(windows): persist welcome, connection form, and feedback window positions across launches
1 parent a7ec25a commit b00da7b

6 files changed

Lines changed: 23 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4444

4545
### Fixed
4646

47+
- Welcome window, connection form, and feedback panel now remember their position and size across launches. Previously these always reopened centered on screen because `setFrameAutosaveName` was never set on the underlying `NSWindow`/`NSPanel`. They now use the same native AppKit frame autosave mechanism the main editor and Settings windows already used.
4748
- MCP: GET `/mcp` now opens a real SSE notification stream. Previously the GET path was routed through the request dispatcher, which had no handler for it, so the connection was closed immediately and `notifications/progress` events were dropped.
4849
- MCP: concurrent tool calls no longer serialize at the dispatcher loop. Each exchange is dispatched in its own child task while session-state guards still serialize per-session work.
4950
- MCP: server validates the `protocolVersion` requested in `initialize` against a supported set and rejects unknown versions with `-32600 invalid_request` instead of silently echoing back whatever the client sent.

TablePro/Core/Services/Infrastructure/ConnectionFormWindowFactory.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import SwiftUI
99
@MainActor
1010
internal enum ConnectionFormWindowFactory {
1111
private static let baseIdentifier = "connection-form"
12+
private static let autosaveName: NSWindow.FrameAutosaveName = "ConnectionFormWindow"
1213

1314
internal static func openOrFront(connectionId: UUID? = nil) {
1415
if let existing = existingWindow(for: connectionId) {
@@ -53,8 +54,8 @@ internal enum ConnectionFormWindowFactory {
5354
window.standardWindowButton(.zoomButton)?.isEnabled = false
5455
window.styleMask.remove(.miniaturizable)
5556
window.collectionBehavior.insert(.fullScreenNone)
56-
window.center()
5757
window.isReleasedWhenClosed = false
58+
window.applyAutosaveName(autosaveName)
5859
return window
5960
}
6061
}

TablePro/Core/Services/Infrastructure/TabWindowController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ internal final class TabWindowController: NSWindowController, NSWindowDelegate {
7474
window.identifier = NSUserInterfaceItemIdentifier("main")
7575
window.minSize = NSSize(width: 720, height: 480)
7676
window.isRestorable = false
77-
window.setFrameAutosaveName("MainEditorWindow")
77+
window.applyAutosaveName("MainEditorWindow")
7878
window.toolbarStyle = .unified
7979
// Hide the window title ("Query 1 / TablePro") embedded in the unified
8080
// toolbar — otherwise it claims leading space and pushes our navigation

TablePro/Core/Services/Infrastructure/WelcomeWindowFactory.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import SwiftUI
99
@MainActor
1010
internal enum WelcomeWindowFactory {
1111
private static let identifier = NSUserInterfaceItemIdentifier("welcome")
12+
private static let autosaveName: NSWindow.FrameAutosaveName = "WelcomeWindow"
1213
private static let contentSize = NSSize(width: 700, height: 450)
1314

1415
internal static func openOrFront() {
@@ -48,8 +49,8 @@ internal enum WelcomeWindowFactory {
4849
window.standardWindowButton(.zoomButton)?.isHidden = true
4950
window.collectionBehavior.insert(.fullScreenNone)
5051
window.setContentSize(contentSize)
51-
window.center()
5252
window.isReleasedWhenClosed = false
53+
window.applyAutosaveName(autosaveName)
5354
return window
5455
}
5556
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// NSWindow+FrameAutosave.swift
3+
// TablePro
4+
//
5+
6+
import AppKit
7+
8+
extension NSWindow {
9+
func applyAutosaveName(_ name: NSWindow.FrameAutosaveName) {
10+
setFrameAutosaveName(name)
11+
if !setFrameUsingName(name) {
12+
center()
13+
}
14+
}
15+
}

TablePro/Views/Feedback/FeedbackWindowController.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import SwiftUI
99
@MainActor
1010
final class FeedbackWindowController {
1111
static let shared = FeedbackWindowController()
12+
private static let autosaveName: NSWindow.FrameAutosaveName = "FeedbackWindow"
1213
private var panel: NSPanel?
1314
private var closeObserver: NSObjectProtocol?
1415
private let viewModel = FeedbackViewModel()
@@ -42,7 +43,7 @@ final class FeedbackWindowController {
4243
panel.standardWindowButton(.miniaturizeButton)?.isHidden = true
4344
panel.standardWindowButton(.zoomButton)?.isHidden = true
4445
panel.contentView = hostingView
45-
panel.center()
46+
panel.applyAutosaveName(Self.autosaveName)
4647
panel.makeKeyAndOrderFront(nil)
4748
self.panel = panel
4849

0 commit comments

Comments
 (0)