fix(grid): never dispatch a stale cell from UIGridView::click_at

#355 made last_clicked_cell the channel by which click_at hands a resolved cell
to dispatchCellClick (the point cannot be recomputed later -- click_at works in
parent-local space, PyScene only has global coords). Two gaps let a cell survive
into a dispatch it did not belong to:

1. click_at stashed the cell at step 3 even when it then returned nullptr because
   the view had no handlers. dispatchCellClick only runs on the drawable PyScene
   got back, so nothing consumed that stash and the cell lingered indefinitely.
2. the no-grid_data early return hands back `this` (when click_callable ||
   is_python_subclass) without clearing the stash.

Together: click a cell on a handler-less grid, then enable interactivity and set
grid_data = None, then click the now cell-less view -- and on_cell_click fired
with a cell from a grid that no longer exists. A wrong-data dispatch, not a
missing one.

Now the cell is stashed only when the view is actually returned as the click
target, and the dataless path clears it.

NOTE: #365 as filed described the repro as "click a cell, set grid = None, click
again," which does NOT reproduce -- dispatchCellClick consumes last_clicked_cell
(nullopt on read), so a cell that was actually dispatched cannot survive. The
unconsumed handler-less stash is the real path; the regression test covers it,
plus a guard that a click on no cell leaves nothing behind.

closes #365
This commit is contained in:
John McCardle 2026-07-12 20:26:59 -04:00
commit 11f8394f9b
3 changed files with 135 additions and 4 deletions

File diff suppressed because one or more lines are too long