Mouse scrolling and selecting on dialog-command.tsx (ctrl+p) is broken only when is no session opened #4036

Closed
opened 2026-02-16 17:42:22 -05:00 by yindo · 2 comments
Owner

Originally created by @fgonzalezurriola on GitHub (Dec 31, 2025).

Originally assigned to: @kommander on GitHub.

Description

On opencode@dev (0.0.0-dev-202512311752) and main (1.0.220), when I try to use the mouse in a fresh opencode TUI invocation inside Ctrl+P, scrolling is broken and selects results far away from the mouse pointer.

This only happens when is no session started or loaded on screen

I tried to vibe debugging it and this is diagnostic that Opus said:


The specific bug lies in the Hit Grid calculation within the @opentui/core native Zig renderer.
Here is the technical breakdown:

  1. Hit-Testing Desync: The engine uses a "Hit Grid" to map screen coordinates (x, y) to specific Renderables. For elements inside a scrollbox (which uses translateY to simulate scrolling) or absolute positioning, the calculation for populating this grid was getting out of sync with the actual visual render.
  2. Stale Offsets: The logic that registers elements into the Hit Grid was likely using stale or incorrect translateY / parent-offset values.
  3. The Result: The renderer "believed" an element was located at a specific coordinate when it wasn't. So, when you hovered physically over Item A, the Hit Grid reported that Item B occupied that space, triggering onMouseOver for the wrong element.
    By removing onMouseOver from the items and doing the math manually in JavaScript (using the parent container's known state), we bypass this flawed internal hit-testing mechanism entirely.

Because the solution that proposed (and worked) didn't use OpenTui (but some plain javascript to calculate the coords) I chose to not open a pr with that. And I barely know Zig, sorry

I think this is important because is a bug that some new adopter could find and think poorly about the project

Sadly, I got rate limited from the antigravity api. Gemini 3 pro said this:


Technical Analysis (The "Why"):

  1. State vs. Render Lag: ScrollBox updates translateY synchronously in the event handler, but the native Hit Grid is only updated during the next async render() pass.
  2. Stale Hit Grid: renderer.ts processes input events using lib.getRenderableAt(), which queries currentHitGrid. This grid represents the state at the end of Frame N-1.
  3. The Race: If a Scroll Event and a Mouse Move Event occur in the same frame:
    • Scroll: Updates logical Y (Frame N state).
    • Move: Checks Hit Grid (Frame N-1 state).
    • Result: The renderer detects a hit on an item at its old position and fires onMouseOver, even though the item has logically moved away.

That's all I can support I hope you guys get a Happy new year :D

OpenCode version

1.0.220

Steps to reproduce

  1. opencode
  2. ctrl+p
  3. Scroll and move mouse
  4. Try to select something

Screenshot and/or share link

https://opncd.ai/share/DJr5d0SD the first half is on spanish read the last half

Operating System

CachyOS

Terminal

Ghostty and Alacritty

Originally created by @fgonzalezurriola on GitHub (Dec 31, 2025). Originally assigned to: @kommander on GitHub. ### Description On opencode@dev (0.0.0-dev-202512311752) and main (1.0.220), when I try to use the mouse in a fresh opencode TUI invocation inside Ctrl+P, scrolling is broken and selects results far away from the mouse pointer. This only happens when is no session started or loaded on screen I tried to vibe debugging it and this is diagnostic that Opus said: --- The specific bug lies in the Hit Grid calculation within the @opentui/core native Zig renderer. Here is the technical breakdown: 1. Hit-Testing Desync: The engine uses a "Hit Grid" to map screen coordinates (x, y) to specific Renderables. For elements inside a scrollbox (which uses translateY to simulate scrolling) or absolute positioning, the calculation for populating this grid was getting out of sync with the actual visual render. 2. Stale Offsets: The logic that registers elements into the Hit Grid was likely using stale or incorrect translateY / parent-offset values. 3. The Result: The renderer "believed" an element was located at a specific coordinate when it wasn't. So, when you hovered physically over Item A, the Hit Grid reported that Item B occupied that space, triggering onMouseOver for the wrong element. By removing onMouseOver from the items and doing the math manually in JavaScript (using the parent container's known state), we bypass this flawed internal hit-testing mechanism entirely. --- Because the solution that proposed (and worked) didn't use OpenTui (but some plain javascript to calculate the coords) I chose to not open a pr with that. And I barely know Zig, sorry I think this is important because is a bug that some new adopter could find and think poorly about the project Sadly, I got rate limited from the antigravity api. Gemini 3 pro said this: --- Technical Analysis (The "Why"): 1. State vs. Render Lag: ScrollBox updates translateY synchronously in the event handler, but the native Hit Grid is only updated during the next async render() pass. 2. Stale Hit Grid: renderer.ts processes input events using lib.getRenderableAt(), which queries currentHitGrid. This grid represents the state at the end of Frame N-1. 3. The Race: If a Scroll Event and a Mouse Move Event occur in the same frame: * Scroll: Updates logical Y (Frame N state). * Move: Checks Hit Grid (Frame N-1 state). * Result: The renderer detects a hit on an item at its old position and fires onMouseOver, even though the item has logically moved away. --- That's all I can support I hope you guys get a Happy new year :D ### OpenCode version 1.0.220 ### Steps to reproduce 1. `opencode` 2. ctrl+p 3. Scroll and move mouse 4. Try to select something ### Screenshot and/or share link https://opncd.ai/share/DJr5d0SD the first half is on spanish read the last half ### Operating System CachyOS ### Terminal Ghostty and Alacritty
yindo added the opentuibugperf labels 2026-02-16 17:42:22 -05:00
yindo closed this issue 2026-02-16 17:42:22 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Dec 31, 2025):

This issue might be a duplicate of existing issues. Please check:

  • #1210: Mouse text selection has unexpected behavior in terminal (similar coordinate/offset tracking issues with mouse input in the TUI)
  • #5168: Mouse Input Spam / SIGPWR Signal Storm in WSL2 (related to mouse input problems in terminals)
  • #3199: Mouse Generates Garbled Text Input & Blocks User Input (related to mouse input causing issues)

Feel free to ignore if none of these address your specific case.

@github-actions[bot] commented on GitHub (Dec 31, 2025): This issue might be a duplicate of existing issues. Please check: - #1210: Mouse text selection has unexpected behavior in terminal (similar coordinate/offset tracking issues with mouse input in the TUI) - #5168: Mouse Input Spam / SIGPWR Signal Storm in WSL2 (related to mouse input problems in terminals) - #3199: Mouse Generates Garbled Text Input & Blocks User Input (related to mouse input causing issues) Feel free to ignore if none of these address your specific case.
Author
Owner

@fgonzalezurriola commented on GitHub (Jan 11, 2026):

Ok this guy fixed it: https://x.com/kitlangton/status/2010152226837201113

@fgonzalezurriola commented on GitHub (Jan 11, 2026): Ok this guy fixed it: https://x.com/kitlangton/status/2010152226837201113
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#4036