mirror of
https://github.com/profanity-im/profanity.git
synced 2024-11-03 19:37:16 -05:00
Fix scrolling state at windows edge
The problem: if user scrolled to the edge of the window, the state that edge is reached, transfers to other windows, rendering user unable to scroll further up/down in other windows as well. Make unique states for each window that show that edge of the DB is reached. Later it might be improved with MAM states as well to decrease load on program in cases when user keeps scrolling despite reaching the edge. Bug discovered by @atomicwatch, reported through the developers' MUC `SCROLL_INNER` naming suggestion by @jubalh
This commit is contained in:
parent
bd0aa3eb85
commit
0d29e05d77
@ -146,9 +146,16 @@ typedef enum {
|
||||
WIN_VCARD
|
||||
} win_type_t;
|
||||
|
||||
typedef enum {
|
||||
WIN_SCROLL_INNER,
|
||||
WIN_SCROLL_REACHED_TOP,
|
||||
WIN_SCROLL_REACHED_BOTTOM
|
||||
} win_scroll_state_t;
|
||||
|
||||
typedef struct prof_win_t
|
||||
{
|
||||
win_type_t type;
|
||||
win_scroll_state_t scroll_state;
|
||||
ProfLayout* layout;
|
||||
Autocomplete urls_ac;
|
||||
Autocomplete quotes_ac;
|
||||
|
@ -75,9 +75,6 @@ static void _win_print_internal(ProfWin* window, const char* show_char, int pad_
|
||||
int flags, theme_item_t theme_item, const char* const from, const char* const message, DeliveryReceipt* receipt);
|
||||
static void _win_print_wrapped(WINDOW* win, const char* const message, size_t indent, int pad_indent);
|
||||
|
||||
static gboolean _reached_top_of_database = FALSE;
|
||||
static gboolean _reached_bottom_of_database = FALSE;
|
||||
|
||||
int
|
||||
win_roster_cols(void)
|
||||
{
|
||||
@ -136,6 +133,7 @@ win_create_console(void)
|
||||
{
|
||||
ProfConsoleWin* new_win = malloc(sizeof(ProfConsoleWin));
|
||||
new_win->window.type = WIN_CONSOLE;
|
||||
new_win->window.scroll_state = WIN_SCROLL_INNER;
|
||||
new_win->window.layout = _win_create_split_layout();
|
||||
|
||||
return &new_win->window;
|
||||
@ -146,6 +144,7 @@ win_create_chat(const char* const barejid)
|
||||
{
|
||||
ProfChatWin* new_win = malloc(sizeof(ProfChatWin));
|
||||
new_win->window.type = WIN_CHAT;
|
||||
new_win->window.scroll_state = WIN_SCROLL_INNER;
|
||||
new_win->window.layout = _win_create_simple_layout();
|
||||
|
||||
new_win->barejid = strdup(barejid);
|
||||
@ -177,6 +176,7 @@ win_create_muc(const char* const roomjid)
|
||||
int cols = getmaxx(stdscr);
|
||||
|
||||
new_win->window.type = WIN_MUC;
|
||||
new_win->window.scroll_state = WIN_SCROLL_INNER;
|
||||
ProfLayoutSplit* layout = malloc(sizeof(ProfLayoutSplit));
|
||||
layout->base.type = LAYOUT_SPLIT;
|
||||
|
||||
@ -231,6 +231,7 @@ win_create_config(const char* const roomjid, DataForm* form, ProfConfWinCallback
|
||||
{
|
||||
ProfConfWin* new_win = malloc(sizeof(ProfConfWin));
|
||||
new_win->window.type = WIN_CONFIG;
|
||||
new_win->window.scroll_state = WIN_SCROLL_INNER;
|
||||
new_win->window.layout = _win_create_simple_layout();
|
||||
new_win->roomjid = strdup(roomjid);
|
||||
new_win->form = form;
|
||||
@ -248,6 +249,7 @@ win_create_private(const char* const fulljid)
|
||||
{
|
||||
ProfPrivateWin* new_win = malloc(sizeof(ProfPrivateWin));
|
||||
new_win->window.type = WIN_PRIVATE;
|
||||
new_win->window.scroll_state = WIN_SCROLL_INNER;
|
||||
new_win->window.layout = _win_create_simple_layout();
|
||||
new_win->fulljid = strdup(fulljid);
|
||||
new_win->unread = 0;
|
||||
@ -264,6 +266,7 @@ win_create_xmlconsole(void)
|
||||
{
|
||||
ProfXMLWin* new_win = malloc(sizeof(ProfXMLWin));
|
||||
new_win->window.type = WIN_XML;
|
||||
new_win->window.scroll_state = WIN_SCROLL_INNER;
|
||||
new_win->window.layout = _win_create_simple_layout();
|
||||
|
||||
new_win->memcheck = PROFXMLWIN_MEMCHECK;
|
||||
@ -276,6 +279,7 @@ win_create_plugin(const char* const plugin_name, const char* const tag)
|
||||
{
|
||||
ProfPluginWin* new_win = malloc(sizeof(ProfPluginWin));
|
||||
new_win->window.type = WIN_PLUGIN;
|
||||
new_win->window.scroll_state = WIN_SCROLL_INNER;
|
||||
new_win->window.layout = _win_create_simple_layout();
|
||||
|
||||
new_win->tag = strdup(tag);
|
||||
@ -291,6 +295,7 @@ win_create_vcard(vCard* vcard)
|
||||
{
|
||||
ProfVcardWin* new_win = malloc(sizeof(ProfVcardWin));
|
||||
new_win->window.type = WIN_VCARD;
|
||||
new_win->window.scroll_state = WIN_SCROLL_INNER;
|
||||
new_win->window.layout = _win_create_simple_layout();
|
||||
|
||||
new_win->vcard = vcard;
|
||||
@ -625,7 +630,6 @@ win_free(ProfWin* window)
|
||||
void
|
||||
win_page_up(ProfWin* window, int scroll_size)
|
||||
{
|
||||
_reached_bottom_of_database = FALSE;
|
||||
int rows = getmaxy(stdscr);
|
||||
int total_rows = getcury(window->layout->win);
|
||||
int page_space = rows - 4;
|
||||
@ -633,6 +637,8 @@ win_page_up(ProfWin* window, int scroll_size)
|
||||
int page_start_initial = *page_start;
|
||||
if (scroll_size == 0)
|
||||
scroll_size = page_space;
|
||||
win_scroll_state_t* scroll_state = &window->scroll_state;
|
||||
*scroll_state = (*scroll_state == WIN_SCROLL_REACHED_BOTTOM) ? WIN_SCROLL_INNER : *scroll_state;
|
||||
|
||||
*page_start -= scroll_size;
|
||||
|
||||
@ -642,11 +648,11 @@ win_page_up(ProfWin* window, int scroll_size)
|
||||
|
||||
// Don't do anything if still fetching mam messages
|
||||
if (first_entry && !(first_entry->theme_item == THEME_ROOMINFO && g_strcmp0(first_entry->message, LOADING_MESSAGE) == 0)) {
|
||||
if (!_reached_top_of_database) {
|
||||
_reached_top_of_database = !chatwin_db_history(chatwin, NULL, NULL, TRUE);
|
||||
if (*scroll_state != WIN_SCROLL_REACHED_TOP) {
|
||||
*scroll_state = !chatwin_db_history(chatwin, NULL, NULL, TRUE) ? WIN_SCROLL_REACHED_TOP : WIN_SCROLL_INNER;
|
||||
}
|
||||
|
||||
if (_reached_top_of_database && prefs_get_boolean(PREF_MAM)) {
|
||||
if (*scroll_state == WIN_SCROLL_REACHED_TOP && prefs_get_boolean(PREF_MAM)) {
|
||||
win_print_loading_history(window);
|
||||
iq_mam_request_older(chatwin);
|
||||
}
|
||||
@ -672,7 +678,6 @@ win_page_up(ProfWin* window, int scroll_size)
|
||||
void
|
||||
win_page_down(ProfWin* window, int scroll_size)
|
||||
{
|
||||
_reached_top_of_database = FALSE;
|
||||
int rows = getmaxy(stdscr);
|
||||
int* page_start = &(window->layout->y_pos);
|
||||
int total_rows = getcury(window->layout->win);
|
||||
@ -680,6 +685,8 @@ win_page_down(ProfWin* window, int scroll_size)
|
||||
int page_start_initial = *page_start;
|
||||
if (scroll_size == 0)
|
||||
scroll_size = page_space;
|
||||
win_scroll_state_t* scroll_state = &window->scroll_state;
|
||||
*scroll_state = (*scroll_state == WIN_SCROLL_REACHED_TOP) ? WIN_SCROLL_INNER : *scroll_state;
|
||||
|
||||
*page_start += scroll_size;
|
||||
|
||||
@ -691,8 +698,8 @@ win_page_down(ProfWin* window, int scroll_size)
|
||||
GDateTime* now = g_date_time_new_now_local();
|
||||
gchar* end = g_date_time_format_iso8601(now);
|
||||
// end is free'd inside
|
||||
if (!_reached_bottom_of_database && !chatwin_db_history((ProfChatWin*)window, start, end, FALSE)) {
|
||||
_reached_bottom_of_database = TRUE;
|
||||
if (*scroll_state != WIN_SCROLL_REACHED_BOTTOM && !chatwin_db_history((ProfChatWin*)window, start, end, FALSE)) {
|
||||
*scroll_state = WIN_SCROLL_REACHED_BOTTOM;
|
||||
}
|
||||
|
||||
g_date_time_unref(now);
|
||||
|
Loading…
Reference in New Issue
Block a user