From 2eea31ded1f334b8b555e4bd0e7c5edde2c47452 Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Sat, 30 May 2026 17:39:59 +0700 Subject: [PATCH] fix(connections): let Tab leave the AI rules text field via the key view loop (#1490) --- CHANGELOG.md | 1 + .../Views/ConnectionForm/Panes/AIRulesPaneView.swift | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8105d916..0bcea99df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Tab and Shift-Tab move focus out of the AI rules text field in the connection form instead of inserting a tab character. (#1490) - Tab moves keyboard focus between the window panes (sidebar, results, inspector) by rebuilding the key view loop when the window appears. (#1490) - The license activation sheet focuses the key field on open, the SQL review sheet closes with Escape even while the editor has focus, and the integration token sheet focuses its Done button. (#1490) - Copy with Headers now has a default keyboard shortcut (Cmd+Option+C), so it works and is discoverable from the keyboard instead of showing in the Edit menu with no key. (#1490) diff --git a/TablePro/Views/ConnectionForm/Panes/AIRulesPaneView.swift b/TablePro/Views/ConnectionForm/Panes/AIRulesPaneView.swift index fc7fe7fb0..f68e00ec5 100644 --- a/TablePro/Views/ConnectionForm/Panes/AIRulesPaneView.swift +++ b/TablePro/Views/ConnectionForm/Panes/AIRulesPaneView.swift @@ -87,5 +87,17 @@ private struct AIRulesEditor: NSViewRepresentable { guard let textView = notification.object as? NSTextView else { return } text.wrappedValue = textView.string } + + func textView(_ textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool { + if commandSelector == #selector(NSResponder.insertTab(_:)) { + textView.window?.selectNextKeyView(nil) + return true + } + if commandSelector == #selector(NSResponder.insertBacktab(_:)) { + textView.window?.selectPreviousKeyView(nil) + return true + } + return false + } } }