Fix scroll/paging state and buffer handling #45

Manually merged
jabber.developer merged 6 commits from playground/fix/scroll-stuck into master 2026-01-07 10:56:04 +00:00
3 changed files with 34 additions and 5 deletions
Showing only changes of commit 6a47efa049 - Show all commits

View File

@@ -268,7 +268,11 @@ _show_scrolled(ProfWin* current)
wattroff(win, bracket_attrs);
wattron(win, scrolled_attrs);
wprintw(win, "SCROLLED");
if (current->layout->unread_msg == 0) {
wprintw(win, "SCROLLED");
} else {
wprintw(win, "SCROLLED, NEW MESSAGES");
}
wattroff(win, scrolled_attrs);
wattron(win, bracket_attrs);

View File

@@ -120,6 +120,7 @@ typedef struct prof_layout_t
ProfBuff buffer;
int y_pos;
int paged;
int unread_msg;
} ProfLayout;
typedef struct prof_layout_simple_t

View File

@@ -103,6 +103,7 @@ _win_create_simple_layout(void)
layout->base.buffer = buffer_create();
layout->base.y_pos = 0;
layout->base.paged = 0;
layout->base.unread_msg = 0;
scrollok(layout->base.win, TRUE);
return &layout->base;
@@ -120,6 +121,7 @@ _win_create_split_layout(void)
layout->base.buffer = buffer_create();
layout->base.y_pos = 0;
layout->base.paged = 0;
layout->base.unread_msg = 0;
scrollok(layout->base.win, TRUE);
layout->subwin = NULL;
layout->sub_y_pos = 0;
@@ -197,6 +199,7 @@ win_create_muc(const char* const roomjid)
layout->base.buffer = buffer_create();
layout->base.y_pos = 0;
layout->base.paged = 0;
layout->base.unread_msg = 0;
scrollok(layout->base.win, TRUE);
new_win->window.layout = (ProfLayout*)layout;
@@ -709,7 +712,7 @@ win_page_down(ProfWin* window, int scroll_size)
*page_start += 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) {
if (((*page_start > total_rows + window->layout->unread_msg - page_space) || ((*page_start == page_space + window->layout->unread_msg) && *page_start >= (total_rows + window->layout->unread_msg))) && window->type == WIN_CHAT) {
jabber.developer marked this conversation as resolved Outdated

At this point, it's really hard to track what this condition is doing. I suggest that we split it into variables with descriptive names so we can understand what's going on in the future

At this point, it's really hard to track what this condition is doing. I suggest that we split it into variables with descriptive names so we can understand what's going on in the future
int bf_size = buffer_size(window->layout->buffer);
if (bf_size > 0 && *scroll_state != WIN_SCROLL_REACHED_BOTTOM) {
// How many lines are left until end of the screen
@@ -743,13 +746,14 @@ win_page_down(ProfWin* window, int scroll_size)
window->layout->paged = 1;
// update only if position has changed
if (page_start_initial != *page_start) {
if ((page_start_initial != *page_start) || (window->layout->unread_msg)) {
jabber.developer marked this conversation as resolved Outdated

nit: I think that we can get rid of extra pair of parentheses.

nit: I think that we can get rid of extra pair of parentheses.
win_update_virtual(window);
}
// switch off page if last line and space line visible
if (total_rows - *page_start == page_space) {
// switch off page if no messages left to read
jabber.developer marked this conversation as resolved Outdated

Could you apply our standard formatting (should apply automatically on ctrl+shift+i in VSCode)? It will fix the CI

Could you apply our standard formatting (should apply automatically on `ctrl+shift+i` in VSCode)? It will fix the CI
if (*scroll_state == WIN_SCROLL_REACHED_BOTTOM) {
window->layout->paged = 0;
window->layout->unread_msg = 0;
}
}
@@ -810,6 +814,7 @@ win_clear(ProfWin* window)
int* page_start = &(window->layout->y_pos);
*page_start = y;
window->layout->paged = 1;
window->layout->unread_msg = 0;
win_update_virtual(window);
}
@@ -914,6 +919,7 @@ void
win_move_to_end(ProfWin* window)
{
window->layout->paged = 0;
window->layout->unread_msg = 0;
int rows = getmaxy(stdscr);
int y = getcury(window->layout->win);
@@ -1698,17 +1704,18 @@ _win_printf(ProfWin* window, const char* show_char, int pad_indent, GDateTime* t
{
/* Test code start
Description: this code prevents printing and buffer update when user is viewing message history [SCROLLING]
TODO:
- TOLERABLE check window->layout->paged handling for reliability (if buffer size is less than window size [SCROLLING] not set)
jabber.developer marked this conversation as resolved Outdated

Nice place for condition and logic.

I feel that readability could be slightly improved without extra pair of parentheses in (window->layout->paged).

Nice place for condition and logic. I feel that readability could be slightly improved without extra pair of parentheses in `(window->layout->paged)`.
- make a propper condition check for differernt cases
- DONE add a user notification in header when new messages arrive while scrolling history
- DONE handle SCROLLED state properly in case of incominf messages (currently it is cleared before new message is printed)
TODO:
- check window->layout->paged handling for reliability (if buffer size is less than window size [SCROLLING] not set)
- make a propper condition check for differernt cases
- add a user notification in header when new messages arrive while scrolling history
- handle SCROLLED state properly in case of incominf messages (currently it is cleared before new message is printed)
Description: this code prevents printing and buffer when user is viewing message history [SCROLLING]
#warning "TEST CODE: temporary/test code present in window.c:1709 - remove before release"*/
if ((window->layout->paged) && wins_is_current(window)) {
window->layout->unread_msg++;
return;
}
/* Test code end */