refactor: AppKit-native window/toolbar management for main editor#768
Open
refactor: AppKit-native window/toolbar management for main editor#768
Conversation
- Bug 004: NSUserActivity becomeCurrent() was skipped on type-flip (viewConnection ↔ viewTable), silently dropping Handoff mid-session. Drop the becomeCurrent: Bool parameter; both call sites already guard on key-window so always promote the activity. - Bug 005: onWindowBecameKey closure captured @binding tables as a frozen value at onAppear time (an empty array, since schema load is async). Read tables fresh from DatabaseManager.session each invocation. - Bug 001: WindowTabGroupingTests still referenced removed APIs (pendingPayloads, acknowledgePayload, consumeOldestPendingConnectionId, WindowOpener.tabbingIdentifier). Drop the obsolete tests; keep the tabbingIdentifier coverage on WindowManager.
…f replacing current tab
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
WindowGroup(id: "main", for: EditorTabPayload.self)scene with an imperativeNSWindowController(TabWindowController+WindowManager) for the main database editor window. Eliminates phantomContentView.init(5–7× per tab open), removes the 200–7000 ms close grace period, and reduces per-focuswindowDidBecomeKeyfan-out from 10–14 handlers to 1..toolbar { ... }modifier with AppKitNSToolbar(MainWindowToolbar) so toolbar items render inside theNSHostingView-hosted content; eliminates theCannot use Scene methods for URL, NSUserActivity...console warnings.NSUserActivity(Handoff forviewConnection/viewTable) from the old SwiftUI.userActivity(...)modifier (which silently no-op'd inNSHostingView) intoTabWindowController.Architecture
TabWindowController.swiftNSWindowController+NSWindowDelegateper editor window. Owns the toolbar, theNSUserActivity, and lifecycle hooks (windowDidBecomeKey/Resign/Close).WindowManager.swiftopenTab(payload:)creates the controller, eagerly createsSessionState(so the toolbar can render on first paint without a flash), retains the controller until the window closes.MainWindowToolbar.swiftNSToolbar+NSToolbarDelegatehosting the SwiftUI toolbar items (Connection,Database,Refresh+Save,Principal,Quick Switcher,+ New Tab,Filters,Preview SQL,Inspector) viaNSHostingController.CommandActionsRegistry.swift@Observablesingleton fallback for@FocusedValue(\\.commandActions)when SwiftUI's focus chain doesn't reachMainContentView(e.g. after clicking a toolbar Button whoseNSHostingControllerclaims scene focus).MainContentCoordinator+WindowLifecycle.swiftToolbar Layout (Apple HIG / Mail / Notes / Music)
.toggleSidebar+sidebarTrackingSeparator(auto-positioned by AppKit).centeredItemIdentifiers, which collapses trailing flex per WWDC 2023 session 10054).allowedItemIdentifiersand accessible via menus + keyboard shortcuts.Bug Fixes Bundled
window.toolbarafter SwiftUI/NavigationSplitViewmid-merge stomp; if the re-claim drops key state, re-key.CommandActionsRegistryfallback published fromwindowDidBecomeKeyANDconfigureWindow(the latter covers the first window after welcome→connect, wherecoordinator.contentWindowisn't set when AppKit's first becomeKey fires).isConnected+hasPendingChanges+isReadOnlywhere applicable).Phase 5 Cleanup
AppDelegate.windowDidBecomeKeytabbing block (47 lines) —WindowManager.openTabnow performs the merge with correct ordering at creation time. Source of the prior 200–7000 ms grace-period delays.WindowOpener.shared.openNativeTab(...)→WindowManager.shared.openTab(payload: ...).WindowOpenershrunk from 90 → 49 lines (kept only theOpenWindowActionbridge for SwiftUI scenes: Welcome / Connection Form / Settings).WindowLifecycleMonitorandWindowAccessorretained — both work correctly as standalone components and migrating their APIs intoWindowManageris large scope for marginal cleanup gain.Test Plan
Window lifecycle
+button on toolbar → opens new tab, Cmd+T/1...9 still work+button on tab bar (next to "Query N") → same as aboveToolbar
Focus + menu state
@FocusedValueregressions in Edit menu (Undo/Redo, Copy/Paste)Handoff (NSUserActivity)
viewTable↔viewConnection)Cannot use Scene methods for URL, NSUserActivity...warningsBuild
xcodebuild -project TablePro.xcodeproj -scheme TablePro -configuration Debug build -skipPackagePluginValidation— greenswiftlint lint --strict— 0 violations