Skip to content

fix(editor): restore the source editor and the tab strip run on macOS 13 - #2920

Merged
datlechin merged 2 commits into
mainfrom
fix/macos-13-editor-and-tab-strip
Sep 16, 2026
Merged

datlechin merged 2 commits into
mainfrom
fix/macos-13-editor-and-tab-strip

Conversation

@datlechin

Copy link
Copy Markdown
Member

Follow-up to #2874, from a tester running real macOS 13.7.8. Two defects, one of them mine.

The source editor rendered nothing

The SQL editor and the result JSON tab's Text mode were both an empty rectangle: no text, no gutter, no line numbers, no cursor. Tree mode rendered, because it never touches this controller.

#2874 replaced super.loadView() with view = NSView() to stop macOS 13 raising over a nib the controller does not have. Those are not the same view. Measured with a standalone AppKit probe over a nib-less NSViewController:

super.loadView() NSView()
frame 500 x 500 0 x 0
autoresizingMask [.width, .height] none

translatesAutoresizingMaskIntoConstraints is true on both, so the empty mask is the load-bearing half: the view can only be resized by something writing its frame, and nothing does. Everything below it is pinned to it by autolayout, so the find controller's view, the scroll view, the text view's width (scrollView.contentSize minus the clip insets) and the gutter's height (taken from the text view's frame) collapse together. PlainControllerView.make() builds what AppKit builds. macOS 14 keeps super.loadView().

Why no machine here could show it: NSView.clipsToBounds "Defaults to NO on macOS 14 and later. Defaults to YES on previous releases" (NSView.h), marked API_AVAILABLE(macos(10.9)), so the availability checker cannot see it. TableProTextEngine hand-frames every view and none of them set the property, so on 14 a wrong frame still draws and on 13 it is erased. TextView and LineFragmentView now set clipsToBounds = false, which is a no-op on 14 and states the contract the renderer was already written against. Every other view in the package already sets it explicitly.

The tab strip measured a run for tabs it did not know about

EditorTabInteractionView.layout() builds the run from interaction.tabIds, and tabIds was written only by the strip's own view modifiers. #2874 had to split onChange(of:initial:true), which is macOS 14, into onAppear plus a plain onChange, which moved the only initial seed to after the first layout pass. The band is installed hidden, so there is no appearance to wait for either.

A run built for fewer tabs than the strip draws gives the ones it knows an equal share of the whole track and leaves the rest with no placement, and item(for:at:in:placement:label:) draws nothing without one. The list and the overflow style now arrive from the model, in configure, where commands already does; the two onChange modifiers carry changes only. track also reads the run and the list once and hands each item its placement, instead of re-reading interaction.run inside a ForEach closure SwiftUI evaluates lazily, so one paint is measured against one run.

This one is not confirmed as what the tester saw. Tabs sharing the track equally with centred titles is the shipped geometry on every macOS, pinned by EditorTabStripLayoutTests, so the screenshot may be correct behaviour. The ordering defect is real either way.

Verification

Universal Debug build at minos 13.0, all 18 bundled plugins universal, sent to the tester. EditorTabStripInteractionTests, EditorTabRunLayoutTests and EditorTabStripLayoutTests pass, with two new cases covering the seed. No CHANGELOG entry: macOS 13 support is still unreleased, so this folds into the entry it already has.

The remaining macOS 13 question needs the tester, not the code: whether the titlebar accessory is inset past the sidebar. EditorTabStripAccessoryController claims it is, and NSTitlebarAccessoryViewController.h does not say so.

@datlechin
datlechin merged commit e6eef37 into main Sep 16, 2026
8 checks passed
@datlechin
datlechin deleted the fix/macos-13-editor-and-tab-strip branch September 16, 2026 09:08
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.

1 participant