From d9729cc29eb717aae2c68ced24d4b04d4c2ea4cf Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sun, 28 Oct 2012 09:26:54 +0100 Subject: [PATCH] Handle all available input before redrawing --- src/commands.cc | 5 ++--- src/input_handler.cc | 11 +++++++---- src/input_handler.hh | 2 +- src/main.cc | 4 ++-- src/ncurses.cc | 10 ++++++++++ src/ncurses.hh | 1 + src/remote.cc | 14 ++++++++++++++ src/remote.hh | 2 ++ src/user_interface.hh | 1 + 9 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/commands.cc b/src/commands.cc index 45d4d37e..392fa500 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -654,7 +654,7 @@ public: assert(m_pos < m_keys.size()); return m_keys[m_pos++]; } - bool has_key_left() const { return m_pos < m_keys.size(); } + bool is_key_available() override { return m_pos < m_keys.size(); } void print_status(const String& , CharCount) override {} void draw(const DisplayBuffer&, const String&) override {} @@ -681,8 +681,7 @@ void exec_keys(const KeyList& keys, Context& context) scoped_edition edition(context.editor()); Context new_context(batch_input_handler, context.editor(), batch_ui); - while (batch_ui.has_key_left()) - batch_input_handler.handle_next_input(new_context); + batch_input_handler.handle_available_inputs(new_context); context.change_editor(new_context.editor()); } diff --git a/src/input_handler.cc b/src/input_handler.cc index 33f8d947..56879e98 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -625,11 +625,14 @@ void InputHandler::on_next_key(KeyCallback callback) m_mode.reset(new InputModes::NextKey(*this, callback)); } -void InputHandler::handle_next_input(Context& context) +void InputHandler::handle_available_inputs(Context& context) { - Key key = context.ui().get_key(); - if (key != Key::Invalid) - m_mode->on_key(key, context); + while (context.ui().is_key_available()) + { + Key key = context.ui().get_key(); + if (key != Key::Invalid) + m_mode->on_key(key, context); + } context.draw_ifn(); } diff --git a/src/input_handler.hh b/src/input_handler.hh index 3e35de6d..98762dfb 100644 --- a/src/input_handler.hh +++ b/src/input_handler.hh @@ -36,7 +36,7 @@ public: void on_next_key(KeyCallback callback); - void handle_next_input(Context& context); + void handle_available_inputs(Context& context); private: friend class InputMode; diff --git a/src/main.cc b/src/main.cc index c6479077..f33b5f7d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -529,7 +529,7 @@ Client create_local_client(const String& file) EventManager::instance().watch(0, [=](int) { try { - input_handler->handle_next_input(*context); + input_handler->handle_available_inputs(*context); } catch (Kakoune::runtime_error& error) { @@ -573,7 +573,7 @@ void setup_server() EventManager::instance().watch(sock, [=](int) { try { - input_handler->handle_next_input(*context); + input_handler->handle_available_inputs(*context); } catch (Kakoune::runtime_error& error) { diff --git a/src/ncurses.cc b/src/ncurses.cc index a7c2a3e5..1cbfbf1f 100644 --- a/src/ncurses.cc +++ b/src/ncurses.cc @@ -211,6 +211,16 @@ struct getch_iterator getch_iterator& operator++(int) { return *this; } }; +bool NCursesUI::is_key_available() +{ + timeout(0); + const int c = getch(); + if (c != ERR) + ungetch(c); + timeout(-1); + return c != ERR; +} + Key NCursesUI::get_key() { const unsigned c = getch(); diff --git a/src/ncurses.hh b/src/ncurses.hh index 287d8a47..9267191b 100644 --- a/src/ncurses.hh +++ b/src/ncurses.hh @@ -23,6 +23,7 @@ public: const String& status_line) override; void print_status(const String& status, CharCount cursor_pos) override; + bool is_key_available() override; Key get_key() override; void menu_show(const memoryview& choices, diff --git a/src/remote.cc b/src/remote.cc index 7bd99d59..a5bd87b9 100644 --- a/src/remote.cc +++ b/src/remote.cc @@ -193,6 +193,20 @@ void RemoteUI::draw(const DisplayBuffer& display_buffer, static const Key::Modifiers resize_modifier = (Key::Modifiers)0x80; +bool RemoteUI::is_key_available() +{ + timeval tv; + fd_set rfds; + + FD_ZERO(&rfds); + FD_SET(m_socket, &rfds); + + tv.tv_sec = 0; + tv.tv_usec = 0; + int res = select(m_socket+1, &rfds, NULL, NULL, &tv); + return res == 1; +} + Key RemoteUI::get_key() { Key key = read(m_socket); diff --git a/src/remote.hh b/src/remote.hh index f4b062c4..8a3ca470 100644 --- a/src/remote.hh +++ b/src/remote.hh @@ -24,6 +24,8 @@ public: void menu_hide() override; void draw(const DisplayBuffer& display_buffer, const String& status_line) override; + + bool is_key_available() override; Key get_key() override; DisplayCoord dimensions() override; diff --git a/src/user_interface.hh b/src/user_interface.hh index b1c116dc..91e5c47c 100644 --- a/src/user_interface.hh +++ b/src/user_interface.hh @@ -31,6 +31,7 @@ public: virtual void draw(const DisplayBuffer& display_buffer, const String& status_line) = 0; virtual DisplayCoord dimensions() = 0; + virtual bool is_key_available() = 0; virtual Key get_key() = 0; };