Skip to content

feat(gpui): port container_query and sticky-axis div scrolling - #5

Merged
freefcw merged 2 commits into
develop/0.9from
cursor/gpui-container-query-scroll-lock-0066
Aug 29, 2026
Merged

feat(gpui): port container_query and sticky-axis div scrolling#5
freefcw merged 2 commits into
develop/0.9from
cursor/gpui-container-query-scroll-lock-0066

Conversation

@freefcw

@freefcw freefcw commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Selective GPUI ports from Zed. Not a wholesale sync.

Rebased onto develop/0.9 at b767199db831b04e78ebd9f8f75c18b4cd8da491 after PR #4 merged (Taffy 0.12.2 → 0.13 + grid_cols_max_content test). Conflict in crates/gpui/src/elements/div.rs tests at the end of the module: #4 appended grid_cols_max_content_sizes_columns_to_their_content after the shadow_sm test; this PR appended restrict_scroll_to_axis tests after the same test. Kept both.

container_query

Adds container_query(|size, window, cx| { … }). The element’s size comes from its style plus the parent offer; the closure then builds children from that measured size. Defaults to filling the parent (size_full()), overridable via Styled. Contents cannot influence the container.

  • New module: crates/gpui/src/elements/container_query.rs
  • Exported from elements/mod.rs and therefore the adabraka-gpui facade (same as div / list)
  • Holy Grail grid_layout example now chooses stacked vs three-column layout from the measured width
  • Tests record the measured size after wide, narrow, and explicitly styled layouts

Commit: 5c58b4e95dbe0c0fdfc2ff85d88fcb750750f6da
Zed-Origin: 49ad06c1b4047b018b1622e1cf94cafcacd39247 (merge of zed#60774)

Axis-locked div scrolling

Ports editor-quality start-axis stick onto the existing restrict_scroll_to_axis / allow_concurrent_scroll machinery. Precise (trackpad) gestures lock to the axis they start on and only unlock when the opposite axis is strong enough (1.9× and at least 6px).

Existing flag semantics are preserved:

  • Callers who already set style.restrict_scroll_to_axis = Some(true) still get no axis remapping
  • allow_concurrent_scroll still picks a dominant axis when both deltas are non-zero
  • Line-based mouse-wheel remapping is unchanged unless the flag is set

Also adds a fluent restrict_scroll_to_axis() builder next to overflow_*_scroll. Local TouchPhase has no PartialEq / Cancelled, so gesture end is matched with matches!(…, Ended).

Commit: 5dac1407b64be5fbe353e31ec1e92bca91b7e73e
Zed-Origin: 79cc17c216cf62d5deec7b3eed986d0f652d1c9a (merge of zed#61797)

Skipped upstream hunks

  • Zed gestures.rs / PlatformGestures / scheduler::Instant — this tree has no gesture arena; OngoingScroll lives next to ScrollDelta in interactive.rs and uses std::time::Instant
  • TouchPhase::Cancelled — local TouchPhase is Started | Moved | Ended only
  • Editor / markdown / agent_ui / search / data_table callers — those crates are not in this repo
  • gpui_platform::application in Zed’s grid example — kept Application::new()

Verification

  • cargo test --locked -p adabraka-gpui-core --lib --features test-support: 227 passed
  • cargo check --locked -p adabraka-gpui --example grid_layout: ok
  • cargo fmt --all -- --check: ok
  • cargo clippy --locked -p adabraka-gpui-core --lib --tests -- -D warnings: ok
Open in Web Open in Cursor 

Sourcery 摘要

为 GPUI 添加响应式容器查询和支持手势感知的轴锁定滚动。

新功能:

  • 添加公开的 container_query 元素,该元素根据元素的测量尺寸构建其内容,并支持响应式布局。
  • 为 div 元素添加流畅的轴向限制滚动:将精确手势锁定到其起始时的主导轴,同时保留现有的滚动行为。

增强功能:

  • 在添加基于手势的轴锁定和解锁行为的同时,保留现有的滚动轴和并发滚动语义。

测试:

  • 添加对容器查询响应式重建和显式尺寸的测试覆盖。
  • 添加对持续滚动轴锁定、手势重置、超时处理以及 div 滚动兼容性的测试覆盖。
Original summary in English

Sourcery 摘要

为 GPUI 滚动功能添加响应式容器查询和手势感知的轴锁定。

新功能:

  • 添加公开的 container_query 元素,该元素会根据测量到的容器大小重建其内容,并支持显式设置尺寸。
  • 为 fluent div 添加轴向限制滚动功能,并支持手势感知的锁定和解锁,以实现精准的滚动输入。

增强功能:

  • 在添加基于手势的轴锁定的同时,保留现有的滚动轴重映射、并发滚动和行滚轮行为。

测试:

  • 增加对响应式容器查询重建、显式尺寸、手势轴锁定、解锁阈值、手势重置、超时以及现有滚动语义的测试覆盖。
Original summary in English

Sourcery 总结

为 GPUI 添加响应式容器查询,以及支持手势感知的轴锁定滚动功能。

新功能:

  • 添加公开的 container_query 元素,根据测量到的尺寸构建响应式内容。
  • 为 div 元素添加流畅的轴向限制滚动,包括支持手势感知的轴锁定与解锁,以实现精准的滚动输入。

增强功能:

  • 在支持手势轴锁定的同时,保留现有的滚动轴重映射、并发滚动选择和鼠标滚轮行为。

测试:

  • 添加对容器查询调整大小和显式尺寸的测试覆盖。
  • 添加对滚动轴锁定、手势解锁、重置、超时,以及与现有滚动语义兼容性的测试覆盖。
Original summary in English

Sourcery 摘要

为 GPUI 添加响应式容器查询,以及支持手势感知的轴锁定滚动。

新功能:

  • 添加公共容器查询元素,根据其测量尺寸构建响应式内容。
  • 为 div 元素添加流式轴向限制滚动,并支持手势感知的轴锁定与解锁。

增强:

  • 在支持精确手势轴锁定的同时,保留现有的滚动轴重映射、并发滚动和鼠标滚轮行为。

测试:

  • 添加对响应式容器查询尺寸和布局变化的覆盖。
  • 添加对手势轴锁定、解锁、重置、超时以及与现有滚动语义兼容性的覆盖。
Original summary in English

Sourcery 总结

为 GPUI 添加响应式容器查询,以及支持手势感知的轴锁定滚动。

新功能:

  • 添加公开的容器查询元素,根据测量到的尺寸构建响应式内容。
  • 为 div 元素添加流畅的轴向限制滚动,并支持手势感知的轴锁定与解锁。

增强功能:

  • 在扩展精确手势处理的同时,保留现有的滚动轴重映射、并发滚动选择和鼠标滚轮行为。

测试:

  • 添加对容器查询调整大小和显式尺寸的覆盖测试。
  • 添加对手势轴锁定、解锁、重置、超时,以及与现有滚动语义兼容性的覆盖测试。
Original summary in English

Sourcery 摘要

为 GPUI 滚动功能添加响应式容器查询和手势感知的轴锁定。

新功能:

  • 添加公开的容器查询元素,根据测量到的尺寸构建响应式内容。
  • 为 div 元素添加流畅的轴向限制滚动,并支持手势感知的锁定与解锁。

增强功能:

  • 在支持精确手势轴锁定的同时,保留现有的滚动轴重映射、并发滚动和鼠标滚轮行为。

测试:

  • 增加对响应式容器尺寸和布局变化的覆盖测试。
  • 增加对手势轴锁定、解锁、重置、超时以及与现有滚动语义兼容性的覆盖测试。
Original summary in English

Summary by Sourcery

Add responsive container queries and gesture-aware axis locking to GPUI scrolling.

New Features:

  • Add a public container query element that builds responsive content from its measured size.
  • Add fluent axis-restricted scrolling for div elements with gesture-aware locking and unlocking.

Enhancements:

  • Preserve existing scroll-axis remapping, concurrent scrolling, and mouse-wheel behavior while supporting precise gesture axis locking.

Tests:

  • Add coverage for responsive container sizing and layout changes.
  • Add coverage for gesture axis locking, unlocking, reset, timeout, and compatibility with existing scrolling semantics.

@sourcery-ai

sourcery-ai Bot commented Aug 29, 2026

Copy link
Copy Markdown

审查者指南

将响应式容器查询和手势感知的轴锁定滚动移植到 GPUI 中,包括公共 API、响应式布局示例、有状态的精确滚动过滤、保持兼容性的行为,以及针对性的测试覆盖。

容器查询测量与渲染的时序图

sequenceDiagram
    participant Parent as Parent layout
    participant CQ as ContainerQuery
    participant Window
    participant Builder as Render callback
    participant Child as Child element

    Parent->>CQ: request_layout()
    CQ->>Window: request_layout(style)
    Window-->>CQ: measured bounds
    CQ->>Builder: render(bounds.size, window, cx)
    Builder-->>CQ: child element
    CQ->>Child: layout_as_root(bounds.size)
    CQ->>Child: prepaint_at(bounds.origin)
    CQ->>Child: paint()
Loading

手势感知的轴锁定 div 滚动时序图

sequenceDiagram
    actor User
    participant Div as Scrollable div
    participant Ongoing as OngoingScroll
    participant Offset as Scroll offset

    User->>Div: ScrollWheelEvent precise delta
    Div->>Ongoing: filter(delta, touch_phase)
    Ongoing-->>Div: delta filtered to dominant axis
    Div->>Div: apply allow_concurrent_scroll and overflow rules
    Div->>Offset: update scroll position
    User->>Div: Perpendicular delta
    Div->>Ongoing: filter(delta, Moved)
    Ongoing-->>Div: unlock when ratio >= 1.9 and delta >= 6px
    Div->>Offset: apply unlocked delta
Loading

响应式容器布局选择流程图

flowchart TD
    A[Window resize or layout pass] --> B[container_query measures assigned size]
    B --> C{Width below 400px?}
    C -->|Yes| D[Build stacked flex-column layout]
    C -->|No| E[Build three-column grid layout]
    D --> F[Render child contents at measured size]
    E --> F
Loading

文件级变更

变更 详细信息 文件
添加一个公共容器查询元素,在构造并绘制其子元素之前测量自身经过样式设置的布局。
  • 引入带有填充父元素默认值和 Styled 覆盖项的 container_query
  • 根据样式执行初始布局,并在测量得到的边界内布局由回调生成的子元素。
  • 通过 GPUI 元素门面导出该元素。
  • 添加用于测试测量尺寸的调整大小和显式尺寸测试。
crates/gpui/src/elements/container_query.rs
crates/gpui/src/elements/mod.rs
更新 Holy Grail 示例,根据测量得到的容器宽度,在响应式堆叠布局和网格布局之间切换。
  • 在容器查询回调中构建共享的布局块。
  • 宽度小于 400px 时选择单列布局,否则选择三列网格布局。
crates/gpui-compat/examples/grid_layout.rs
在保留现有 div 滚动和轴重映射语义的同时,实现精确手势的轴锁定。
  • 添加 OngoingScroll 状态,支持主导轴锁定、1.9 倍/6px 解锁阈值、手势结束重置,以及基于超时的手势检测。
  • 在已跟踪和未跟踪的滚动器中,将持续滚动状态与滚动偏移量一同存储。
  • 在应用溢出和并发滚动规则之前过滤精确增量;行滚轮行为保持不变。
  • 添加流式的 restrict_scroll_to_axis() 构建器,并记录更新后的样式语义。
  • 添加针对锁定、解锁、超时/重置行为,以及与现有样式标志兼容性的单元测试和集成测试覆盖。
crates/gpui/src/interactive.rs
crates/gpui/src/elements/div.rs
crates/gpui/src/style.rs

提示和命令

与 Sourcery 交互

  • 触发新的审查: 在拉取请求中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 根据审查评论生成 GitHub issue: 回复审查评论,请 Sourcery 根据该评论创建 issue。你也可以使用 @sourcery-ai issue 回复审查评论,以便根据该评论创建 issue。
  • 生成拉取请求标题: 在拉取请求标题的任意位置写入 @sourcery-ai,即可随时生成标题。你也可以在拉取请求中评论 @sourcery-ai title,以便随时生成或重新生成标题。
  • 生成拉取请求摘要: 在拉取请求正文的任意位置写入 @sourcery-ai summary,即可在你指定的位置随时生成 PR 摘要。你也可以在拉取请求中评论 @sourcery-ai summary,以便随时生成或重新生成摘要。
  • 生成审查者指南: 在拉取请求中评论 @sourcery-ai guide,即可随时生成或重新生成审查者指南。
  • 解决所有 Sourcery 评论: 在拉取请求中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,此功能会很有用。
  • 驳回所有 Sourcery 审查: 在拉取请求中评论 @sourcery-ai dismiss,即可驳回所有现有的 Sourcery 审查。如果你想从新的审查开始,这一功能尤其有用——别忘了评论 @sourcery-ai review 以触发新的审查!

自定义使用体验

访问你的控制面板以:

  • 启用或禁用审查功能,例如 Sourcery 生成的拉取请求摘要、审查者指南等。
  • 更改审查语言。
  • 添加、移除或编辑自定义审查说明。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

Ports responsive container queries and gesture-aware axis-locked scrolling into GPUI, including public APIs, a responsive layout example, stateful precise-scroll filtering, compatibility-preserving behavior, and focused test coverage.

Sequence diagram for container query measurement and rendering

sequenceDiagram
    participant Parent as Parent layout
    participant CQ as ContainerQuery
    participant Window
    participant Builder as Render callback
    participant Child as Child element

    Parent->>CQ: request_layout()
    CQ->>Window: request_layout(style)
    Window-->>CQ: measured bounds
    CQ->>Builder: render(bounds.size, window, cx)
    Builder-->>CQ: child element
    CQ->>Child: layout_as_root(bounds.size)
    CQ->>Child: prepaint_at(bounds.origin)
    CQ->>Child: paint()
Loading

Sequence diagram for gesture-aware axis-locked div scrolling

sequenceDiagram
    actor User
    participant Div as Scrollable div
    participant Ongoing as OngoingScroll
    participant Offset as Scroll offset

    User->>Div: ScrollWheelEvent precise delta
    Div->>Ongoing: filter(delta, touch_phase)
    Ongoing-->>Div: delta filtered to dominant axis
    Div->>Div: apply allow_concurrent_scroll and overflow rules
    Div->>Offset: update scroll position
    User->>Div: Perpendicular delta
    Div->>Ongoing: filter(delta, Moved)
    Ongoing-->>Div: unlock when ratio >= 1.9 and delta >= 6px
    Div->>Offset: apply unlocked delta
Loading

Flow diagram for responsive container layout selection

flowchart TD
    A[Window resize or layout pass] --> B[container_query measures assigned size]
    B --> C{Width below 400px?}
    C -->|Yes| D[Build stacked flex-column layout]
    C -->|No| E[Build three-column grid layout]
    D --> F[Render child contents at measured size]
    E --> F
Loading

File-Level Changes

Change Details Files
Adds a public container-query element that measures its own styled layout before constructing and painting its child.
  • Introduces container_query with parent-filling defaults and Styled overrides.
  • Performs an initial layout from style and lays out the callback-generated child at the measured bounds.
  • Exports the element through the GPUI element facade.
  • Adds resize and explicit-size tests for measured dimensions.
crates/gpui/src/elements/container_query.rs
crates/gpui/src/elements/mod.rs
Updates the Holy Grail example to switch between responsive stacked and grid layouts using measured container width.
  • Builds shared layout blocks inside the container-query callback.
  • Selects a single-column layout below 400px and a three-column grid otherwise.
crates/gpui-compat/examples/grid_layout.rs
Implements precise-gesture axis locking while preserving existing div scrolling and axis-remapping semantics.
  • Adds OngoingScroll state with dominant-axis locking, 1.9x/6px unlock thresholds, gesture-end reset, and timeout-based gesture detection.
  • Stores ongoing-scroll state alongside scroll offsets for tracked and untracked scrollers.
  • Filters precise deltas before applying overflow and concurrent-scroll rules; line-wheel behavior remains unchanged.
  • Adds the fluent restrict_scroll_to_axis() builder and documents the updated style semantics.
  • Adds unit and integration coverage for locking, unlocking, timeout/reset behavior, and compatibility with existing style flags.
crates/gpui/src/interactive.rs
crates/gpui/src/elements/div.rs
crates/gpui/src/style.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@cursor
cursor Bot force-pushed the cursor/gpui-container-query-scroll-lock-0066 branch from 625311a to bed0bb6 Compare August 29, 2026 09:38
@freefcw
freefcw marked this pull request as ready for review August 29, 2026 09:38
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 29, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-29T09:41:45.178714Z bed0bb6 Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@cursor
cursor Bot force-pushed the cursor/gpui-container-query-scroll-lock-0066 branch from bed0bb6 to c8c9fd9 Compare August 29, 2026 09:39

@sourcery-ai sourcery-ai 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.

你好——我已经审阅了你的更改,看起来很棒!


Sourcery 对开源项目免费——如果你喜欢我们的审阅,请考虑分享它们 ✨
请帮我变得更有用!请在每条评论上点击 👍 或 👎,我会利用这些反馈来改进你的审阅。
Original comment in English

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@cursor
cursor Bot force-pushed the cursor/gpui-container-query-scroll-lock-0066 branch from c8c9fd9 to 12bbb51 Compare August 29, 2026 12:06
Add a CSS-style container query element whose size comes from its style
and the space offered by its parent. Once that size is known, the
provided closure builds children from the measured size. Defaults to
filling the parent; contents cannot influence the container. Export it
from the public facade and adapt the Holy Grail grid_layout example.

Zed-Origin: 49ad06c1b4047b018b1622e1cf94cafcacd39247

Co-authored-by: freefcw <freefcw@gmail.com>
Port editor-quality sticky-axis scrolling onto the existing
restrict_scroll_to_axis flag. Precise trackpad gestures lock to the
axis they start on and only unlock when the opposite axis is strong
enough. Line-based wheel remapping and allow_concurrent_scroll keep
their previous semantics for callers who already set the style.

Zed-Origin: 79cc17c216cf62d5deec7b3eed986d0f652d1c9a

Co-authored-by: freefcw <freefcw@gmail.com>
@cursor
cursor Bot force-pushed the cursor/gpui-container-query-scroll-lock-0066 branch from 12bbb51 to 5dac140 Compare August 29, 2026 12:53
@freefcw
freefcw merged commit 057e9b1 into develop/0.9 Aug 29, 2026
19 checks passed
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