# Fix editor hang when positioned above viewport \(\#45077\) · gitcafe/zed

[View on GitCafe](https://git.cafe/gitcafe/zed/commit/637ff342545523e66f2e2964e6c16fdeaa227dee)

Repository: [gitcafe/zed](https://git.cafe/gitcafe/zed)

Visibility: public

Requested revision: 637ff342545523e66f2e2964e6c16fdeaa227dee

Requested commit: 637ff342545523e66f2e2964e6c16fdeaa227dee

Commit: 637ff342545523e66f2e2964e6c16fdeaa227dee

Tree: d5dba8bc81c4a8ff946c2e74baed5bffa3917a05

Author: Antonio Scandurra

Committer: GitHub

## Message

````
Fix editor hang when positioned above viewport (#45077)

Fixes the hang introduced in #44995 (which was reverted in #45011) and
re-enables the optimization.

## Background

PR #44995 introduced an optimization to skip rendering lines that are
clipped by parent containers (e.g., when a large AutoHeight editor is
inside a scrollable List). This significantly improved performance for
large diffs in the Agent Panel.
However, #45011 reverted this change because it caused the main thread
to hang for 100+ seconds in certain scenarios, requiring a force quit to
recover.

## Root Cause
The original analysis in #45011 suggested that visible_bounds wasn’t
being intersected properly, but that was incorrect—the intersection via
with_content_mask works correctly. The actual bug: when an editor is
positioned above the visible viewport (e.g., scrolled past in a List),
the clipping calculation produces a start_row that exceeds max_row:

1. Editor’s bounds.origin.y becomes very negative (e.g., -10000px)
2. After intersection, visible_bounds.origin.y is at the viewport top
(e.g., 0)
3. clipped_top_in_lines = (0 - (-10000)) / line_height = huge number
4. start_row = huge number, but end_row is clamped to max_row
5. This creates an invalid range where start_row > end_row

This caused two different failures depending on build mode:
- Debug mode: Panic from subtraction overflow in
Range<DisplayRow>::len()
- Release mode: Integer wraparound causing blocks_in_range to enter an
infinite loop (the 100+ second hang)

## Fix

Simply clamp start_row to max_row, ensuring the row range is always
valid:

```rs
let start_row = cmp::min(
    DisplayRow((scroll_position.y + clipped_top_in_lines).floor() as u32),
    max_row,
);
```

## Testing
Added a regression test that draws an editor at y=-10000 to simulate an
editor that’s been scrolled past in a List. This would panic in debug
mode (and hang in release mode) before the fix.

Release Notes:
- Improved agent panel performance when rendering large diffs.
````

## Parents

- [c5b3b06b94f455383e736d163b181fc37eda7207](https://git.cafe/gitcafe/zed/commit/c5b3b06b94f455383e736d163b181fc37eda7207?format=markdown)

[Source at this commit](https://git.cafe/gitcafe/zed/tree/637ff342545523e66f2e2964e6c16fdeaa227dee?format=markdown)
