diff options
| author | blasty <blasty@local> | 2026-07-09 14:17:20 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-07-09 14:17:20 +0200 |
| commit | 29326c9c88a62532fd5aeb76302075ab138c5887 (patch) | |
| tree | cab35eee55256dd4565f18f878b9a97aabe79081 /idatui | |
| parent | column cursor: real left/right movement + follow the ref UNDER the cursor (diff) | |
| download | ida-tui-29326c9c88a62532fd5aeb76302075ab138c5887.tar.gz ida-tui-29326c9c88a62532fd5aeb76302075ab138c5887.tar.xz ida-tui-29326c9c88a62532fd5aeb76302075ab138c5887.zip | |
mouse: click to place cursor, double-click to follow
- ColumnCursor.on_click maps the click to a virtual (line, column) via
event.get_content_offset (handles padding/border) + scroll_offset, then places
the line+column cursor (disasm posts CursorMoved for the status line).
- double-click (event.chain>=2) = place cursor + follow the symbol under it,
identical to selecting it and pressing Enter.
- works in both views (verified: disasm click on 'call sub_XXXX' lands on the
exact token; pseudocode click maps columns with no padding).
- pilot suite 36/36.
Diffstat (limited to 'idatui')
| -rw-r--r-- | idatui/app.py | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/idatui/app.py b/idatui/app.py index d8900c0..49156e6 100644 --- a/idatui/app.py +++ b/idatui/app.py @@ -253,6 +253,35 @@ class ColumnCursor: s, e = _word_bounds(plain, min(self.cursor_x, len(plain) - 1)) return plain[s:e] or None + # -- mouse ------------------------------------------------------------- # + def _after_cursor_move(self) -> None: + pass + + def _set_cursor_at(self, line: int, col: int) -> None: + total = self.total + if total <= 0: + return + self.cursor = max(0, min(total - 1, line)) + plain = self._line_plain(self.cursor) + maxx = max(len(plain) - 1, 0) if plain is not None else col + self.cursor_x = max(0, min(maxx, col)) + self._scroll_cursor_into_view() + self._hscroll() + self.refresh() + self._after_cursor_move() + + def on_click(self, event) -> None: # type: ignore[no-untyped-def] + off = event.get_content_offset(self) + if off is None: + return + line = round(self.scroll_offset.y) + off.y + if line >= self.total: + return + self.focus() + self._set_cursor_at(line, round(self.scroll_offset.x) + off.x) + if event.chain >= 2: # double-click == place cursor + follow + self.post_message(FollowRequested(self)) + class SearchMixin: """Vim-style in-view search shared by the disasm and pseudocode views. @@ -617,6 +646,9 @@ class DisasmView(SearchMixin, NavMixin, ColumnCursor, ScrollView, can_focus=True _refresh_lines(self, old, self.cursor) # only the two changed rows self.post_message(DisasmView.CursorMoved(self.cursor, self._cursor_ea())) + def _after_cursor_move(self) -> None: + self.post_message(DisasmView.CursorMoved(self.cursor, self._cursor_ea())) + def _cursor_ea(self) -> int | None: if self.model is None: return None |
