Skip to content

[render] lay out content for the visible size on macOS, instead of under legacy scroll bars - #113

Merged
honghaoz merged 9 commits into
masterfrom
render/layout-beside-legacy-scroll-bars
Oct 3, 2026
Merged

honghaoz merged 9 commits into
masterfrom
render/layout-beside-legacy-scroll-bars

Conversation

@honghaoz

@honghaoz honghaoz commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • On macOS, a legacy scroll bar takes space from the scroll view: AppKit shrinks the clip view by the bar's thickness. Legacy bars show when a mouse is connected, or when "Show scroll bars" is set to "Always". ComposeView still laid out its content for its full bounds, so the bar covered the last 17 pt of the content, and content as wide as the view could scroll sideways under it.
  • ComposeView now lays out its content for its size minus the space the scroll bars take, which is visibleSize, as AppKit apps do. Render handlers and renderable updates get that area as the render bounds. With overlay scroll bars and on UIKit, the render size equals the bounds size, so nothing changes there.

What changed

  • Render size (macOS): renderBounds() returns the content offset with visibleSize. A render pass made for an earlier size, because it was held or waited behind another view's pass, renders for that size minus the current scroll bar space, and a follow-up pass renders the new size (renderSize(for:)).
  • Scroll bar decision (layout(_:), formerly inline in render(_:)): with .auto, a pass that isn't a scroll decides the scroll bars from a layout for the view's full size. If a legacy bar then takes space, the content lays out again for the smaller size, and a bar also shows for any axis the content now overflows. A scroll keeps the bars and lays out once, from the cached layout. onWillLayout runs before each layout at a new size, so it can run more than once in a pass.
  • Re-tiling (macOS): in a window, AppKit re-tiles without laying the view out when the scroller style changes, for example when a mouse is connected, or when the app shows or hides a scroll bar. ComposeView overrides tile() to ask for a layout when that changes the visible size it rendered for.
  • ContentUpdateContext: stores the view's bounds, the content offset with the full size, instead of the render bounds, since the render size depends on the scroll bars the pass decides.
  • render(_:): its locals are now renderSize and renderBounds, and it re-reads the offset after the will-render handler from contentOffset.
  • CHANGELOG: a breaking-change entry for the new layout area, the render bounds and onWillLayout. The entry from [scroll] lock ComposeView's magnification, border and automatic content insets on macOS #109 no longer says the content always lays out for its bounds.
  • Tests:
    • ComposeView_LegacyScrollBarsTests (new, macOS): the layout area with a vertical, a horizontal, or both legacy bars, a bar that makes the content overflow the other axis adding the second bar, content that overflows the full size but fits the smaller one keeping its bar, overlay bars laying out once, scrolling keeping the bars, resizing deciding them again, .always and .manual, and in a window: scroller style changes both ways, a manual bar toggle, and no extra layout for a style change that doesn't change the visible size, a resize, or a refresh that shows a bar.
    • ComposeView_RenderHandlerTests: with automatic scroll indicators that don't take space, onWillLayout runs once per pass, on macOS and iOS.
    • ComposeView_RenderOverrideTests: a held pass renders for its earlier size minus the scroll bar.
    • Tests that encoded the full-bounds layout under legacy bars now expect the visible size (render bounds, renderable updates, animation behavior, parent resize, update context). ComposeView_ScrollIndicatorBehaviorTests' sub-pixel overflow test pins overlay bars, since it depended on the system setting.
    • Mutation checks: removing the re-tile layout request, either of its conditions, or the laidOutSize check fails a test, and earlier checks did the same for the scroll bar decision and the scroll rule.

Review fixes

  • Flash order: newly shown scroll indicators flash after the content size is set, as on master, so the flash shows the new range.
  • Held passes: a pass prepared at a size smaller than the space the scroll bars take renders at zero width, instead of a negative one.
  • What onWillLayout can change: the handler can adjust things like the content offset, but not the view's size, its visible size or its scroll settings, as the doc now says. Changing scrollBehavior, scrollIndicatorBehavior or clippingBehavior asserts and keeps the current values. A change that resizes the visible area, such as showing a legacy scroll bar or switching the scroller style, asserts, and the pass puts back the scroll bars and the scroller style, keeping the offset. Before, a handler that picked a legacy scroll bar or the scroller style from the container size made the view render forever.
  • Screen scale: each layout reads contentScaleFactor after its onWillLayout call, as on master, so a handler that changes the scale gets a layout at the new scale.
  • Re-rendering on view size changes: the view records its size from each render pass, and one check, used by the bounds-change path, the check after each pass and the tile() override, compares it along with the render bounds. A resize that leaves the visible size the same, for example together with a scroller style switch, now renders again, and the automatic scroll bar decision no longer mistakes it for a scroll.
  • tile() is final (macOS): a subclass that resized the clip view after super.tile() left the content laid out for the old visible size. The CHANGELOG entry for this PR mentions it.
  • Viewport reported to onWillLayout: every call reports the current offset with the size it lays out for, so a later call reflects an offset a handler set in an earlier one, and a held update reports where the view scrolled to while it was held.
  • Switching to .auto: a scroll after an app switches scrollIndicatorBehavior to .auto now decides the scroll indicators.
  • Scroll position (macOS): the automatic decision can hide a legacy bar and show it again in one pass, and AppKit clamped the offset in between, against the old content size. Each scroll bar change now keeps the offset, and the pass clamps it once, after the new content size is set, against the final content and visible area. layout(_:) returns whether that clamp is needed, along with the render size. The pass clamps only when the scroll bars end different from how they started, so an offset set outside the scrollable range survives a refresh that doesn't change them.
  • autohidesScrollers stays false (macOS): AppKit hiding a legacy bar on its own changes the size the content lays out for, which could make the two alternate forever. Setting it asserts and keeps it off, like the settings [scroll] lock ComposeView's magnification, border and automatic content insets on macOS #109 locked, and the CHANGELOG entry for [scroll] lock ComposeView's magnification, border and automatic content insets on macOS #109 lists it.
  • Scroll elasticity (macOS): a pass schedules the elasticity update only when the content size or the render size changed, so scrolls skip it, saving about 1 µs per scroll frame.
  • Docs: onWillLayout can run before up to three layouts, and can't change the scroll settings. ScrollBehavior.auto compares the content with the visible size. Both automatic behaviors note that legacy scroll bars take space on macOS, so a scroll indicator also shows for content that overflows only the space the other bar leaves.
  • Tests: each fix has a test that fails without it: the flash order, a handler changing the scroll settings on the first or a later layout, a handler showing a legacy scroll bar or switching the scroller style from the container size, scroll indicators that take no space, a handler changing the scale, a resize and a did-render resize with a scroller style switch that keep the visible size, a scroll after switching to .auto, the zero-width held pass with the document at the origin, the scroll position after an unchanged refresh, with the last row or column fully rendered, and after a refresh that hides a bar, in both directions, an offset outside the scrollable range kept across an unchanged refresh, a handler's offset, the current offset in later and held will-layout calls, clamping for shorter content and for hidden bars, the autohidesScrollers lock, and the elasticity updates.

Decisions

  • The scroll bars are decided from the full size, which showing a bar doesn't change. Deciding from the smaller size could flip back and forth: a bar makes the content fit, which hides the bar, which makes the content overflow again. The cost is a rare case: content that keeps its aspect ratio can overflow the full size but fit once a legacy bar takes its space, and that bar stays with nothing to scroll.
  • The bar space is read from visibleSize, AppKit's own tiling, instead of computed from the scroller thickness. AppKit can draw a legacy bar inside the content insets without shrinking the clip view. Computing it would let a pass decide the bars before applying them, without the offset undo and clamp, but it needs a rule for how insets and scroll bars share space, so that refactor is planned with #108.
  • onWillLayout can't change the scroll settings or the visible size. Applying a change in the same pass took a retry and guards, and each fix exposed another case: a second change in a later callback, or indicator values set along with .manual. No caller needs these changes in the layout callback, so refusing them removes the whole class. The visible size is checked by its effect instead of a list of properties, so the check covers the scroll bars, the scroller style and anything else AppKit tiles, and never fires where a change takes no space, such as scroll indicators on iOS. The pass puts back the scroll bars and the scroller style. Content insets aren't put back, since [scroll] Make ComposeView's scrolling and fitting content account for content insets #108 defines how they share space with the scroll bars.
  • tile() is final, instead of watching the clip view's size. Watching the clip view would have covered a subclass's tiling without an API change, but the content lays out for the visible size tile() sets, so ComposeView keeps the tiling to itself, like the scroll view settings it locks.
  • lastRenderBounds still records the render bounds, not the full bounds. A scroller style change changes the render size without changing the bounds, and the public previousRenderBounds is compared with the current render bounds.
  • No in-layout guard in the tile() override. AppKit ignores a layout request made during layout(): it reads back false, and no extra layout follows. So the override only skips re-tiles during the view's own render pass, which renders for the size they leave.
  • autohidesScrollers is locked instead of modeled. AppKit's auto-hiding loops with .manual indicators too, so only keeping it off covers every behavior.
  • The kept offset is clamped after the content size is set. Clamping during the layout used the old content size and could undo an offset a will-layout handler set. It's clamped only when the scroll bars end different from how they started. Otherwise the visible area hasn't changed, AppKit clamps for a content size change itself, and a clamp would move an offset set outside the scrollable range.
  • onWillLayout reports the current offset in every call, not the one the update was made with. This also changes what a held update's first call reports when the view scrolled while it was held: the current offset instead of the earlier one, as the RenderType doc describes, and where the pass renders.

Not in this PR

Test plan

  • Full macOS suite: 1,450 tests, 0 failures, with the system scroll bar setting on "Always". Tests that depend on the style pin it.
  • Full iOS suite: 1,314 tests, 0 failures.
  • Coverage: every new line runs under the tests. The only uncovered regions in ComposeView.swift are existing assertion messages.
  • make format and make lint.
  • CI on all four platforms. tvOS and visionOS aren't installed locally.

One early local full macOS run had a single failing test that I couldn't identify, because I had filtered its output to the summary line. Every full run since then has passed.

Fixes #111

Summary by CodeRabbit

  • Bug Fixes
    • Content now lays out and renders within the visible area when macOS legacy scroll bars take up space.
    • Layout and scroll indicators update when the available area changes, including when scroll bars appear or disappear and when the view is resized.
    • Scroll position is preserved when possible and adjusted if the available content area shrinks.
    • Layout callbacks may run more than once during a render pass when legacy scroll bars change the available area.
    • Changes to scroll settings during layout are rejected and reverted.
    • Automatic hiding of scroll bars remains unsupported on macOS.
  • Documentation
    • Updated the macOS ComposeView notes to clarify legacy scroll bar and layout behavior.

@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: ff4c313b-9daf-4555-91c5-8c3cea9e6c90
📥 Commits

Reviewing files that changed from the base of the PR and between e0eeabb and 446a3dc.

📒 Files selected for processing (3)
  • ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift
  • ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+LegacyScrollBarsTests.swift
  • ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+RenderHandlerTests.swift

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

ComposeView now accounts for visible space taken by legacy macOS scroll bars. Layout may repeat, update contexts retain view bounds, and rendering uses computed visible bounds. Tests cover indicators, offsets, resizing, and deferred passes.

Changes

Legacy Scroll-Bar Layout

Layer / File(s) Summary
Bounds-aware layout and indicators
ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift, ComposeUI/Sources/ComposeUI/ComposeView/ComposeView+ContentUpdateContext.swift, CHANGELOG.md, AGENTS.md, ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+LegacyScrollBarsTests.swift, ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+ScrollIndicatorBehaviorTests.swift, ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+RenderHandlerTests.swift, ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+ScrollBehaviorTests.swift, ComposeUI/Tests/ComposeUITests/ComposeView/ComposeViewTests.swift
ContentUpdateContext stores view bounds. Layout calculates the available render size and may repeat after legacy scrollers reduce that size. Indicator changes preserve or clamp offsets. Enabling autohidesScrollers asserts and leaves the property false.
Computed render bounds and callbacks
ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift
Render handlers, renderable update contexts, and last-render state use computed render bounds and the current content offset.
Layout, scroller, and offset tests
ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+LegacyScrollBarsTests.swift, ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+RenderOverrideTests.swift, ComposeUI/Tests/ComposeUITests/ComposeNodes/ComposeViewNode+ParentResizeTests.swift, ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+ScrollIndicatorBehaviorTests.swift, ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+RenderHandlerTests.swift, ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+ScrollBehaviorTests.swift, ComposeUI/Tests/ComposeUITests/ComposeView/ComposeViewTests.swift
Tests cover scroller sizing and visibility, offsets, handler constraints, resizing, and held render passes.
Visible bounds and render expectations
ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+RenderBoundsTests.swift, ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+RenderableTests.swift, ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+AnimationBehaviorTests.swift, ComposeUI/Tests/ComposeUITests/ComposeView/ComposeView+ContentUpdateContextTests.swift
Tests expect render bounds and renderable contexts to use the visible area, including after scrolling, resizing, and scroller changes.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant ComposeView
  participant ContentLayout
  participant AppKitScrollView
  ComposeView->>ContentLayout: Layout at the current container size
  ContentLayout-->>ComposeView: Return content size and overflow
  ComposeView->>AppKitScrollView: Update indicators
  AppKitScrollView-->>ComposeView: Report visible size after legacy scrollers
  ComposeView->>ContentLayout: Relayout when scrollers reduce available space
  ComposeView->>AppKitScrollView: Apply content size and offset
Loading

Merge Risk: ⚪ Minimal · up to 446a3

Legacy scroll bars now reduce the macOS content area while overlay scroll bars retain the full area. No demonstrated blocker remains before merge.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 446a3

The change remains within UI layout and rendering, with no identified increase in privileges or crossing of a new trust boundary. The main residual risk is client compatibility with changed viewport geometry and repeated layout callbacks.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The evidenced propagation is through local ComposeView layout handlers, render handlers and renderable updates. Their viewport inputs change, but the inspected producer-consumer path does not add an identity transition or authority-bearing capability. Effects in external application callbacks remain unverified.

Trust Boundaries and Controls

  • observed — The render entrypoint asserts main-thread use, refuses self-reentrant rendering, and defers work when a pass cannot start. On normal completion it clears the update context and animation decision and restores the prior rendering view. These are lifecycle controls, not new authorization controls.

Resilience and Maintainability Implications

  • observed — Indicator changes preserve the original offset across intermediate AppKit clamping. Any required clamp is applied after final content sizing, and callbacks are followed by an offset reread. Held-pass tests inspect recovery through a stale prepared pass followed by a current-size pass; they were not executed during this review.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.13% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 92 functions across 13 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR meets [#111]. On macOS, .auto decides bars from a full-size layout, then lays out for visibleSize when legacy bars take space. The reduced layout does not change the initial bar decision, a…
Out of Scope Changes check ✅ Passed No unrelated change is demonstrated. Re-tiling, offset preservation and clamping, held-pass sizing, scroll-setting restrictions, and disabling auto-hiding support correct layout with space-taking bars…
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: macOS content now lays out within the visible area instead of beneath legacy scroll bars.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.47%. Comparing base (caebf13) to head (446a3dc).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #113      +/-   ##
==========================================
+ Coverage   96.41%   96.47%   +0.05%     
==========================================
  Files         114      114              
  Lines        7039     7141     +102     
==========================================
+ Hits         6787     6889     +102     
  Misses        252      252              
Flag Coverage Δ
ComposeUI 96.47% <100.00%> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ComposeView/ComposeView+ContentUpdateContext.swift 100.00% <100.00%> (ø)
...UI/Sources/ComposeUI/ComposeView/ComposeView.swift 98.53% <100.00%> (+0.20%) ⬆️

Impacted file tree graph

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@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: ca56ab0408

ℹ️ 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".

Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift
Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift Outdated
Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift Outdated
Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift Outdated
…ender sizes at zero, and apply scroll indicator behavior changes in the same pass
…idesScrollers off, and stop the automatic scroll indicator update when a handler changes the behavior

@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: 5e5255ccb8

ℹ️ 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".

Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift Outdated
Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift
…ument the automatic scroll behaviors against the visible size

Also adds the AGENTS.md lesson to refuse an invalid use where it enters, instead of correcting for it downstream.
…the last row and the document origin in the legacy scroll bar tests

@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: 137c55cac9

ℹ️ 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".

Comment thread CHANGELOG.md Outdated
Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift Outdated
Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift
…eport the current offset to every onWillLayout call

@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: 9dfe0e33cb

ℹ️ 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".

Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift
Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift Outdated
Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift

@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: e0eeabbc3f

ℹ️ 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".

Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift Outdated
Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift
Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift
…ze, read the scale after it, and re-render when the view's size changes

@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: 446a3dccfd

ℹ️ 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".

Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift
Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift
Comment thread ComposeUI/Sources/ComposeUI/ComposeView/ComposeView.swift
@honghaoz
honghaoz merged commit b28cd97 into master Oct 3, 2026
6 checks passed
@honghaoz
honghaoz deleted the render/layout-beside-legacy-scroll-bars branch October 3, 2026 02:55
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.

[render] Lay out ComposeView's content beside legacy scroll bars on macOS

1 participant