From f218e3f15e2d5525e817fb07e6a8b4773f296073 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 18 May 2019 02:25:48 -0700 Subject: [PATCH] fix #H8753 - curses message window anomalies Autodescribe feedback and multi-digit count prompts are always shown on the last line of the message window and are suppressed from message history (both ^P and DUMPLOG). When the message window is using all available lines, the last one was being overwritten (until the count or the feedback was completed or dismissed, then last line returned). Adopt the suggestion that it be scrolled up a line instead of being overwritten. [I haven't been able to reproduce the reported problem where shorter overlaid text left some of longer underlying text visible but that should now become moot.] Bonus fix: while testing, I noticed that if your screen only has room for a one-line message window and you used ESC to cancel 'pick a spot with cursor' prompting before moving the cursor, the prompt was left intact on the message line. tty erases it in that situation, but the clear_nhwindow(WIN_MESSAGE) was a no-op for curses because it usually doesn't erase old messages. This changes the curses behavior when the core asks it to erase the message window: now it forces one blank line of fake autodesribe feedback (causing the prompt or other most recent message to scroll off top), then removes that fake feedback (leaving a blank message line). For multi-line message window, the old messages scroll up by one line sooner than they would when waiting for the next real message but are otherwise unaffected. --- doc/fixes36.3 | 8 +++++++- win/curses/cursinit.c | 3 +++ win/curses/cursmain.c | 6 ++++++ win/curses/cursmesg.c | 34 ++++++++++++++++++++++------------ win/curses/curswins.c | 6 ++++++ 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 77aac6895..f935c3bdc 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.3 $ $NHDT-Date: 1558045586 2019/05/16 22:26:26 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.5 $ $NHDT-Date: 1558171542 2019/05/18 09:25:42 $ 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, @@ -26,6 +26,12 @@ Platform- and/or Interface-Specific Fixes or Features curses: very tall menus tried to use selector characters a-z, A-Z, and 0-9, but 0-9 should be reserved for counts and if the display was tall enough for more than 62 entries, arbitrary ASCII punctuation got used +curses: when all available lines in the message window are in use, + autodescribe feedback for 'pick a position with cursor' overwrote + the last line (usually the 'pick a position' prompt/hint), sometimes + leaving part of longer underlying line's text visible +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 Windows: some startup error messages were not being delivered successfully diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 19a12c6bc..728f1e8ea 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -260,6 +260,9 @@ curses_create_main_windows() if (curses_get_nhwin(STATUS_WIN)) { curses_del_nhwin(STATUS_WIN); + /* 'count window' overlays last line of mesg win; + asking it to display a Null string removes it */ + curses_count_window((char *) 0); curses_del_nhwin(MESSAGE_WIN); curses_del_nhwin(MAP_WIN); curses_del_nhwin(INV_WIN); diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index c179610b6..96f984213 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -301,6 +301,11 @@ curses_clear_nhwindow(winid wid) { if (wid != NHW_MESSAGE) { curses_clear_nhwin(wid); + } else { + /* scroll the message window one line if it's full */ + curses_count_window(""); + /* remove 'countwin', leaving last message line blank */ + curses_count_window((char *) 0); } } @@ -585,6 +590,7 @@ wait_synch() -- Wait until all pending output is complete (*flush*() for void curses_wait_synch() { + /* [do we need 'if (counting) curses_count_window((char *)0);' here?] */ } /* diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index 656dce57d..f9a8468d6 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -164,7 +164,7 @@ curses_got_input(void) /* misleadingly named; represents number of lines delivered since player was sure to have had a chance to read them; if player - has just given input then there aren't any such lines right; + has just given input then there aren't any such lines right now; that includes responding to More>> even though it stays same turn */ turn_lines = 0; } @@ -375,8 +375,8 @@ void curses_count_window(const char *count_text) { static WINDOW *countwin = NULL; - int startx, starty, winx, winy; - int messageh, messagew; + int winx, winy; + int messageh, messagew, border; if (!count_text) { if (countwin) @@ -384,17 +384,28 @@ curses_count_window(const char *count_text) counting = FALSE; return; } - counting = TRUE; + /* position of message window, not current position within message window + (so <0,0> for align_message:Top but will vary for other alignings) */ curses_get_window_xy(MESSAGE_WIN, &winx, &winy); + /* size of message window, with space for borders already subtracted */ curses_get_window_size(MESSAGE_WIN, &messageh, &messagew); - if (curses_window_has_border(MESSAGE_WIN)) { - winx++; - winy++; - } + /* decide where to put the one-line counting window */ + border = curses_window_has_border(MESSAGE_WIN) ? 1 : 0; + winx += border; /* first writeable message column */ + winy += border + (messageh - 1); /* last writable message line */ - winy += messageh - 1; + /* 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 + 1 >= border + messageh) { + scroll_window(MESSAGE_WIN); + /* last position within the message window */ + my = border + (messageh - 1) - 1; + mx = border; + /* wmove(curses_get_nhwin(MESSAGE_WIN), my, mx); -- not needed */ + } + counting = TRUE; #ifdef PDCURSES if (countwin) @@ -404,10 +415,9 @@ curses_count_window(const char *count_text) but not for dolook's autodescribe when it refers to a named monster */ if (!countwin) countwin = newwin(1, messagew, winy, winx); - startx = 0; - starty = 0; + werase(countwin); - mvwprintw(countwin, starty, startx, "%s", count_text); + mvwprintw(countwin, 0, 0, "%s", count_text); wrefresh(countwin); } diff --git a/win/curses/curswins.c b/win/curses/curswins.c index ae28140b9..5c9997633 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -352,6 +352,8 @@ curses_del_wid(winid wid) void curs_destroy_all_wins() { + curses_count_window((char *) 0); /* clean up orphan */ + while (nhwids) curses_del_wid(nhwids->nhwid); } @@ -483,6 +485,10 @@ curses_puts(winid wid, int attr, const char *text) } if (wid == MESSAGE_WIN) { + /* if a no-history message is being shown, remove it */ + if (counting) + curses_count_window((char *) 0); + curses_message_win_puts(text, FALSE); return; } -- 2.40.0