Skip to content

editor: Fix right-click context menus failing to appear at pixel-snapped scroll positions - #61348

Merged
ChristopherBiscardi merged 1 commit into
zed-industries:mainfrom
amtoaer:fix_context_menu
Jul 22, 2026
Merged

editor: Fix right-click context menus failing to appear at pixel-snapped scroll positions#61348
ChristopherBiscardi merged 1 commit into
zed-industries:mainfrom
amtoaer:fix_context_menu

Conversation

@amtoaer

@amtoaer amtoaer commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Objective

Fixes #56136.

The issue was initially reported while an agent was generating code. Later reports reproduced it during manual editing and with AI disabled, ruling out the agent as the cause.

At fractional display scales, the editor's right-click context menu could fail to appear at specific discrete scroll positions. Scrolling one line at a time could make the menu alternate between hidden and visible, even when its anchor remained within the viewport.

Solution

The editor-specific changes in #54728 started pixel-snapping the vertical scroll position used by EditorElement to derive and render visible rows. However, Editor::display_to_pixel_point continued using the raw scroll position for its visibility check and vertical projection.

When a downward pixel snap crossed an integer display-row boundary, EditorElement treated the preceding row as the visible range start. display_to_pixel_point then rejected that row as being above the raw viewport. Mouse context menu layout returned early before inspecting the actual clicked anchor, leaving the menu state present without rendering its element.

This change applies the same line-height and display-scale pixel snapping in display_to_pixel_point. Its visibility check and coordinate projection now use the coordinate space actually rendered by the editor.

A test-support-only scale-factor setter was also added so GPUI tests can exercise fractional display scaling without depending on the host display.

Testing

Added a GPUI regression test using 100 plain-text lines so the editor can scroll. The test uses a 1.25 scale factor and a 14px font with 1.3 relative line height. The resulting 18.2px line height is rounded to 18px, producing exactly 22.5 device pixels per row.

At a raw scroll position of one row, midpoint-toward-zero snapping maps 22.5 device pixels to 22, or approximately 0.978 rows. This reproduces the old boundary mismatch where the snapped visible range starts at row zero while the raw visibility check starts at row one.

The test pins these values with precondition assertions. Row five and an in-bounds click keep the actual source visible, while checking the rendered bounds of the Copy item ensures the test does not pass merely because menu state was created.

Manually verified that scrolling from the start of a document no longer makes the context menu alternate between hidden and visible.

Self-Review Checklist:

  • I've reviewed my own diff for quality, security, and reliability
  • Unsafe blocks (if any) have justifying comments
  • The content adheres to Zed's UI standards (UX/UI and icon guidelines)
  • Tests cover the new/changed behavior
  • Performance impact has been considered and is acceptable

Showcase

Before:

2026-07-20_23-36-05.mp4

After:

2026-07-20_23-38-15.mp4

Release Notes:

  • Fixed editor right-click context menus intermittently failing to appear at certain scroll positions.

@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Jul 20, 2026
@zed-community-bot zed-community-bot Bot added community champion Issues filed by our amazing community champions! 🫶 guild Pull requests by someone in Zed Guild. NOTE: the label application is automated via github actions labels Jul 20, 2026
@ChristopherBiscardi ChristopherBiscardi added the area:editor Feedback for code editing, formatting, editor iterations, etc label Jul 22, 2026

@ChristopherBiscardi ChristopherBiscardi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

@ChristopherBiscardi
ChristopherBiscardi added this pull request to the merge queue Jul 22, 2026
Merged via the queue into zed-industries:main with commit 547a6cd Jul 22, 2026
69 checks passed
@ChristopherBiscardi ChristopherBiscardi self-assigned this Jul 23, 2026
jolutz pushed a commit to jolutz/zed that referenced this pull request Aug 8, 2026
…ped scroll positions (zed-industries#61348)

# Objective

Fixes zed-industries#56136.

The issue was initially reported while an agent was generating code.
Later reports reproduced it during manual editing and with AI disabled,
ruling out the agent as the cause.

At fractional display scales, the editor's right-click context menu
could fail to appear at specific discrete scroll positions. Scrolling
one line at a time could make the menu alternate between hidden and
visible, even when its anchor remained within the viewport.



## Solution

The editor-specific changes in zed-industries#54728 started pixel-snapping the
vertical scroll position used by `EditorElement` to derive and render
visible rows. However, `Editor::display_to_pixel_point` continued using
the raw scroll position for its visibility check and vertical
projection.

When a downward pixel snap crossed an integer display-row boundary,
`EditorElement` treated the preceding row as the visible range start.
`display_to_pixel_point` then rejected that row as being above the raw
viewport. Mouse context menu layout returned early before inspecting the
actual clicked anchor, leaving the menu state present without rendering
its element.

This change applies the same line-height and display-scale pixel
snapping in `display_to_pixel_point`. Its visibility check and
coordinate projection now use the coordinate space actually rendered by
the editor.

A test-support-only scale-factor setter was also added so GPUI tests can
exercise fractional display scaling without depending on the host
display.

## Testing

Added a GPUI regression test using 100 plain-text lines so the editor
can scroll. The test uses a `1.25` scale factor and a `14px` font with
`1.3` relative line height. The resulting `18.2px` line height is
rounded to `18px`, producing exactly `22.5` device pixels per row.

At a raw scroll position of one row, midpoint-toward-zero snapping maps
`22.5` device pixels to `22`, or approximately `0.978` rows. This
reproduces the old boundary mismatch where the snapped visible range
starts at row zero while the raw visibility check starts at row one.

The test pins these values with precondition assertions. Row five and an
in-bounds click keep the actual source visible, while checking the
rendered bounds of the `Copy` item ensures the test does not pass merely
because menu state was created.

Manually verified that scrolling from the start of a document no longer
makes the context menu alternate between hidden and visible.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

Before:


https://github.com/user-attachments/assets/e14c030f-1587-4172-aed2-fecfbfcb65ed


After:



https://github.com/user-attachments/assets/3080db1e-46eb-4e20-a619-b1608f233668



---

Release Notes:

- Fixed editor right-click context menus intermittently failing to
appear at certain scroll positions.
playdohface pushed a commit to playdohface/zed that referenced this pull request Aug 29, 2026
…ped scroll positions (zed-industries#61348)

# Objective

Fixes zed-industries#56136.

The issue was initially reported while an agent was generating code.
Later reports reproduced it during manual editing and with AI disabled,
ruling out the agent as the cause.

At fractional display scales, the editor's right-click context menu
could fail to appear at specific discrete scroll positions. Scrolling
one line at a time could make the menu alternate between hidden and
visible, even when its anchor remained within the viewport.



## Solution

The editor-specific changes in zed-industries#54728 started pixel-snapping the
vertical scroll position used by `EditorElement` to derive and render
visible rows. However, `Editor::display_to_pixel_point` continued using
the raw scroll position for its visibility check and vertical
projection.

When a downward pixel snap crossed an integer display-row boundary,
`EditorElement` treated the preceding row as the visible range start.
`display_to_pixel_point` then rejected that row as being above the raw
viewport. Mouse context menu layout returned early before inspecting the
actual clicked anchor, leaving the menu state present without rendering
its element.

This change applies the same line-height and display-scale pixel
snapping in `display_to_pixel_point`. Its visibility check and
coordinate projection now use the coordinate space actually rendered by
the editor.

A test-support-only scale-factor setter was also added so GPUI tests can
exercise fractional display scaling without depending on the host
display.

## Testing

Added a GPUI regression test using 100 plain-text lines so the editor
can scroll. The test uses a `1.25` scale factor and a `14px` font with
`1.3` relative line height. The resulting `18.2px` line height is
rounded to `18px`, producing exactly `22.5` device pixels per row.

At a raw scroll position of one row, midpoint-toward-zero snapping maps
`22.5` device pixels to `22`, or approximately `0.978` rows. This
reproduces the old boundary mismatch where the snapped visible range
starts at row zero while the raw visibility check starts at row one.

The test pins these values with precondition assertions. Row five and an
in-bounds click keep the actual source visible, while checking the
rendered bounds of the `Copy` item ensures the test does not pass merely
because menu state was created.

Manually verified that scrolling from the start of a document no longer
makes the context menu alternate between hidden and visible.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

Before:


https://github.com/user-attachments/assets/e14c030f-1587-4172-aed2-fecfbfcb65ed


After:



https://github.com/user-attachments/assets/3080db1e-46eb-4e20-a619-b1608f233668



---

Release Notes:

- Fixed editor right-click context menus intermittently failing to
appear at certain scroll positions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:editor Feedback for code editing, formatting, editor iterations, etc cla-signed The user has signed the Contributor License Agreement community champion Issues filed by our amazing community champions! 🫶 guild Pull requests by someone in Zed Guild. NOTE: the label application is automated via github actions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Editor right-click context menu intermittently fails to appear

2 participants