From 5d52eafb88c4f2c6af001586d41f73a9c90ee5b3 Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Thu, 25 Jun 2026 14:22:50 +0700 Subject: [PATCH 1/2] fix(editor): arm new-tab focus claim before the editor view loads, add focus logging (#1765) --- TablePro/Views/Editor/SQLEditorCoordinator.swift | 13 ++++++++++--- TablePro/Views/Editor/SQLEditorView.swift | 8 +++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/TablePro/Views/Editor/SQLEditorCoordinator.swift b/TablePro/Views/Editor/SQLEditorCoordinator.swift index e48062ad1..d588f33cf 100644 --- a/TablePro/Views/Editor/SQLEditorCoordinator.swift +++ b/TablePro/Views/Editor/SQLEditorCoordinator.swift @@ -54,6 +54,7 @@ final class SQLEditorCoordinator: TextViewCoordinator, TextViewDelegate { func scheduleEditorFocusClaim() { focusClaimPending = true + Self.logger.debug("Editor focus claim armed") } /// Vim mode for UI observation @@ -118,12 +119,18 @@ final class SQLEditorCoordinator: TextViewCoordinator, TextViewDelegate { EditorEventRouter.shared.register(self, textView: textView) if !self.isDestroyed, let window = textView.window { - if self.focusClaimPending { + let claimPending = self.focusClaimPending + let responderName = window.firstResponder.map { String(describing: type(of: $0)) } ?? "nil" + var made = false + if claimPending { self.focusClaimPending = false - window.makeFirstResponder(textView) + made = window.makeFirstResponder(textView) } else if window.firstResponder == nil || window.firstResponder === window { - window.makeFirstResponder(textView) + made = window.makeFirstResponder(textView) } + Self.logger.debug("Editor focus claim: pending=\(claimPending) isKey=\(window.isKeyWindow) responderBefore=\(responderName, privacy: .public) made=\(made)") + } else { + Self.logger.debug("Editor focus claim skipped: hasWindow=\(textView.window != nil) destroyed=\(self.isDestroyed) pending=\(self.focusClaimPending)") } if controller.cursorPositions.isEmpty { controller.setCursorPositions([CursorPosition(range: NSRange(location: 0, length: 0))]) diff --git a/TablePro/Views/Editor/SQLEditorView.swift b/TablePro/Views/Editor/SQLEditorView.swift index e32e21d31..35686f293 100644 --- a/TablePro/Views/Editor/SQLEditorView.swift +++ b/TablePro/Views/Editor/SQLEditorView.swift @@ -50,6 +50,9 @@ struct SQLEditorView: View { coordinator.databaseType = databaseType coordinator.tabID = tabID coordinator.connectionId = connectionId + if claimFocusOnAppear { + coordinator.scheduleEditorFocusClaim() + } return SourceEditor( $text, @@ -60,11 +63,6 @@ struct SQLEditorView: View { completionDelegate: completionAdapter ) .accessibilityLabel(String(localized: "SQL query editor")) - .onAppear { - if claimFocusOnAppear { - coordinator.scheduleEditorFocusClaim() - } - } .onChange(of: editorState.cursorPositions) { _, newValue in guard let positions = newValue else { return } // Skip cursor propagation when the editor doesn't have focus From 6d6d3caa9905e043c07fb9dd128242e2814423cb Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Thu, 25 Jun 2026 15:11:03 +0700 Subject: [PATCH 2/2] refactor(editor): drop redundant focus-claim armed log (#1765) --- TablePro/Views/Editor/SQLEditorCoordinator.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/TablePro/Views/Editor/SQLEditorCoordinator.swift b/TablePro/Views/Editor/SQLEditorCoordinator.swift index d588f33cf..3032d156a 100644 --- a/TablePro/Views/Editor/SQLEditorCoordinator.swift +++ b/TablePro/Views/Editor/SQLEditorCoordinator.swift @@ -54,7 +54,6 @@ final class SQLEditorCoordinator: TextViewCoordinator, TextViewDelegate { func scheduleEditorFocusClaim() { focusClaimPending = true - Self.logger.debug("Editor focus claim armed") } /// Vim mode for UI observation