diff options
| author | blasty <blasty@local> | 2026-07-24 15:48:19 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-07-24 15:48:19 +0200 |
| commit | 4975a92c338819b43cb6647d7bbb9197c5772f32 (patch) | |
| tree | d36a08551940cc25643bab5867d741e1862e8007 /idatui | |
| parent | hex: click to place the byte cursor (hex + ascii panes) (diff) | |
| download | ida-tui-4975a92c338819b43cb6647d7bbb9197c5772f32.tar.gz ida-tui-4975a92c338819b43cb6647d7bbb9197c5772f32.tar.xz ida-tui-4975a92c338819b43cb6647d7bbb9197c5772f32.zip | |
hex: cursor follows the scroll (stays visible on wheel/scrollbar)
Override watch_scroll_y so a viewport scroll drags the byte cursor along: when
the rounded scroll changes, clamp the cursor's row into the visible range
[top, top+height) keeping its column, so it rides the nearest edge instead of
being left off-screen. No feedback loop -- key-nav's _scroll_to_cursor already
puts the cursor in view (clamp is then a no-op), and HexView.Moved only updates
the status line. Pairs with the click-to-place support.
Pilot `hex` scenario updated: after a scroll the cursor must now be within the
visible rows (was: asserted it stayed put). 9/9 hex checks pass.
Diffstat (limited to 'idatui')
| -rw-r--r-- | idatui/app.py | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/idatui/app.py b/idatui/app.py index 5314f66..3b84217 100644 --- a/idatui/app.py +++ b/idatui/app.py @@ -1680,6 +1680,26 @@ class HexView(ScrollView, can_focus=True): top = max(0, min(top, max(self.total - 1, 0))) self._apply_scroll(top) + def watch_scroll_y(self, old_value: float, new_value: float) -> None: + super().watch_scroll_y(old_value, new_value) + # Follow the scroll: a wheel-scroll / scrollbar drag drags the byte cursor + # along so it stays visible (pinned to the nearest edge row, same column). + if round(old_value) != round(new_value): + self._follow_scroll(round(new_value)) + + def _follow_scroll(self, top: int) -> None: + if self.model is None or self.model.size == 0: + return + height = self._visible_height() + row, col = self.cursor // 16, self.cursor % 16 + new_row = min(max(row, top), top + max(height - 1, 0)) + new_row = max(0, min(new_row, max(self.total - 1, 0))) + new_cursor = max(0, min(new_row * 16 + col, self.model.size - 1)) + if new_cursor != self.cursor: + self.cursor = new_cursor + self.refresh() # cursor is reactive(repaint=False) + self.post_message(HexView.Moved(self.cursor_va())) + # -- navigation -------------------------------------------------------- # def _move(self, delta: int) -> None: if self.model is None or self.model.size == 0: |
