From f25ac939ccccb83afdf6a62aba1b085a102aae2f Mon Sep 17 00:00:00 2001 From: Jessey van Offeren Date: Thu, 21 May 2026 20:27:51 +0200 Subject: [PATCH] fix(share): terminal scrollback for large output Render with pyte.HistoryScreen and show scrollback + screen, so large output (ls -la, cat, etc.) can be scrolled up to read. Auto-scroll to the bottom only when already at the bottom; preserve position when the user has scrolled up. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 5 +++++ pyproject.toml | 2 +- src/rigdoctor/__init__.py | 2 +- src/rigdoctor/gui/terminal_widget.py | 27 ++++++++++++++++++--------- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3262b0e..3ce9f99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to RigDoctor are recorded here. Format follows (`MAJOR.MINOR.PATCH`, pre-1.0). `__version__` and `pyproject.toml` must match the git release tag (so the auto-updater, D18, can compare versions). +## [0.7.3] - 2026-05-21 +### Fixed +- Shared terminal now has **scrollback** — large output (e.g. `ls -la`) can be scrolled up to + read; it keeps a history buffer and only auto-scrolls to the bottom when you're already there. + ## [0.7.2] - 2026-05-21 ### Changed - Removed the GUI **Inventory** tab — use the CLI `rigdoctor inventory` instead. (Inventory is diff --git a/pyproject.toml b/pyproject.toml index 39fc91e..ab28edc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "rigdoctor" -version = "0.7.2" +version = "0.7.3" description = "Modular hardware monitoring & crash diagnostics for Linux gamers." readme = "README.md" requires-python = ">=3.11" diff --git a/src/rigdoctor/__init__.py b/src/rigdoctor/__init__.py index 613139b..8abac0e 100644 --- a/src/rigdoctor/__init__.py +++ b/src/rigdoctor/__init__.py @@ -1,3 +1,3 @@ """RigDoctor — modular hardware monitoring & crash diagnostics for Linux gamers.""" -__version__ = "0.7.2" +__version__ = "0.7.3" diff --git a/src/rigdoctor/gui/terminal_widget.py b/src/rigdoctor/gui/terminal_widget.py index cb2dab6..c2de92f 100644 --- a/src/rigdoctor/gui/terminal_widget.py +++ b/src/rigdoctor/gui/terminal_widget.py @@ -24,7 +24,7 @@ class TerminalView(QPlainTextEdit): self.setUndoRedoEnabled(False) self.setMinimumHeight(260) self._rows, self._cols = rows, cols - self._screen = pyte.Screen(cols, rows) + self._screen = pyte.HistoryScreen(cols, rows, history=1000, ratio=0.5) self._stream = pyte.ByteStream(self._screen) def grid(self) -> tuple[int, int]: @@ -38,15 +38,24 @@ class TerminalView(QPlainTextEdit): self._screen.reset() self._render() + def _row_text(self, row) -> str: + return "".join(row[x].data for x in range(self._cols)).rstrip() + def _render(self) -> None: - self.setPlainText("\n".join(self._screen.display)) - # Place the caret at the terminal's actual cursor (row, col) and keep it in view. - cursor = self.textCursor() - cursor.movePosition(QTextCursor.MoveOperation.Start) - cursor.movePosition(QTextCursor.MoveOperation.Down, QTextCursor.MoveMode.MoveAnchor, self._screen.cursor.y) - cursor.movePosition(QTextCursor.MoveOperation.Right, QTextCursor.MoveMode.MoveAnchor, self._screen.cursor.x) - self.setTextCursor(cursor) - self.ensureCursorVisible() + bar = self.verticalScrollBar() + at_bottom = bar.value() >= bar.maximum() - 2 + prev = bar.value() + history = [self._row_text(r) for r in self._screen.history.top] # scrollback + self.setPlainText("\n".join(history + list(self._screen.display))) + if at_bottom: # follow output; place caret at the real (row, col) + cursor = self.textCursor() + cursor.movePosition(QTextCursor.MoveOperation.Start) + cursor.movePosition(QTextCursor.MoveOperation.Down, QTextCursor.MoveMode.MoveAnchor, len(history) + self._screen.cursor.y) + cursor.movePosition(QTextCursor.MoveOperation.Right, QTextCursor.MoveMode.MoveAnchor, self._screen.cursor.x) + self.setTextCursor(cursor) + self.ensureCursorVisible() + else: # user scrolled up to read — keep their place + bar.setValue(prev) def resizeEvent(self, event): # noqa: N802 (Qt override) super().resizeEvent(event)