From patchwork Sun Nov 23 10:08:17 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Brobecker X-Patchwork-Id: 3855 Received: (qmail 11717 invoked by alias); 23 Nov 2014 10:08:24 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 11708 invoked by uid 89); 23 Nov 2014 10:08:22 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Sun, 23 Nov 2014 10:08:20 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 1B1141167FB; Sun, 23 Nov 2014 05:08:19 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id WdeAjesamdub; Sun, 23 Nov 2014 05:08:19 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 920591167E3; Sun, 23 Nov 2014 05:08:18 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id DC13240F79; Sun, 23 Nov 2014 14:08:17 +0400 (RET) Date: Sun, 23 Nov 2014 14:08:17 +0400 From: Joel Brobecker To: Patrick Palka Cc: Pedro Alves , gdb-patches@sourceware.org Subject: Re: [PATCH] Fix the processing of Meta-key commands in TUI Message-ID: <20141123100817.GG5774@adacore.com> References: <1408740286-29326-1-git-send-email-patrick@parcs.ath.cx> <53FF12FF.3020003@redhat.com> <53FF5534.3050209@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Patrick, > Attached is the patch that Pedro approved, augmented with a comment > describing the potential problem with 3+ byte sequences. I wonder if > someone could commit this for me? [...] > 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. Your patch did not apply to today's sources. The conflict was trivially resolved, but it would be good if you could check the "master" branch out, and rebuild, to make sure your fix was correctly pushed. Attached is what I did push. Thanks for the patch. From d64e57faa89ba4de0ebacdc30fbee5d19310950c Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Sun, 23 Nov 2014 14:03:39 +0400 Subject: [PATCH] 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. --- gdb/ChangeLog | 9 +++++++++ gdb/event-top.c | 13 ++++++++++++- gdb/event-top.h | 1 + gdb/tui/tui-io.c | 28 +++++++++++++++++++++++++++- 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e16f28f..326a0d6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,14 @@ 2014-11-23 Patrick Palka + * 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. + +2014-11-23 Patrick Palka + Pushed by Joel Brobecker * linux-fork.c (checkpoint_command): Print index of new checkpoint in response message. diff --git a/gdb/event-top.c b/gdb/event-top.c index 282c0fe..cb438ac 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -119,6 +119,11 @@ int exec_done_display_p = 0; read commands from. */ int input_fd; +/* Used by the stdin event handler to compensate for missed stdin events. + Setting this to a non-zero value inside an stdin callback makes the callback + run again. */ +int call_stdin_event_handler_again_p; + /* Signal handling variables. */ /* Each of these is a pointer to a function that the event loop will invoke if the corresponding signal has received. The real signal @@ -420,7 +425,13 @@ stdin_event_handler (int error, gdb_client_data client_data) quit_command ((char *) 0, stdin == instream); } else - (*call_readline) (client_data); + { + do + { + call_stdin_event_handler_again_p = 0; + (*call_readline) (client_data); + } while (call_stdin_event_handler_again_p != 0); + } } /* Re-enable stdin after the end of an execution command in diff --git a/gdb/event-top.h b/gdb/event-top.h index ac0d47b..919287e 100644 --- a/gdb/event-top.h +++ b/gdb/event-top.h @@ -61,6 +61,7 @@ extern void (*call_readline) (void *); extern void (*input_handler) (char *); extern int input_fd; extern void (*after_char_processing_hook) (void); +extern int call_stdin_event_handler_again_p; /* Wrappers for rl_callback_handler_remove and rl_callback_handler_install that keep track of whether the callback 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; } -- 1.9.1