Repository navigation
Conversation
…direction change Fitted inline render frames can end up a fraction of a pixel shorter than their page. Chromium latches a trackpad swipe to a frame that can scroll even one device pixel, so a reversed swipe moved neither the page nor the thread. Fitted frames now set scrolling="no".
…l-latching # Conflicts: # apps/web/src/components/files/BrowserDocumentFrame.tsx
…l-latching # Conflicts: # apps/web/src/components/files/BrowserDocumentFrame.tsx
|
| Layer / File(s) | Summary |
|---|---|
Fit-aware iframe scrolling apps/web/src/components/files/BrowserDocumentFrame.tsx, apps/web/src/components/chat/HtmlRenderFrame.tsx, apps/web/src/components/guest/GuestHtmlRender.tsx |
The shared document frame disables scrolling when fitted and not fullscreen. Chat and guest renders treat unknown content height or height at or below HTML_RENDER_MAX_FIT_HEIGHT as fitted. Taller content retains unspecified iframe scrolling. |
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Bug fix · Severity of issue fixed: Medium
Suggested reviewers: juliusmarminge, maria-rcks
Merge Risk: 
Moderate · up to e94a5
-
Guest share pages may clip content, either horizontally for wide pages or vertically if the first height report is missed, and the guest view has no way to scroll it back into reach. Address both before merging. The chat view's behavior is unaffected by these issues.
Pre-merge checks: 
4
-
Check name Status Explanation Title check The title names the main change: trackpad swipes over inline HTML renders no longer drop after a direction change. The change adds scrolling="no" to fitted render frames, which the title does not name… Linked Issues check Linked issue #23864is the only direct, active target. Its coding requirement is to stop Chromium from latching macOS trackpad swipes to fitted inline render frames, while keeping scrolling for pages …Out of Scope Changes check The whole-PR diff (merge base c8a601c to head e94a5bc) changes only three files: apps/web/src/components/chat/HtmlRenderFrame.tsx,apps/web/src/components/files/BrowserDocumentFrame.tsx, and `apps…Description check The description includes all required sections. It clearly explains the problem, expected behavior, implementation, scope, linked issue, verification evidence, limitations, and unchecked environments. Full details: Title check
-
Explanation
The title names the main change: trackpad swipes over inline HTML renders no longer drop after a direction change. The change adds scrolling="no" to fitted render frames, which the title does not name. It is a conventional commit title in plain language, and it matches the objectives and the linked issue
#23864.
Full details: Linked Issues check
-
Explanation
Linked issue
#23864is the only direct, active target. Its coding requirement is to stop Chromium from latching macOS trackpad swipes to fitted inline render frames, while keeping scrolling for pages past the fit cap and for content inside the page. The reviewed head implements this in three places:HtmlRenderFrame.tsxpassesfitted={contentHeight === undefined || contentHeight <= HTML_RENDER_MAX_FIT_HEIGHT}toHtmlRenderDocument. A frame with no reported height counts as fitted.BrowserDocumentFrame.tsxHtmlRenderDocumentsetsscrolling={props.fitted && !fullscreen ? "no" : undefined}. Thefullscreenvalue comes fromuseSyncExternalStoreondocument.fullscreenElement === frameRef.current, so a page that takes the screen can still scroll.GuestHtmlRender.tsxsetsscrollingto"no"whencontentHeightis undefined or at mostHTML_RENDER_MAX_FIT_HEIGHT, and leaves it undefined above the cap.
Frames past the cap keep the default scrolling. The issue asks for no automated test, so the lack of one does not fail this check. The macOS recordings, the real-trackpad counts, and the minimal reproduction in the PR description are author reports. I did not re-run them. The code change matches the requirement.
Full details: Out of Scope Changes check
-
Explanation
The whole-PR diff (merge base c8a601c to head e94a5bc) changes only three files:
apps/web/src/components/chat/HtmlRenderFrame.tsx,apps/web/src/components/files/BrowserDocumentFrame.tsx, andapps/web/src/components/guest/GuestHtmlRender.tsx. Every hunk applies the fitted-frame scroll lock or supports it. This covers the newfittedprop, the fullscreen snapshot that restores scrolling, thescrollingattribute, and the guest share view. The guest share view uses the same render path as the issue, and the PR objectives name it. No unrelated changes appear. One effect goes beyond the issue text. Inline pages wider than the column can no longer scroll sideways, because the frame no longer scrolls its viewport. The PR describes this as a deliberate trade-off. It is a direct result of the approach the issue proposes, not an unrelated change. Fullscreen keeps the sideways scroll.
-
Finishing Touches
-
Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
The guest view has no fullscreen, so a fitted frame that cannot scroll would cut off a page wider than the column with no way to reach it.
|
Note Written by Verified in a real dev environmentverified as-is at created the real git project and thread in the web app. real codex
matching main and pr screenshots show the same provider-published document. the short clip shows main followed by the pr; captions are recording annotations, not app controls. uploaded playback and seeking were checked. Not verifiednative macos trackpad input, the exact persistent 0.5px macos frame mismatch, electron shell behavior, windows, ios/android, guest sharing, and remote/relay/tunnel connections were not exercised on this linux vm. the linux reproduction covers the remount/latching path, not a claim about physical macos input. |



Problem
On macOS, trackpad swipes with the pointer over an inline HTML render are often lost right after a direction change, so you have to swipe twice. Some fitted render frames end up 0.5 px shorter than their page. Chromium latches a swipe to any frame that can scroll even one device pixel, so the swipe never reaches the thread. Details and measurements are in #23864.
This replaces #23865, which was closed for missing a recording. The recordings are below.
Change
Inline render frames set
scrolling="no"while they are fitted to their page: before the page first reports its height, and while that height is withinHTML_RENDER_MAX_FIT_HEIGHT. The page can then no longer scroll its own viewport by user input, so Chromium never picks the frame as the swipe's scroll target. Script-driven scrolling, scrollable elements inside the page, and wheel handlers in the page are unaffected.GuestHtmlRender) fits its frame the same way but is left as is. It has no fullscreen, so a page wider than its frame would have no way to scroll sideways. It can get the fix once it has a full-size view.fullscreen) drops the attribute while it is the fullscreen element, so a page taller than the screen can still scroll there. Chromium applies the attribute change to a live frame in both directions.HTML_RENDER_MAX_HEIGHTuntil its page reports, and a taller page could otherwise latch swipes during that time.One behavior changes: a page wider than the chat column can no longer be scrolled sideways inline. It still can in fullscreen (third clip below).
The frame being 0.5 px short is a separate bug, left for its own fix.
Scope and approval
Fixes #23864.
Verification
Recordings
Dev desktop build on macOS, recorded through the DevTools protocol screencast. "This branch" is f38853e; the later commits only change a page that takes the screen and leave the guest view out. The thread is a demo thread with four published pages of made-up data. Two of them are 0.5 px taller than their frame, which is the bug's trigger. The yellow dot, the swipe labels and the result labels are an overlay drawn by the recording script; each result label is the thread's measured scroll change. Swipes are synthesized trackpad-style scroll gestures (
Input.synthesizeScrollGesture) at a fixed point over the render, alternating direction.1. Alternating swipes over a render.
main(c8a601c) first, then this branch.MP4
main2. A page wider than the column.
maininline, this branch inline, then this branch in fullscreen.MP4
main, inlineOther checks
mainand of this fix on a thread of real renders, with scroll events logged from the trackpad. Reversed swipes over a render were lost 19 / 44 times (43%) onmainand 2 / 24 (8%) with the fix. The remaining losses came before the window was in front or overlapped momentum from the previous swipe.sandbox="allow-scripts"iframe holding a 1,500.5 px page: 7 / 10 alternating swipes lost withoutscrolling="no", 0 / 10 with it.vp run check:changedpasses: format, lint, knip, typecheck, the tests beside the changed files, and the React compiler check.There is no automated test. The bug is in Chromium's gesture latching across out-of-process frames, which the web browser tests can't drive, and a test that the attribute is set would only mirror the implementation.
Not checked: Windows, Linux, and mouse wheels.