From 3863b17384b9a22c414ca0e698a9dde9209ef37c Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 23 May 2019 17:54:37 -0700 Subject: [PATCH 1/3] curses: remove duplicate wincap2 bit WC2_HITPOINTBAR was OR'd into wincap2 bitmask twice. --- win/curses/cursmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 96f984213..ada703de4 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -22,7 +22,7 @@ struct window_procs curses_procs = { #if defined(STATUS_HILITES) | WC2_HILITE_STATUS #endif - | WC2_HITPOINTBAR | WC2_FLUSH_STATUS | WC2_TERM_SIZE + | WC2_FLUSH_STATUS | WC2_TERM_SIZE | WC2_STATUSLINES | WC2_WINDOWBORDERS | WC2_PETATTR | WC2_GUICOLOR | WC2_SUPPRESS_HIST), curses_init_nhwindows, From 5de1666f9cdbe3dda468dd77d78b03217e5eec67 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 23 May 2019 18:56:20 -0700 Subject: [PATCH 2/3] curses message window refresh Sometimes curses tears down and recreates all its windows (when the display is resized, for instance) and after doing that it repopulates the message window with data saved for use by ^P. But it was showing the oldest messages available rather than the most recent ones. There is still room for improvement. That process combines short messages but the refresh is based on the available number of lines; combining messages can result in lines at the bottom of the message window being left blank. This could be fixed by reverse-scrolling the window and inserting more messages at the top, or by combining short messages in history data instead of at refresh time. The second seems easier but won't handle changing the message window's width sensibly, and neither method handles wrapped, long lines well. A More>> prompt (possibly more than one) is issued if the refresh shows too many lines (either because long messages already took multiple lines or because the window has become narrower and ones which used to fit now need to be wrapped). --- doc/fixes36.3 | 8 +++++++- win/curses/cursmesg.c | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 93b708797..dc0c5c8a8 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.12 $ $NHDT-Date: 1558562367 2019/05/22 21:59:27 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.14 $ $NHDT-Date: 1558662976 2019/05/24 01:56:16 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -37,6 +37,12 @@ curses: if message window is only one line, cancelling some prompts with ESC left the prompts visible on the message line instead of erasing them curses: support EDIT_GETLIN (but like with tty, it's disabled by default) to pre-load an earlier response as the default answer for some prompts +curses: when display windows get reconfigured (after setting align_status, + align_message, statuslines, windowborders or due to external resize), + the message window was being refreshed with the oldest available N + messages rather than most recent N. [Still room for improvement; + when feasible it combines short lines, resulting in N messages on + fewer than N lines and leaving some of the available lines blank.] tty: re-do one optimization used when status conditions have all been removed and remove another that tried to check whether condition text to be displayed next was the same as the existing value; sometimes new diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index 4daf1784b..ab22a2586 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -275,25 +275,42 @@ curses_clear_unhighlight_message_window() void curses_last_messages() { - boolean border = curses_window_has_border(MESSAGE_WIN); nhprev_mesg *mesg; - int i, j, height, width; + int i, height, width; + int border = curses_window_has_border(MESSAGE_WIN) ? 1 : 0; + WINDOW *win = curses_get_nhwin(MESSAGE_WIN); curses_get_window_size(MESSAGE_WIN, &height, &width); + werase(win); + mx = my = border; - if (border) - mx = my = 1; - else - mx = my = 0; - + /* + * FIXME! + * This shouldn't be relying on a naive line count to decide where + * to start and stop because curses_message_win_puts() combines short + * lines. So we can end up with blank lines at bottom of the message + * window, missing out on one or more older messages which could have + * been included at the top. + * + * 3.6.2 showed oldest available N lines (by starting at + * num_mesages - 1 and working back toward 0 until window height was + * reached [via index 'j' which is gone now]) rather than most recent + * N (start at height - 1 and work way up through 0) so showed wrong + * lines even if N lines had been the right way to handle this. + */ ++last_messages; - for (j = 0, i = num_messages - 1; i > 0 && j < height; --i, ++j) { + i = min(height, num_messages) - 1; + for ( ; i > 0; --i) { mesg = get_msg_line(TRUE, i); if (mesg && mesg->str && *mesg->str) curses_message_win_puts(mesg->str, TRUE); } curses_message_win_puts(toplines, TRUE); --last_messages; + + if (border) + box(win, 0, 0); + wrefresh(win); } @@ -329,7 +346,7 @@ curses_teardown_messages(void) num_messages = 0; } -/* Display previous message window messages in reverse chron order */ +/* Display previous messages in a popup (via menu so can scroll backwards) */ void curses_prev_mesg() @@ -362,6 +379,8 @@ curses_prev_mesg() if (!do_lifo) curs_menu_set_bottom_heavy(wid); curses_select_menu(wid, PICK_NONE, &selected); + if (selected) /* should always be null for PICK_NONE but be paranoid */ + free((genericptr_t) selected); curses_del_wid(wid); } @@ -712,6 +731,7 @@ mesg_add_line(const char *mline) /* create a new list element */ current_mesg = (nhprev_mesg *) alloc((unsigned) sizeof (nhprev_mesg)); current_mesg->str = dupstr(mline); + current_mesg->next_mesg = current_mesg->prev_mesg = (nhprev_mesg *) 0; } else { /* instead of discarding list element being forced out, reuse it */ current_mesg = first_mesg; From ba5efe7f61598b731f7c8d0c28ecc43e2a978061 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 24 May 2019 01:33:45 -0700 Subject: [PATCH 3/3] curses message window vs prompting Fix a problem introduced by f218e3f15e2d5525e817fb07e6a8b4773f296073 and/or a19e64e470f21ef30b96122dd2d40c26ef9b1527. Sometimes the line after a prompt would be empty and the next message get shown on the line after that. a19e64e470 was intended to fix the opposite problem so probably overshot the mark.... --- doc/fixes36.3 | 3 ++- win/curses/cursmesg.c | 17 +++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index dc0c5c8a8..5ff4a1850 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.14 $ $NHDT-Date: 1558662976 2019/05/24 01:56:16 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.15 $ $NHDT-Date: 1558686805 2019/05/24 08:33:25 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -22,6 +22,7 @@ xans fly, but could not reach your feet if you flew Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository ------------------------------------------------------------------ +curses: sometimes the message window would show a blank line after a prompt Platform- and/or Interface-Specific Fixes or Features diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index ab22a2586..0d67cff1c 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -290,17 +290,18 @@ curses_last_messages() * to start and stop because curses_message_win_puts() combines short * lines. So we can end up with blank lines at bottom of the message * window, missing out on one or more older messages which could have - * been included at the top. + * been included at the top. Also long messages might wrap and take + * more than one line apiece. * - * 3.6.2 showed oldest available N lines (by starting at + * 3.6.2 showed oldest available N-1 lines (by starting at * num_mesages - 1 and working back toward 0 until window height was - * reached [via index 'j' which is gone now]) rather than most recent - * N (start at height - 1 and work way up through 0) so showed wrong - * lines even if N lines had been the right way to handle this. + * reached [via index 'j' which is gone now]) plus the latest line + * (via toplines[]), rather than most recent N (start at height - 1 + * and work way up through 0). So it showed wrong subset of lines + * even if 'N lines' had been the right way to handle this. */ ++last_messages; - i = min(height, num_messages) - 1; - for ( ; i > 0; --i) { + for (i = min(height, num_messages) - 1; i > 0; --i) { mesg = get_msg_line(TRUE, i); if (mesg && mesg->str && *mesg->str) curses_message_win_puts(mesg->str, TRUE); @@ -417,7 +418,7 @@ curses_count_window(const char *count_text) /* if most recent message (probably prompt leading to this instance of counting window) is going to be covered up, scroll mesgs up a line */ - if (!counting && my >= border + (messageh - 1)) { + if (!counting && my == border + (messageh - 1) && mx > border) { scroll_window(MESSAGE_WIN); if (messageh > 1) { /* handling for next message will behave as if we're currently