From 10bcc7adcfd5e0e980bb156de8a38fe5a6484a33 Mon Sep 17 00:00:00 2001 From: cancel Date: Mon, 6 Jan 2020 05:53:16 +0900 Subject: [PATCH] Fix dialogs and menus when terminal is resized big->small->big Used regular curses newwin WINDOWs before. Now uses newpad/subpad. The buffers will be clipped correctly to the visible terminal area, and will not be erased when the window is made too small and then resized to be big again. --- term_util.c | 9 +++++++-- term_util.h | 1 + tui_main.c | 20 ++++++++++++++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/term_util.c b/term_util.c index fe4034b..bbf97b3 100644 --- a/term_util.c +++ b/term_util.c @@ -142,8 +142,13 @@ void qnav_stack_push(Qblock* qb, int height, int width) { } qnav_stack.blocks[qnav_stack.count] = qb; ++qnav_stack.count; - qb->outer_window = newwin(total_h, total_w, top, left); - qb->content_window = derwin(qb->outer_window, height, width, 1, 1); + qb->outer_window = newpad(total_h, total_w); + // This used to be derwin when when used newwin instead of newpad -- not sure + // if we should use derwin or subpad now. subpad is probably more compatible. + // ncurses docs state that it handles it correctly, unlike some others? + qb->content_window = subpad(qb->outer_window, height, width, 1, 1); + qb->y = top; + qb->x = left; qnav_stack.stack_changed = true; } diff --git a/term_util.h b/term_util.h index ee41810..e57fdf8 100644 --- a/term_util.h +++ b/term_util.h @@ -64,6 +64,7 @@ typedef struct { WINDOW* outer_window; WINDOW* content_window; char const* title; + int y, x; } Qblock; typedef struct { diff --git a/tui_main.c b/tui_main.c index bab1510..1b1e3b6 100644 --- a/tui_main.c +++ b/tui_main.c @@ -2668,6 +2668,9 @@ int main(int argc, char** argv) { wnoutrefresh(cont_window); drew_any = true; } + int term_h, term_w; + if (qnav_stack.count > 0) // todo lame, move this + getmaxyx(stdscr, term_h, term_w); for (Usz i = 0; i < qnav_stack.count; ++i) { Qblock* qb = qnav_stack.blocks[i]; if (qnav_stack.stack_changed) { @@ -2684,8 +2687,21 @@ int main(int argc, char** argv) { break; } } - touchwin(qb->outer_window); - wnoutrefresh(qb->outer_window); + touchwin(qb->outer_window); // here? or after continue? + if (term_h < 1 || term_w < 1) + continue; + int qbwin_h, qbwin_w; + getmaxyx(qb->outer_window, qbwin_h, qbwin_w); + int qbwin_endy = qb->y + qbwin_h; + int qbwin_endx = qb->x + qbwin_w; + if (qbwin_endy >= term_h) + qbwin_endy = term_h - 1; + if (qbwin_endx >= term_w) + qbwin_endx = term_w - 1; + if (qb->y >= qbwin_endy || qb->x >= qbwin_endx) + continue; + pnoutrefresh(qb->outer_window, 0, 0, qb->y, qb->x, qbwin_endy, + qbwin_endx); drew_any = true; } qnav_stack.stack_changed = false;