diff options
| author | blasty <blasty@local> | 2026-07-09 16:22:58 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-07-09 16:22:58 +0200 |
| commit | 6ba52ae97fbcf0238b379fef17733425f7cd8706 (patch) | |
| tree | b2ca718afaf556796b90ef726d870fae51b48746 /idatui | |
| parent | smoother scroll restore on jump-back; non-degenerate test (diff) | |
| download | ida-tui-6ba52ae97fbcf0238b379fef17733425f7cd8706.tar.gz ida-tui-6ba52ae97fbcf0238b379fef17733425f7cd8706.tar.xz ida-tui-6ba52ae97fbcf0238b379fef17733425f7cd8706.zip | |
fix stale top frame on jump-back; test the actual repaint
The pane could keep showing the top (scroll 0) after jumping back even though
scroll_offset was correct: the deferred call_after_refresh set the scroll AFTER
the paint and didn't force a repaint. Now the deferred callback re-applies the
scroll AND refreshes, so the pane is repainted at the restored offset.
Crucially, the prior test only checked scroll_offset.y (which was correct even
when the bug was visible). Added a render-level assertion: trace render_line and
assert the last repaint happened at the restored scroll. (Also: my earlier
scratch repros used a non-existent function name so 'back' was a no-op -- the
real suite test uses a valid second function.) pilot suite 53/53.
Diffstat (limited to 'idatui')
| -rw-r--r-- | idatui/app.py | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/idatui/app.py b/idatui/app.py index a5be0f7..b76e6c5 100644 --- a/idatui/app.py +++ b/idatui/app.py @@ -627,8 +627,11 @@ class DisasmView(SearchMixin, NavMixin, ColumnCursor, ScrollView, can_focus=True target = min(self._pending_scroll_y, max(total - 1, 0)) # Apply now (works when the region is already sized) and again after # refresh (covers the case where max_scroll_y isn't computed yet). + # The deferred call also forces a repaint, so the pane is never left + # showing a stale frame at the top with scroll_offset already moved. self.scroll_to(y=target, animate=False) - self.call_after_refresh(lambda t=target: self.scroll_to(y=t, animate=False)) + self.call_after_refresh( + lambda t=target: (self.scroll_to(y=t, animate=False), self.refresh())) else: self._scroll_cursor_into_view() self._pending_scroll_y = None |
