Skip to content

fix(editor): make result pinning reachable from the result tabs (#1982) - #1988

Merged
datlechin merged 2 commits into
mainfrom
fix/1982-result-pin-reachable
Jul 29, 2026
Merged

fix(editor): make result pinning reachable from the result tabs (#1982)#1988
datlechin merged 2 commits into
mainfrom
fix/1982-result-pin-reachable

Conversation

@datlechin

Copy link
Copy Markdown
Member

Fixes #1982.

Root cause

The pin feature was not broken. The right-click never reached it.

EditorEventRouter installed one process-global .rightMouseDown monitor and decided which view owned the click with textView.bounds.contains(point). TextView is the document view of a scroll view, sized to the whole query, so bounds covered everything below the visible editor. Any query taller than the editor pane made the editor claim right-clicks on the result tab strip, the data grid, and the status bar, and return nil swallowed the event so the result tab's own menu never ran.

The reporter's screenshots show exactly this: right-clicking near the result tabs opens the SQL editor's menu. The same bug also took out the data grid's row menu and Clear Results in query tabs.

Two more problems sat behind it. The pin glyph only appeared after a result was pinned, so there was nothing to discover. And canPinActiveResultSet and showsResultTabBar were separate predicates that disagreed in JSON view, in Structure view, and during Explain, where View > Pin Result stayed enabled with no tab on screen.

What changed

Right-click routing. The monitor is gone. TextView.menu(for:) now prefers a menu assigned to the view and keeps its editing default when there is none, SQLEditorCoordinator assigns the AI menu to the text view, and the gutter forwards to the editor. AppKit decides ownership, which is what NSView.menu(for:) is for.

A visible pin. Each result tab carries a pin control on the trailing edge with close moved to the leading edge, matching Xcode's documented tab controls. It shows on the tab you are on and when you point at a tab, and stays visible once pinned. Both controls sit in fixed 12x12 slots so a tab never changes width. VoiceOver gets a named action for each, since a control revealed by pointing is not reachable any other way. Pinned results move to the front of the strip, which is where the next run puts them anyway.

One rule for pinning. ResultTabBarPolicy is now the single source of truth for the View menu, the tab menu, and whether the strip renders, with canPin defined in terms of showsTabBar so a pinnable result always has a tab on screen. Result tabs also render in JSON view, so a multi-statement run is switchable there.

Testing

  • ResultTabBarPolicyTests covers the gating matrix, including the invariant that pinning is never offered without a strip.
  • ResultPinningTests gains coverage for pin ordering, the active result surviving a pin, and parity between the View menu and the strip.
  • EditorContextMenuRoutingTests covers menu resolution: an assigned menu wins, and a text view without one keeps the standard editing items.
  • ResultTabPinUITests runs the reported flow end to end against the sample database, with a query padded past the editor height, and asserts the result tab's own menu opens.

The change was reviewed in two adversarial passes. The first caught a hard compile error in the pin toggle and two regressions in the vendored text view, including one that stripped the editing menu from the JSON, DDL, and trigger editors. The second caught a replacement test that could not fail, which was removed rather than kept.

I could not build or lint this. swiftlint is not installed on the machine that produced the change and xcode-select points at Command Line Tools, so there is no xcodebuild. Line lengths and the SwiftLint opt-in rules were checked by hand and the writing-style gate passes, but CI is the first real build.

Notes for review

  • Two files under LocalPackages/ change. Both are small and both keep existing behaviour: the text view gains an assigned-menu path ahead of its default, and the gutter forwards its menu to the editor so right-clicking line numbers still answers.
  • TableProMobile.xcodeproj uses explicit file references and does not pick up the new ResultTabBarPolicy.swift. It already omits QueryTabState.swift while referencing MainContentCoordinator+SidebarActions.swift, so it looked stale before this change and was left alone.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@datlechin
datlechin merged commit 3c9d597 into main Jul 29, 2026
3 checks passed
@mintlify

mintlify Bot commented Jul 29, 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 29, 2026, 2:30 AM

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

@datlechin
datlechin deleted the fix/1982-result-pin-reachable branch July 29, 2026 02:30
@mintlify

mintlify Bot commented Jul 29, 2026

Copy link
Copy Markdown

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

Project Status Preview Updated (UTC)
TablePro 🟡 Building Jul 29, 2026, 2:29 AM

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

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.

Pin the output window

1 participant