Skip to content

fix(editor): keep SQL editor focus after dismissing autocomplete with Escape (#1845)#1848

Merged
datlechin merged 1 commit into
mainfrom
fix/1845-editor-escape-focus
Jul 10, 2026
Merged

fix(editor): keep SQL editor focus after dismissing autocomplete with Escape (#1845)#1848
datlechin merged 1 commit into
mainfrom
fix/1845-editor-escape-focus

Conversation

@datlechin

Copy link
Copy Markdown
Member

Problem

Fixes #1845. In the SQL editor, pressing Escape to dismiss the autocomplete popup also drops keyboard focus, so the caret disappears and you cannot keep typing without clicking back into the editor.

Root cause

Bare Escape is registered as a global SwiftUI menu key equivalent for "Clear Selection" (a data grid action). A menu key equivalent preempts the key window's local event monitors, so the completion popup's own Escape handler (which would close the popup and keep focus) never runs. With Vim off, the "Clear Selection" action falls through to NSApp.sendAction(#selector(NSResponder.cancelOperation(_:)), to: nil, from: nil), a target-agnostic broadcast that drops the editor's first responder, and nothing re-asserts it. This is the same class as the existing "Window Close (Cmd+W)" invariant, and it is why handleVimEscapeFromMenu already existed.

Fix

Extend the existing EditorEventRouter menu-escape routing so the menu Escape defers to the focused editor before falling back to the grid. When the editor is focused, the menu now consumes Escape (dismissing the popup if open) and skips the broadcast, with an explicit makeFirstResponder and cursor rebuild as a backstop. Focus stays in the editor, matching native NSTextView completion behavior and every peer editor (VS Code, Xcode, JetBrains, Postico, Sequel Ace, Sublime).

Grid-focused Escape is unchanged: it still clears the grid selection.

Changes

  • New public isShowingCompletions / dismissCompletions() on the vendored TextViewController, with a per-controller identity check so one tab cannot dismiss another's popup.
  • SQLEditorCoordinator.handleEscapeFromMenu() dismisses the popup, routes to Vim, and reclaims first responder and the caret when the editor was focused.
  • EditorEventRouter.handleVimEscapeFromMenu() renamed to handleEscapeFromMenu(); the "Clear Selection" call site updated.
  • Fixed a latent focus leak where handleShowCompletions returned the unconsumed event when closing a visible popup (reachable via Ctrl+Space).
  • Replaced Vim's hand-rolled child-window scan with the new dismissCompletions() API.

Tests

  • Package: TextViewControllerSuggestionsTests covers isShowingCompletions identity, and dismissCompletions() return value and popup close, against the real SuggestionController.
  • App: SQLEditorCoordinatorEscapeMenuTests covers handleEscapeFromMenu() returning false when no editor is focused, so the grid keeps Escape.

The full end-to-end flow (type, popup shows, Esc, keep typing) needs accessibility identifiers on the editor and the vendored popup and races the completion debounce, so it is not covered by a UI test yet. Manual check: open a query tab, type a keyword, press Esc, keep typing. The caret stays and characters land.

Notes

App and vendored-package code only. No PluginKit ABI change.

@mintlify

mintlify Bot commented Jul 10, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
TablePro 🟢 Ready View Preview Jul 10, 2026, 1:04 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@datlechin datlechin merged commit 2f2f815 into main Jul 10, 2026
3 checks passed
@datlechin datlechin deleted the fix/1845-editor-escape-focus branch July 10, 2026 01:06

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f400932c1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

reclaimFirstResponder()
}

return wasFocused || vimHandled

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return consumed only for current editor focus

When the editor focus cache is stale, this returns true solely because wasEditorFocused was previously true, so the Clear Selection menu skips the cancelOperation fallback even if focus has already moved to the data grid. wasEditorFocused is updated later via the window update observer, so a quick click from the editor into a selected grid followed by Escape can be swallowed here and even reclaim editor focus instead of clearing the grid selection, contradicting the intended grid-focused behavior.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Current SQL editor is unusable.

1 participant