diff options
| author | blasty <blasty@local> | 2026-07-25 18:59:43 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-07-25 18:59:43 +0200 |
| commit | b2f221691f88af382c30b6a1d9060b75ea7c19dd (patch) | |
| tree | 4f8fb8e264a28e30e4bfef3930f1dbded3add205 | |
| parent | projects: don't duplicate a binary that's already in the project (diff) | |
| download | ida-tui-b2f221691f88af382c30b6a1d9060b75ea7c19dd.tar.gz ida-tui-b2f221691f88af382c30b6a1d9060b75ea7c19dd.tar.xz ida-tui-b2f221691f88af382c30b6a1d9060b75ea7c19dd.zip | |
decomp: repaint on a same-viewport jump (Esc back looked like it did nothing)
Esc in the pseudocode view navigated correctly but the pane kept showing the old
cursor line until you pressed something else. The listing view was fine because
its path goes through load(), which relayouts and repaints.
DecompView.goto() sets `cursor`, which is reactive(repaint=False), and then
leaves redrawing to _apply_scroll — but that only repaints via
call_after_refresh, which needs a refresh to actually happen. Jump somewhere
inside the viewport already on screen (exactly what Esc-back within a function
does) and the scroll doesn't change, so nothing asked the widget to redraw: the
old highlight stayed and the status line had already updated, which is why it
looked like the jump half-worked. _move() doesn't hit this because it repaints
the old and new rows via _refresh_lines.
goto() now refreshes explicitly.
Verification note: a render_line-level probe CANNOT see this bug — render_line
reads self.cursor live, so it always reports the new position. The staleness is
in Textual's compositor cache, which only a repaint request clears. Verified by
spying on the widget's refresh instead: a same-viewport goto now requests one
(it requested none before). Suite 192/0.
| -rw-r--r-- | idatui/app.py | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/idatui/app.py b/idatui/app.py index e96483b..db237cb 100644 --- a/idatui/app.py +++ b/idatui/app.py @@ -1574,6 +1574,13 @@ class DecompView(SearchMixin, NavMixin, ColumnCursor, ScrollView, can_focus=True else: scroll_x = sx self._apply_scroll(min(max(scroll_y, 0), max(total - 1, 0)), max(scroll_x, 0)) + # `cursor` is reactive(repaint=False) and _apply_scroll only repaints via + # call_after_refresh, so a jump that lands in the SAME viewport (Esc back + # to another spot in the function already on screen) moved the cursor + # with nothing to redraw it — the pane kept showing the old highlight + # until the next keypress. Repaint here; _move does the same via + # _refresh_lines. + self.refresh() self._after_cursor_move() def get_loading_widget(self): # type: ignore[override] |
