From e3636217535a5ff93f9b448cb1998ed010bfbbba Mon Sep 17 00:00:00 2001 From: blasty Date: Thu, 9 Jul 2026 15:25:02 +0200 Subject: paging: preserve the cursor's viewport-relative row (IDA-style) PageUp/Down and Ctrl+U/D now move the scroll top and the cursor by the same (clamped) delta, so the cursor keeps its relative screen row instead of snapping to an edge; at the very top/bottom the cursor jumps to the extreme. Shared _page_scroll in ColumnCursor, used by both views. pilot suite 49/49. --- idatui/app.py | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'idatui') diff --git a/idatui/app.py b/idatui/app.py index 497f0ac..87420c2 100644 --- a/idatui/app.py +++ b/idatui/app.py @@ -301,6 +301,31 @@ class ColumnCursor: if event.chain >= 2: # double-click == place cursor + follow self.post_message(FollowRequested(self)) + # -- paging (keeps the cursor at the same viewport-relative row) ------- # + def _page_scroll(self, lines: int) -> None: + total = self.total + if total <= 0: + return + height = self._visible_height() + top = round(self.scroll_offset.y) + max_top = max(total - height, 0) + new_top = max(0, min(max_top, top + lines)) + delta = new_top - top + if delta == 0: # already at an edge: jump the cursor to the extreme + self.cursor = (total - 1) if lines > 0 else 0 + else: # move cursor by the same delta -> relative row preserved + self.cursor = max(0, min(total - 1, self.cursor + delta)) + self._clamp_x() + self.scroll_to(y=new_top, animate=False) + self.refresh() + self._after_cursor_move() + + def action_page(self, direction: int) -> None: + self._page_scroll(direction * self._visible_height()) + + def action_half_page(self, direction: int) -> None: + self._page_scroll(direction * (self._visible_height() // 2)) + class SearchMixin: """Vim-style in-view search shared by the disasm and pseudocode views. @@ -698,12 +723,6 @@ class DisasmView(SearchMixin, NavMixin, ColumnCursor, ScrollView, can_focus=True def action_cursor_up(self) -> None: self._move(-1) - def action_half_page(self, direction: int) -> None: - self._move(direction * (self._visible_height() // 2)) - - def action_page(self, direction: int) -> None: - self._move(direction * self._visible_height()) - def action_goto_top(self) -> None: self._move(-self.total) @@ -869,12 +888,6 @@ class DecompView(SearchMixin, NavMixin, ColumnCursor, ScrollView, can_focus=True def action_cursor_up(self) -> None: self._move(-1) - def action_half_page(self, direction: int) -> None: - self._move(direction * (self._visible_height() // 2)) - - def action_page(self, direction: int) -> None: - self._move(direction * self._visible_height()) - def action_goto_top(self) -> None: self._move(-len(self._strips)) -- cgit v1.3.1-sl0p