Skip to content

Commit 9c85de3

Browse files
committed
fix: auto-focus SQL editor on new tab and restore cursor on tab switch
1 parent 5531c75 commit 9c85de3

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

CHANGELOG.md

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

1818
### Fixed
1919

20+
- SQL editor not auto-focused on new tab and cursor missing after tab switch
2021
- SSH profile lost after app restart when iCloud Sync enabled
2122
- MariaDB JSON columns showing as hex dumps instead of JSON text
2223
- MongoDB Atlas TLS certificate verification failure

TablePro/Views/Editor/SQLEditorCoordinator.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ final class SQLEditorCoordinator: TextViewCoordinator {
2626
@ObservationIgnored private var contextMenu: AIEditorContextMenu?
2727
@ObservationIgnored private var inlineSuggestionManager: InlineSuggestionManager?
2828
@ObservationIgnored private var editorSettingsObserver: NSObjectProtocol?
29+
@ObservationIgnored private var windowKeyObserver: NSObjectProtocol?
2930
/// Debounce work item for frame-change notification to avoid
3031
/// triggering syntax highlight viewport recalculation on every keystroke.
3132
@ObservationIgnored private var frameChangeWorkItem: DispatchWorkItem?
@@ -61,6 +62,9 @@ final class SQLEditorCoordinator: TextViewCoordinator {
6162
if let observer = editorSettingsObserver {
6263
NotificationCenter.default.removeObserver(observer)
6364
}
65+
if let observer = windowKeyObserver {
66+
NotificationCenter.default.removeObserver(observer)
67+
}
6468
frameChangeWorkItem?.cancel()
6569
}
6670

@@ -69,6 +73,10 @@ final class SQLEditorCoordinator: TextViewCoordinator {
6973
NotificationCenter.default.removeObserver(observer)
7074
editorSettingsObserver = nil
7175
}
76+
if let observer = windowKeyObserver {
77+
NotificationCenter.default.removeObserver(observer)
78+
windowKeyObserver = nil
79+
}
7280
frameChangeWorkItem?.cancel()
7381
frameChangeWorkItem = nil
7482
}
@@ -89,6 +97,22 @@ final class SQLEditorCoordinator: TextViewCoordinator {
8997
self.installVimModeIfEnabled(controller: controller)
9098
if let textView = controller.textView {
9199
EditorEventRouter.shared.register(self, textView: textView)
100+
101+
// Auto-focus: make the editor first responder, then ensure a
102+
// cursor exists. Order matters — setCursorPositions calls
103+
// updateSelectionViews which guards on isFirstResponder.
104+
if let window = textView.window {
105+
window.makeFirstResponder(textView)
106+
}
107+
if controller.cursorPositions.isEmpty {
108+
controller.setCursorPositions([CursorPosition(range: NSRange(location: 0, length: 0))])
109+
}
110+
111+
// Recreate cursor views when the window regains key status.
112+
// resignKeyWindow() on the text view calls removeCursors() which
113+
// destroys cursor subviews, but becomeKeyWindow() only resets the
114+
// blink timer without recreating them.
115+
self.installWindowKeyObserver(for: textView.window)
92116
}
93117
}
94118
}
@@ -280,6 +304,24 @@ final class SQLEditorCoordinator: TextViewCoordinator {
280304
}
281305
}
282306

307+
// MARK: - Window Key Observer
308+
309+
/// Observe when the editor's window regains key status (e.g. tab switch) and
310+
/// recreate cursor views that were destroyed by resignKeyWindow → removeCursors.
311+
private func installWindowKeyObserver(for window: NSWindow?) {
312+
guard let window else { return }
313+
windowKeyObserver = NotificationCenter.default.addObserver(
314+
forName: NSWindow.didBecomeKeyNotification,
315+
object: window,
316+
queue: .main
317+
) { [weak self, weak controller] _ in
318+
guard let self, let controller, !controller.cursorPositions.isEmpty else { return }
319+
// At this point becomeKeyWindow → becomeFirstResponder has already run,
320+
// so isFirstResponder is true and setCursorPositions will create cursor views.
321+
controller.setCursorPositions(controller.cursorPositions)
322+
}
323+
}
324+
283325
// MARK: - Horizontal Scrolling Fix
284326

285327
/// Enable horizontal scrolling when word wrap is off.

0 commit comments

Comments
 (0)