aboutsummaryrefslogtreecommitdiff
path: root/gdb/tui/tui-io.c
diff options
context:
space:
mode:
authorPatrick Palka <patrick@parcs.ath.cx>2014-11-23 14:03:39 +0400
committerJoel Brobecker <brobecker@adacore.com>2014-11-23 14:04:09 +0400
commitd64e57faa89ba4de0ebacdc30fbee5d19310950c (patch)
treedb4b32e5e7e98b16bdf8ccb31e64dbf171dc61a0 /gdb/tui/tui-io.c
parent6f9d33d89858fce0278af93658fcaef8d76f33cb (diff)
downloadgdb-d64e57faa89ba4de0ebacdc30fbee5d19310950c.zip
gdb-d64e57faa89ba4de0ebacdc30fbee5d19310950c.tar.gz
gdb-d64e57faa89ba4de0ebacdc30fbee5d19310950c.tar.bz2
Fix the processing of Meta-key commands in TUI
This patch fixes the annoying bug where key sequences such as Alt_F or Alt_B (go forward or backwards by a word) do not behave promptly in TUI. You have to press a third key in order for the key sequence to register. This is mostly ncurses' fault. Calling wgetch() normally causes ncurses to read only a single key from stdin. However if the key read is the start-sequence key (^[ a.k.a. ESC) then wgetch() reads TWO keys from stdin, storing the 2nd key into an internal FIFO buffer and returning the start-sequence key. The extraneous read of the 2nd key makes us miss its corresponding stdin event, so the event loop blocks until a third key is pressed. This explains why such key sequences do not behave promptly in TUI. To fix this issue, we must somehow compensate for the missed stdin event corresponding to the 2nd byte of a key sequence. This patch achieves this by hacking up the stdin event handler to conditionally execute the readline callback multiple times in a row. This is done via a new global variable, call_stdin_event_handler_again_p, which is set from tui_getc() when we receive a start-sequence key and notice extra pending input in the ncurses buffer. Tested on x86_64-unknown-linux-gnu. gdb/ChangeLog: * event-top.h (call_stdin_event_handler_again_p): Declare. * event-top.c (call_stdin_event_handler_again_p): Define. (stdin_event_handler): Use it. * tui/tui-io.c (tui_getc): Prepare to call the stdin event handler again if there is pending input following a start sequence.
Diffstat (limited to 'gdb/tui/tui-io.c')
-rw-r--r--gdb/tui/tui-io.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
index 601d278..aa1d1c7 100644
--- a/gdb/tui/tui-io.c
+++ b/gdb/tui/tui-io.c
@@ -691,7 +691,33 @@ tui_getc (FILE *fp)
TUI_CMD_WIN->detail.command_info.curch = 0;
if (ch == KEY_BACKSPACE)
return '\b';
-
+
+ if (async_command_editing_p && key_is_start_sequence (ch))
+ {
+ int ch_pending;
+
+ nodelay (w, TRUE);
+ ch_pending = wgetch (w);
+ nodelay (w, FALSE);
+
+ /* If we have pending input following a start sequence, call the stdin
+ event handler again because ncurses may have already read and stored
+ the input into its internal buffer, meaning that we won't get an stdin
+ event for it. If we don't compensate for this missed stdin event, key
+ sequences as Alt_F (^[f) will not behave promptly.
+
+ (We only compensates for the missed 2nd byte of a key sequence because
+ 2-byte sequences are by far the most commonly used. ncurses may have
+ buffered a larger, 3+-byte key sequence though it remains to be seen
+ whether it is useful to compensate for all the bytes of such
+ sequences.) */
+ if (ch_pending != ERR)
+ {
+ ungetch (ch_pending);
+ call_stdin_event_handler_again_p = 1;
+ }
+ }
+
return ch;
}