From f636090fd9214743606e9baf23fd177f24b2a63f Mon Sep 17 00:00:00 2001 From: Jabber Developer Date: Wed, 2 Jul 2025 19:27:15 +0200 Subject: [PATCH] fix(window): preserve scroll offset on page_down and refactor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When paging down beyond the visible chat buffer, the scroll position could jump unexpectedly. This occurred because the visual distance from the bottom (e.g. 6 lines until the last message) wasn’t preserved after loading new messages from the DB. This patch fixes that by capturing the visual offset (`current_offset`) before the DB fetch and reapplying it after, based on the y-position of the final buffer entry. This ensures consistent and smooth scroll transitions, even as message heights vary. In addition to fixing the visual glitch, this commit introduces a targeted performance optimization: once the bottom of the chat has been reached (`WIN_SCROLL_REACHED_BOTTOM`), we skip expensive operations entirely — including datetime lookups and entry formatting — during further page_down events. This reduces performance stalls during rapid paging (e.g. holding the Page Down key at the bottom of the scrolling area). This update also adapts to the recent change in `chatwin_db_history()`, which now returns a `db_history_result_t` instead of `gboolean`, allowing correct differentiation between an empty result and an actual DB error. Together, these changes: - Fix a scroll-jump bug in `page_down` - Improve performance and responsiveness during rapid navigation - Align with improved DB result handling --- src/ui/window.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ui/window.c b/src/ui/window.c index 9bce0f7b..5dc81391 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -710,17 +710,21 @@ win_page_down(ProfWin* window, int scroll_size) // Scrolled down after reaching the bottom of the page if ((*page_start > total_rows - page_space || (*page_start == page_space && *page_start >= total_rows)) && window->type == WIN_CHAT) { int bf_size = buffer_size(window->layout->buffer); - if (bf_size > 0) { + if (bf_size > 0 && *scroll_state != WIN_SCROLL_REACHED_BOTTOM) { + // How many lines are left until end of the screen + int current_offset = total_rows - *page_start; GDateTime* now = g_date_time_new_now_local(); ProfBuffEntry* last_entry = buffer_get_entry(window->layout->buffer, bf_size - 1); auto_gchar gchar* start = g_date_time_format_iso8601(last_entry->time); auto_gchar gchar* end_date = g_date_time_format_iso8601(now); - if (*scroll_state != WIN_SCROLL_REACHED_BOTTOM && !chatwin_db_history((ProfChatWin*)window, start, end_date, FALSE)) { + db_history_result_t db_response = chatwin_db_history((ProfChatWin*)window, start, end_date, FALSE); + if (db_response == DB_RESPONSE_EMPTY) *scroll_state = WIN_SCROLL_REACHED_BOTTOM; - } - int offset = last_entry->y_end_pos - 1; - *page_start = offset - page_space + scroll_size; + // similar to page_up (see explanation there) + // Get offset of the message that was the latest prior to loading messages from the DB + int original_pos = last_entry->y_end_pos; + *page_start = original_pos - current_offset; g_date_time_unref(now); } }