From cde528fdd90697c89414c061cfb085ae7d52222e Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Tue, 6 Feb 2024 01:40:45 +0330 Subject: [PATCH] LibLine: Fully redraw on resize when origin position changes --- Userland/Libraries/LibLine/Editor.cpp | 29 ++++++++++++++++++++++++++- Userland/Libraries/LibLine/Editor.h | 1 + 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibLine/Editor.cpp b/Userland/Libraries/LibLine/Editor.cpp index d5367de31f..5b8745ba31 100644 --- a/Userland/Libraries/LibLine/Editor.cpp +++ b/Userland/Libraries/LibLine/Editor.cpp @@ -644,12 +644,38 @@ ErrorOr Editor::resized() { m_was_resized = true; m_previous_num_columns = m_num_columns; + auto old_origin_row = m_origin_row; + auto old_origin_column = m_origin_column; + get_terminal_size(); if (!m_has_origin_reset_scheduled) { // Reset the origin, but make sure it doesn't blow up if we can't read it if (set_origin(false)) { + // The origin we have right now actually points to where the cursor should be (in the middle of the buffer somewhere) + // Find the "true" origin. + auto current_buffer_metrics = actual_rendered_string_metrics(buffer_view(), m_current_masks); + auto lines = m_cached_prompt_metrics.lines_with_addition(current_buffer_metrics, m_num_columns); + auto offset = m_cached_prompt_metrics.offset_with_addition(current_buffer_metrics, m_num_columns); + if (lines > m_origin_row) + m_origin_row = 1; + else + m_origin_row -= lines - 1; // the prompt and the origin share a line. + + if (offset > m_origin_column) + m_origin_column = 1; + else + m_origin_column -= offset; + + set_origin(m_origin_row, m_origin_column); + TRY(handle_resize_event(false)); + if (old_origin_column != m_origin_column || old_origin_row != m_origin_row) { + m_expected_origin_changed = true; + deferred_invoke([this] { + (void)refresh_display(); + }); + } } else { deferred_invoke([this] { handle_resize_event(true).release_value_but_fixme_should_propagate_errors(); }); m_has_origin_reset_scheduled = true; @@ -1365,8 +1391,9 @@ ErrorOr Editor::refresh_display() // Someone changed the window size, figure it out // and react to it, we might need to redraw. if (m_was_resized) { - if (m_previous_num_columns != m_num_columns) { + if (m_expected_origin_changed || m_previous_num_columns != m_num_columns) { // We need to cleanup and redo everything. + m_expected_origin_changed = false; m_cached_prompt_valid = false; m_refresh_needed = true; swap(m_previous_num_columns, m_num_columns); diff --git a/Userland/Libraries/LibLine/Editor.h b/Userland/Libraries/LibLine/Editor.h index a32c32f470..7386d8e10e 100644 --- a/Userland/Libraries/LibLine/Editor.h +++ b/Userland/Libraries/LibLine/Editor.h @@ -442,6 +442,7 @@ private: // Exact position before our prompt in the terminal. size_t m_origin_row { 0 }; size_t m_origin_column { 0 }; + bool m_expected_origin_changed { false }; bool m_has_origin_reset_scheduled { false }; OwnPtr m_suggestion_display;