fix github issue #1002 - curses screen flash

Reported by jeremyhetzler:  with recently revised curses interface,
when dismissing a menu or prompt with ESC the screen flashed.

This was caused by calling beep() when the terminal is set for
'visible bell' (of flagged as incapable of 'audible bell'); the
curses library flashed the screen deliberately.  We don't want that.

Change the function key handling to not call beep() when an ESC
is typed by itself rather than being the leading part of a
multi-character escape sequence.  beep() will still be called if
you type an arrow key (or other function key) when nethack is
expecting text input.  That's what the recent change intended.

This also removes an early return from parse_escape_sequence()
when a number pad key generates an escape sequence.  I don't have
a number pad to verify that this bit works as intended.

Closes #1002
This commit is contained in:
PatR
2023-03-23 11:12:34 -07:00
parent 8f142020a1
commit f5d400be75
2 changed files with 25 additions and 21 deletions

View File

@@ -1,4 +1,4 @@
HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1093 $ $NHDT-Date: 1672605786 2023/01/01 20:43:06 $
HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1139 $ $NHDT-Date: 1679595146 2023/03/23 18:12:26 $
General Fixes and Modified Features
-----------------------------------
@@ -1535,6 +1535,10 @@ curses: for screen refresh, don't attempt to refresh windows that haven't been
set up yet or have already been shut down
curses: for raw_print() in #if PDCURSES config, don't attempt to write to
message window if it isn't set up yet or has already been shut down
curses: typing ESC to cancel something issued a beep; if the terminal was set
to 'visible bell', the screen flashed; only beep when the ESC is part
of an escape sequence--other than M-c generating ESC c--and nethack
is expecting text rather than a command or direction
Qt: at Xp levels above 20 with 'showexp' On, the combined status field
"Level:NN/nnnnnnnn" was too big and truncated by a char at each end
Qt: searching a text window for something that wasn't found and then searching

View File

@@ -32,7 +32,7 @@ static boolean modifiers_available = FALSE;
static int modified(int ch);
static void update_modifiers(void);
static int parse_escape_sequence(void);
static int parse_escape_sequence(boolean *);
int
curses_getch(void)
@@ -864,7 +864,7 @@ int
curses_convert_keys(int key)
{
boolean reject = !gp.program_state.getting_a_command,
as_is = FALSE;
as_is = FALSE, numpad_esc;
int ret = key;
if (modifiers_available)
@@ -877,11 +877,9 @@ curses_convert_keys(int key)
/* changes ESC c to M-c or number pad key to corresponding digit
(but we only get here via key==ESC if curses' getch() didn't
change the latter to KEY_xyz) */
ret = parse_escape_sequence();
if (ret != '\033') {
reject = FALSE;
as_is = TRUE; /* don't perform phonepad inversion */
}
ret = parse_escape_sequence(&numpad_esc);
reject = ((uchar) ret < 1 || ret > 255);
as_is = !numpad_esc; /* don't perform phonepad inversion */
break;
case KEY_BACKSPACE:
/* we can't distinguish between a separate backspace key and
@@ -980,8 +978,8 @@ curses_convert_keys(int key)
if (reject) {
/* an arrow or function key has been pressed during text entry */
beep(); /* not curses_nhbell() because it might end up getting
* changed to deliver a sound effect */
curses_nhbell(); /* calls beep() which might cause unwanted screen
* refresh if terminal is set for 'visible bell' */
ret = '\033'; /* ESC */
}
@@ -1074,36 +1072,38 @@ curses_mouse_support(int mode) /* 0: off, 1: on, 2: alternate on */
note: curses converts a lot of escape sequences to single values greater
than 255 and those won't look like ESC to caller so won't get here */
static int
parse_escape_sequence(void)
parse_escape_sequence(boolean *keypadnum)
{
#ifndef PDCURSES
int ret;
timeout(10);
*keypadnum = FALSE;
timeout(10);
ret = getch();
if (ret == 'O') { /* Numeric keypad */
/* ESC O <something> */
ret = getch();
if (ret >= 112 && ret <= 121) {
timeout(-1);
return ret - 112 + '0'; /* Convert to number */
}
if (ret == ERR)
ret = 'O'; /* there was no third char; treat as ESC O below */
if (ret == ERR) {
ret = 'O'; /* there was no third char; treat as M-O below */
} else if (ret >= 112 && ret <= 121) { /* 'p'..'y' */
*keypadnum = TRUE; /* convert 'p'..'y' to '0'..'9' below */
}
}
if (ret != ERR && ret <= 255) {
timeout(-1); /* reset to 'wait unlimited time for next input' */
if (*keypadnum) {
ret -= (112 - '0'); /* Convert c from 'ESC O c' to digit */
} else if (ret != ERR && ret <= 255) {
/* ESC <something>; effectively 'altmeta' behind player's back */
ret = M(ret); /* Meta key support for most terminals */
} else {
ret = '\033'; /* Just an escape character */
}
timeout(-1);
return ret;
#else
return '\033';