Fix pointer style becoming sticky on screen removal #6358
+51
−2
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #6349 - The mouse pointer (cursor) style becomes "sticky" when a modal screen containing a
Buttonis dismissed. The cursor remains as a pointing-hand instead of reverting to the default arrow.Root cause: Two issues contributed:
Stale
mouse_overreference:update_pointer_shape()usedapp.mouse_overwithout checking whether the widget belonged to the current screen. After a screen dismiss,mouse_overcould still reference a widget from the removed screen (e.g., aButtonwithpointer: pointerstyle), causing the stale pointer shape to persist.Missing pointer refresh on screen resume:
_on_screen_resumedid not re-send the pointer shape to the terminal. Since_pointer_shapeis a reactivevar, the watcher only fires on value changes. If the resumed screen already had_pointer_shape="default", no escape sequence was emitted -- so the terminal kept showing the dismissed screen's pointer shape.Fix:
update_pointer_shape()against stale cross-screenmouse_overreferences by checking if the widget is an ancestor of the current screen._on_screen_resumeafter recalculating the correct shape, regardless of whether the reactive value changed.Test plan
test_pointer_shape_restored_on_screen_dismissthat reproduces the exact scenario from the issue (push modal with Button, hover over button, dismiss, verify pointer resets)test_pointer_shapetest continues to passtest_app.pytests pass (27/27)test_screens.pyandtest_modal.pytests pass (20/20)🤖 Generated with Claude Code