From patchwork Fri Aug 22 20:44:46 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 2521 Received: (qmail 7103 invoked by alias); 22 Aug 2014 20:44:58 -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 7092 invoked by uid 89); 22 Aug 2014 20:44:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 X-HELO: mail-qc0-f170.google.com Received: from mail-qc0-f170.google.com (HELO mail-qc0-f170.google.com) (209.85.216.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Fri, 22 Aug 2014 20:44:56 +0000 Received: by mail-qc0-f170.google.com with SMTP id x3so11528079qcv.1 for ; Fri, 22 Aug 2014 13:44:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=bRWuJsPk4t7iMgtJbaKvZ0BTLO8yu/TNmqOffZ/Oze4=; b=eo2LGmsnrgfANKd6xpYbc4McaHwWo4umTmyNQUVgxaJhDEa31/5Mahv5FuJq7EHjsK zmeoiYw0HJFHfjeH3yDDcPcl5+MJt9w8x5jk43doiDuNWs170Fsk4MKPzJi5jAlKtQNE 63QDxcG7SlMlygnY7O5FFgZOLS2IEUMbRdLINOoxrldAMiJoJfmCt67gfEO4d83I/l6c xkp6u8tutFHhxFWHGx2JQlFW+iBBMTkYypF/WhNp4Q8whS4VFA/VyoGeRaQimR5zuc7q oE/blHMxHzzDiUucUzCMlNi7W1TkOspvFFrANol/gZdd0k1VGnn3hx54Tg0QTjr6a4GE yDig== X-Gm-Message-State: ALoCoQk7ub3e7h6JtrmPQVriDECIN5veXRLumYv8LRwbPWonk2p4ItVHhIGxTR8BrBqLGa7vX/lW X-Received: by 10.224.111.193 with SMTP id t1mr11483497qap.103.1408740293958; Fri, 22 Aug 2014 13:44:53 -0700 (PDT) Received: from localhost.localdomain (ool-4353af5c.dyn.optonline.net. [67.83.175.92]) by mx.google.com with ESMTPSA id i18sm57267507qar.29.2014.08.22.13.44.52 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 22 Aug 2014 13:44:53 -0700 (PDT) From: Patrick Palka To: gdb-patches@sourceware.org Cc: Patrick Palka Subject: [PATCH] Fix the processing of Meta-key commands in TUI Date: Fri, 22 Aug 2014 16:44:46 -0400 Message-Id: <1408740286-29326-1-git-send-email-patrick@parcs.ath.cx> X-IsSubscribed: yes 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 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/event-top.c | 13 ++++++++++++- gdb/event-top.h | 1 + gdb/tui/tui-io.c | 22 +++++++++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/gdb/event-top.c b/gdb/event-top.c index 833f49d..df1351d 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -120,6 +120,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 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 @@ -370,7 +375,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 2d05d45..c7b1224 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; extern void cli_command_loop (void *); diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c index a890678..32cc96e 100644 --- a/gdb/tui/tui-io.c +++ b/gdb/tui/tui-io.c @@ -695,7 +695,27 @@ 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 event + handler again. 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. */ + if (ch_pending != ERR) + { + ungetch (ch_pending); + call_stdin_event_handler_again_p = 1; + } + } + return ch; }