Skip to content

list: measure an existing row when the configured item is absent - #2975

Merged
huacnlee merged 4 commits into
longbridge:mainfrom
grishy:sg-list-measurement-fallback
Sep 6, 2026
Merged

list: measure an existing row when the configured item is absent#2975
huacnlee merged 4 commits into
longbridge:mainfrom
grishy:sg-list-measurement-fallback

Conversation

@grishy

@grishy grishy commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

List measures one row to determine the height of its items. When the configured row is missing, it measures an empty element at zero height. A remaining row can then overlap the section footer.

The measurement row is chosen in this order:

  1. Use the configured index if both its section and row exist.
  2. Otherwise, use the first row in the first non-empty section.
  3. If all sections are empty, skip item measurement.

The fallback is only used for the current measurement. It does not overwrite item_to_measure_index, which is the caller's setting. For example, if row 5 is configured but filtering leaves only two rows, the list measures row 0 without changing the setting to 0. Once row 5 is a valid index again, the list measures it. This preserves the configured position, not the identity of a particular item.

The choice stays in prepare_items_if_needed, where List already measures its rows. Selection, filtering, and header/footer measurement are unchanged.

Screenshots

Both captures use the same fixed-data Story setup, with an empty first section and search results replaced on each query. Only the measurement fix differs. This setup is not included in the PR.

Before After
Acme overlaps its section footer before the fix Acme and its footer occupy separate space after the fix

How to Test

The regression reproduces the problem without any Story changes:

cargo test -p gpui-component --lib measures_an_existing_row_when_the_requested_item_is_absent --locked

Without the fix, the test fails with 0px instead of 36px. It covers missing rows and sections, an empty list, and a configured index becoming invalid and then valid again. Different row heights verify that measurement returns to the configured index without resetting it.

I also manually checked filtering, empty results, clearing the query, repeated searches, and window resizing on macOS. Rows and the section footer stayed separated.

Automated checks
cargo test -p gpui-base -p gpui-component --lib --locked
cargo clippy -p gpui-base -p gpui-component -p gpui-component-story --all-targets --locked -- -D warnings

771 base and 419 component tests passed, along with strict Clippy, formatting, and the diff whitespace check.

Windows and Linux runtime were not tested.

Checklist

  • Read CONTRIBUTING.md and followed the guidelines.
  • Reviewed the final patch, including the AI-assisted changes.
  • Manually tested the related Story example on macOS.

AI assistance

I tested this fix in my application, then asked OpenAI's gpt-6-astra to extract it into a standalone PR. The agent prepared the patch, regression test, and description, and ran the automated checks. I reviewed the extracted patch, requested corrections, and manually tested it again on macOS.

An absent measurement row produces a zero-height wrapper even when other
sections contain items. Validate the configured index and fall back to a
real row without overwriting the caller's preference.
@huacnlee
huacnlee merged commit 3f495d3 into longbridge:main Sep 6, 2026
8 checks passed
huacnlee pushed a commit that referenced this pull request Sep 6, 2026
List Story appends search matches to the previous results. Repeating a
search or refreshing the data duplicates rows, and a query with no
matches can leave old rows visible.

This clears each result group before rebuilding it from the source
companies. The groups themselves stay in place so industry order and
section indices do not change between queries. It also removes an extra
empty group from initialization, which put companies and their industry
headings at different indices.

Only the Story delegate and its regression test change. The List
component and its public API are unchanged.

## Screenshots

These show an unmatched query and the list after clearing it, not a
before/after comparison. Company data is randomly generated on each
launch.

| No matches | Query cleared |
| --- | --- |
| ![An unmatched query leaves no stale
rows](https://github.com/user-attachments/assets/a53b4880-4ddd-4872-b22c-c03e9460e367)
| ![Clearing the query restores the company
rows](https://github.com/user-attachments/assets/9a374283-378b-441d-8c49-c283aecfcff2)
|

## How to Test

On macOS:

```sh
MTL_HUD_ENABLED=1 ./script/run-story-macos List
```

Use the company list's search field, not the sidebar search:

1. Search for a company currently visible in the list. Only matching
companies should remain.
2. Enter `no-company-matches-123`. The list should be empty.
3. Clear the query. The original companies should return under their
industry headings.
4. Repeat the first search and clear it again. Rows should not
accumulate.

Correct filtering can expose the separate row-measurement bug fixed by
[#2975](#2975). If a filtered
row overlaps its footer, that is not fixed here. The two patches should
remain separate, with #2975 merged first.

The regression runs without opening a window:

```sh
cargo test -p gpui-component-story --lib searching_and_refreshing_replace_company_groups --locked
```

It failed before the fix and passes afterward. It checks
case-insensitive matching, no matches, clearing the query, alignment
between companies and industry groups, and rebuilding results without
duplicates.

<details>
<summary>Automated checks</summary>

```sh
cargo test -p gpui-component-story --lib --locked
cargo clippy -p gpui-component-story --all-targets --locked -- -D warnings
```

All 14 Story library tests passed, along with strict Clippy, formatting,
and the diff whitespace check. The agent also checked matching, empty,
cleared, and repeated searches through the macOS accessibility tree.

</details>

Windows and Linux runtime were not tested.

## Checklist

- [x] Read
[CONTRIBUTING.md](https://github.com/longbridge/gpui-kit/blob/main/CONTRIBUTING.md)
and followed the guidelines.
- [x] Reviewed the final patch, including the AI-assisted changes.
- [x] Manually tested the related Story example on macOS.

## AI assistance

I tested this fix in my application, then asked OpenAI's `gpt-6-astra`
to extract it into a standalone PR. The agent prepared the patch,
regression test, and description, and ran the automated checks. I
reviewed the extracted patch, requested corrections, and manually tested
it again on macOS.
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.

2 participants