diff options
author | Daniel Bertalan <dani@danielbertalan.dev> | 2021-06-05 16:46:33 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-10 17:18:02 +0200 |
commit | ce9460de59e31ede6793432a86fa20f83ee6c753 (patch) | |
tree | bd3e66aa44253ab7c2cf3f9e10ed7fe4bc3faefb /Userland | |
parent | 13991eade72ef6f2c488f40e9cb1304f0133ed57 (diff) | |
download | serenity-ce9460de59e31ede6793432a86fa20f83ee6c753.zip |
Kernel+LibVT: Fix selection with scrollback wrap-around
If lines are removed from the tail of the scrollback buffer, the
previous line indices will refer to different lines; therefore we need
to offset them.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibVT/Range.h | 6 | ||||
-rw-r--r-- | Userland/Libraries/LibVT/Terminal.cpp | 9 | ||||
-rw-r--r-- | Userland/Libraries/LibVT/Terminal.h | 7 | ||||
-rw-r--r-- | Userland/Libraries/LibVT/TerminalWidget.cpp | 5 | ||||
-rw-r--r-- | Userland/Libraries/LibVT/TerminalWidget.h | 2 |
5 files changed, 21 insertions, 8 deletions
diff --git a/Userland/Libraries/LibVT/Range.h b/Userland/Libraries/LibVT/Range.h index 2efcc4af3c..dcb51cb85f 100644 --- a/Userland/Libraries/LibVT/Range.h +++ b/Userland/Libraries/LibVT/Range.h @@ -42,6 +42,12 @@ public: m_end = end; } + void offset_row(int delta) + { + m_start = Position(m_start.row() + delta, m_start.column()); + m_end = Position(m_end.row() + delta, m_end.column()); + } + bool operator==(const Range& other) const { return m_start == other.m_start && m_end == other.m_end; diff --git a/Userland/Libraries/LibVT/Terminal.cpp b/Userland/Libraries/LibVT/Terminal.cpp index 7009a79db5..4d04d34176 100644 --- a/Userland/Libraries/LibVT/Terminal.cpp +++ b/Userland/Libraries/LibVT/Terminal.cpp @@ -39,9 +39,10 @@ void Terminal::clear() void Terminal::clear_history() { dbgln_if(TERMINAL_DEBUG, "Clear history"); + auto previous_history_size = m_history.size(); m_history.clear(); m_history_start = 0; - m_client.terminal_history_changed(); + m_client.terminal_history_changed(-previous_history_size); } #endif @@ -744,8 +745,11 @@ void Terminal::scroll_up(u16 region_top, u16 region_bottom, size_t count) // NOTE: We have to invalidate the cursor first. invalidate_cursor(); + int history_delta = -count; bool should_move_to_scrollback = !m_use_alternate_screen_buffer && max_history_size() != 0; if (should_move_to_scrollback) { + auto remaining_lines = max_history_size() - history_size(); + history_delta = (count > remaining_lines) ? remaining_lines - count : 0; for (size_t i = 0; i < count; ++i) add_line_to_history(move(active_buffer().ptr_at(region_top + i))); } @@ -767,8 +771,7 @@ void Terminal::scroll_up(u16 region_top, u16 region_bottom, size_t count) // The other lines have implicitly been set dirty by being cleared. for (u16 row = region_top; row <= region_bottom - count; ++row) active_buffer()[row].set_dirty(true); - if (!m_use_alternate_screen_buffer && max_history_size() != 0) - m_client.terminal_history_changed(); + m_client.terminal_history_changed(history_delta); } // Insert `count` blank lines at the top of the region. Text moves down. Does not affect the scrollback buffer. diff --git a/Userland/Libraries/LibVT/Terminal.h b/Userland/Libraries/LibVT/Terminal.h index 3087a05c4f..160bf08e40 100644 --- a/Userland/Libraries/LibVT/Terminal.h +++ b/Userland/Libraries/LibVT/Terminal.h @@ -45,7 +45,7 @@ public: virtual void set_window_title(const StringView&) = 0; virtual void set_window_progress(int value, int max) = 0; virtual void terminal_did_resize(u16 columns, u16 rows) = 0; - virtual void terminal_history_changed() = 0; + virtual void terminal_history_changed(int delta) = 0; virtual void emit(const u8*, size_t) = 0; virtual void set_cursor_style(CursorStyle) = 0; }; @@ -141,10 +141,11 @@ public: void set_max_history_size(size_t value) { if (value == 0) { + auto previous_size = m_history.size(); m_max_history_lines = 0; m_history_start = 0; m_history.clear(); - m_client.terminal_history_changed(); + m_client.terminal_history_changed(-previous_size); return; } @@ -158,7 +159,7 @@ public: } m_history = move(new_history); m_history_start = 0; - m_client.terminal_history_changed(); + m_client.terminal_history_changed(value - existing_line_count); } m_max_history_lines = value; } diff --git a/Userland/Libraries/LibVT/TerminalWidget.cpp b/Userland/Libraries/LibVT/TerminalWidget.cpp index aeb4996218..be866a0e10 100644 --- a/Userland/Libraries/LibVT/TerminalWidget.cpp +++ b/Userland/Libraries/LibVT/TerminalWidget.cpp @@ -947,13 +947,16 @@ int TerminalWidget::last_selection_column_on_row(int row) const return row == normalized_selection_end.row() || m_rectangle_selection ? normalized_selection_end.column() : m_terminal.columns() - 1; } -void TerminalWidget::terminal_history_changed() +void TerminalWidget::terminal_history_changed(int delta) { bool was_max = m_scrollbar->value() == m_scrollbar->max(); m_scrollbar->set_max(m_terminal.history_size()); if (was_max) m_scrollbar->set_value(m_scrollbar->max()); m_scrollbar->update(); + // If the history buffer wrapped around, the selection needs to be offset accordingly. + if (m_selection.is_valid() && delta < 0) + m_selection.offset_row(delta); } void TerminalWidget::terminal_did_resize(u16 columns, u16 rows) diff --git a/Userland/Libraries/LibVT/TerminalWidget.h b/Userland/Libraries/LibVT/TerminalWidget.h index 73ef382d69..0935f98cf7 100644 --- a/Userland/Libraries/LibVT/TerminalWidget.h +++ b/Userland/Libraries/LibVT/TerminalWidget.h @@ -119,7 +119,7 @@ private: virtual void set_window_title(const StringView&) override; virtual void set_window_progress(int value, int max) override; virtual void terminal_did_resize(u16 columns, u16 rows) override; - virtual void terminal_history_changed() override; + virtual void terminal_history_changed(int delta) override; virtual void emit(const u8*, size_t) override; virtual void set_cursor_style(CursorStyle) override; |