mirror of
https://github.com/anomalyco/opentui.git
synced 2026-04-25 13:06:00 +03:00
[PR #502] [MERGED] core: debounce hover recheck after hit-grid changes #1363
Labels
No labels
bug
core
documentation
feature
good first issue
help wanted
pull-request
question
react
solid
tmux
windows
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/opentui#1363
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/anomalyco/opentui/pull/502
Author: @simonklee
Created: 1/8/2026
Status: ✅ Merged
Merged: 1/12/2026
Merged by: @kommander
Base:
main← Head:debounce-hover📝 Commits (8)
c727c0fcore: debounce hover recheck after hit-grid changes35594dffix(renderer): fix debounced hover rechecks and z-index hit/hover updatesaa7bdb2Merge branch 'main' into debounce-hoverae61993check hitgrid dirty in native before swapping2dd819eadd back last ponter modifiersc402472Merge branch 'main' into debounce-hover9454e5aremove dead codecc746a1add examples to index📊 Changes
7 files changed (+616 additions, -4 deletions)
View changed files
📝
packages/core/src/Renderable.ts(+6 -2)📝
packages/core/src/examples/index.ts(+14 -0)📝
packages/core/src/renderer.ts(+53 -0)📝
packages/core/src/tests/scrollbox-hitgrid.test.ts(+518 -2)📝
packages/core/src/zig.ts(+9 -0)📝
packages/core/src/zig/lib.zig(+4 -0)📝
packages/core/src/zig/renderer.zig(+12 -0)📄 Description
So, the core issue was that scrolling or animating elements left the hover state stale because we were only running hit tests on actual mouse movement. If the element moved but the mouse didn't, we wouldn't catch it.
To fix this without tanking performance during scroll, we implemented a dirty-flag + debounce system:
Dirty Tracking: I added a hitGridDirty flag to the renderer. Now, whenever a Renderable changes a property that affects hit testing (translateX/Y, zIndex, visible, overflow, or layout shifts), it calls markHitGridDirty().
Debounced Recheck: At the end of the render loop, if the grid is dirty, we schedule a debounced hover recheck. This groups many updates into a single check instead of running hit logic every frame.
Synthetic Events: The recheck uses the last known pointer position. If the target under the cursor changes, we fire out and over events to update the UI.
I cancel this check if the user moves the mouse, since that triggers an immediate test. It's also skipped during drags to avoid messing with drop targets.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.