diff --git a/src/ui/titlebar.c b/src/ui/titlebar.c index f0f1e310..7ed5ed81 100644 --- a/src/ui/titlebar.c +++ b/src/ui/titlebar.c @@ -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); diff --git a/src/ui/win_types.h b/src/ui/win_types.h index a7e0174e..360732eb 100644 --- a/src/ui/win_types.h +++ b/src/ui/win_types.h @@ -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 diff --git a/src/ui/window.c b/src/ui/window.c index b2dba5a5..59651843 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -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; @@ -698,9 +701,11 @@ void win_page_down(ProfWin* window, int scroll_size) { int total_rows = getcury(window->layout->win); + int total_rows_with_unread = total_rows + window->layout->unread_msg; int* page_start = &(window->layout->y_pos); int page_space = getmaxy(stdscr) - 4; int page_start_initial = *page_start; + if (scroll_size == 0) scroll_size = page_space; win_scroll_state_t* scroll_state = &window->scroll_state; @@ -709,7 +714,11 @@ 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) { + gboolean past_bottom = *page_start > total_rows_with_unread - page_space; + gboolean at_page_space_and_past_unread = (*page_start == page_space && *page_start >= total_rows_with_unread); + gboolean is_chat = window->type == WIN_CHAT; + + if ((past_bottom || at_page_space_and_past_unread) && is_chat) { 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 +752,16 @@ 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) { 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. + * TODO: update buffer end handling to check messages just after last entry. + */ + if (*scroll_state == WIN_SCROLL_REACHED_BOTTOM) { window->layout->paged = 0; + window->layout->unread_msg = 0; } } @@ -810,6 +822,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 +927,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); @@ -1696,6 +1710,13 @@ win_newline(ProfWin* window) static void _win_printf(ProfWin* window, const char* show_char, int pad_indent, GDateTime* timestamp, int flags, theme_item_t theme_item, const char* const display_from, const char* const from_jid, const char* const message_id, const char* const message, ...) { + + /* Prevent printing and buffer update when user is viewing message history [SCROLLING]*/ + if (window->layout->paged && wins_is_current(window)) { + window->layout->unread_msg++; + return; + } + if (timestamp == NULL) { timestamp = g_date_time_new_now_local(); } else {