diff --git a/docs/profanity.1 b/docs/profanity.1 index 8590da59..ef1f4541 100755 --- a/docs/profanity.1 +++ b/docs/profanity.1 @@ -71,6 +71,14 @@ Page the occupants or roster panel up. .BI ALT+PAGEDOWN Page the occupants or roster panel down. .TP +.BI ALT+UP " or " ALT+WHEEL UP +Scroll up. Note: limited support for scrolling with mouse wheel, +please, get in touch with devs if you know how to add support +for other terminals. +.TP +.BI ALT+DOWN " or " ALT+WHEEL DOWN +Scroll down. See note above. +.TP .BI ALT+a Jump to the next unread window. .TP diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 48790e88..8af1b6cd 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -81,6 +81,7 @@ #include "tools/bookmark_ignore.h" #include "tools/editor.h" #include "plugins/plugins.h" +#include "ui/inputwin.h" #include "ui/ui.h" #include "ui/window_list.h" #include "xmpp/avatar.h" diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c index 3966daca..d2104f87 100644 --- a/src/ui/inputwin.c +++ b/src/ui/inputwin.c @@ -136,6 +136,7 @@ static int _inp_rl_subwin_pageup_handler(int count, int key); static int _inp_rl_subwin_pagedown_handler(int count, int key); static int _inp_rl_startup_hook(void); static int _inp_rl_down_arrow_handler(int count, int key); +static int _inp_rl_scroll_handler(int count, int key); static int _inp_rl_send_to_editor(int count, int key); static int _inp_rl_print_newline_symbol(int count, int key); @@ -554,6 +555,8 @@ _inp_rl_startup_hook(void) rl_bind_key('\t', _inp_rl_tab_handler); rl_bind_keyseq("\\e[Z", _inp_rl_shift_tab_handler); + rl_bind_keyseq("\\e[1;3A", _inp_rl_scroll_handler); // alt + scroll/arrow up + rl_bind_keyseq("\\e[1;3B", _inp_rl_scroll_handler); // alt + scroll/arrow down rl_bind_keyseq("\\e[1;5B", _inp_rl_down_arrow_handler); // ctrl+arrow down rl_bind_keyseq("\\eOb", _inp_rl_down_arrow_handler); @@ -906,7 +909,7 @@ static int _inp_rl_win_pageup_handler(int count, int key) { ProfWin* current = wins_get_current(); - win_page_up(current); + win_page_up(current, 0); return 0; } @@ -914,7 +917,7 @@ static int _inp_rl_win_pagedown_handler(int count, int key) { ProfWin* current = wins_get_current(); - win_page_down(current); + win_page_down(current, 0); return 0; } @@ -934,6 +937,21 @@ _inp_rl_subwin_pagedown_handler(int count, int key) return 0; } +static int +_inp_rl_scroll_handler(int count, int key) +{ + ProfWin* window = wins_get_current(); + + if (key == 'B') { + // mouse wheel down + win_page_down(window, 4); + } else if (key == 'A') { + // mouse wheel up + win_page_up(window, 4); + } + return 0; +} + static int _inp_rl_down_arrow_handler(int count, int key) { diff --git a/src/ui/window.c b/src/ui/window.c index 348bfeaa..e3dff377 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -623,17 +623,20 @@ win_free(ProfWin* window) } void -win_page_up(ProfWin* window) +win_page_up(ProfWin* window, int scroll_size) { _reached_bottom_of_database = FALSE; int rows = getmaxy(stdscr); - int y = getcury(window->layout->win); + int total_rows = getcury(window->layout->win); int page_space = rows - 4; int* page_start = &(window->layout->y_pos); + int page_start_initial = *page_start; + if (scroll_size == 0) + scroll_size = page_space; - *page_start -= page_space; + *page_start -= scroll_size; - if (*page_start == -page_space && window->type == WIN_CHAT) { + if (*page_start == -scroll_size && window->type == WIN_CHAT) { ProfChatWin* chatwin = (ProfChatWin*)window; ProfBuffEntry* first_entry = buffer_size(window->layout->buffer) != 0 ? buffer_get_entry(window->layout->buffer, 0) : NULL; @@ -655,27 +658,33 @@ win_page_up(ProfWin* window) *page_start = 0; window->layout->paged = 1; - win_update_virtual(window); + // update only if position has changed + if (page_start_initial != *page_start) { + win_update_virtual(window); + } // switch off page if last line and space line visible - if ((y) - *page_start == page_space) { + if ((total_rows) - *page_start == page_space) { window->layout->paged = 0; } } void -win_page_down(ProfWin* window) +win_page_down(ProfWin* window, int scroll_size) { _reached_top_of_database = FALSE; int rows = getmaxy(stdscr); - int y = getcury(window->layout->win); - int page_space = rows - 4; int* page_start = &(window->layout->y_pos); + int total_rows = getcury(window->layout->win); + int page_space = rows - 4; + int page_start_initial = *page_start; + if (scroll_size == 0) + scroll_size = page_space; - *page_start += page_space; + *page_start += scroll_size; // Scrolled down after reaching the bottom of the page - if ((*page_start == y || (*page_start == page_space && *page_start >= y)) && window->type == WIN_CHAT) { + if ((*page_start == total_rows || (*page_start == page_space && *page_start >= total_rows)) && window->type == WIN_CHAT) { int bf_size = buffer_size(window->layout->buffer); if (bf_size > 0) { auto_gchar gchar* start = g_date_time_format_iso8601(buffer_get_entry(window->layout->buffer, bf_size - 1)->time); @@ -691,18 +700,21 @@ win_page_down(ProfWin* window) } // only got half a screen, show full screen - if ((y - (*page_start)) < page_space) - *page_start = y - page_space; + if ((total_rows - (*page_start)) < page_space) + *page_start = total_rows - page_space; // went past end, show full screen - else if (*page_start >= y) - *page_start = y - page_space - 1; + else if (*page_start >= total_rows) + *page_start = total_rows - page_space - 1; window->layout->paged = 1; - win_update_virtual(window); + // update only if position has changed + if (page_start_initial != *page_start) { + win_update_virtual(window); + } // switch off page if last line and space line visible - if ((y) - *page_start == page_space) { + if ((total_rows) - *page_start == page_space) { window->layout->paged = 0; } } diff --git a/src/ui/window.h b/src/ui/window.h index 9bbbf8c4..037cab0a 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -88,8 +88,8 @@ void win_update_entry_message(ProfWin* window, const char* const id, const char* gboolean win_has_active_subwin(ProfWin* window); -void win_page_up(ProfWin* window); -void win_page_down(ProfWin* window); +void win_page_up(ProfWin* window, int scroll_size); +void win_page_down(ProfWin* window, int scroll_size); void win_sub_page_down(ProfWin* window); void win_sub_page_up(ProfWin* window);