diff --git a/src/client.cc b/src/client.cc index 55fba617..af5ae20f 100644 --- a/src/client.cc +++ b/src/client.cc @@ -55,15 +55,14 @@ Client::~Client() m_window->set_client(nullptr); } -void Client::process_pending_inputs() +bool Client::process_pending_inputs() { - try + const bool debug_keys = (bool)(context().options()["debug"].get() & DebugFlags::Keys); + // steal keys as we might receive new keys while handling them. + Vector keys = std::move(m_pending_keys); + for (auto& key : keys) { - const bool debug_keys = (bool)(context().options()["debug"].get() & DebugFlags::Keys); - - // steal keys as we might receive new keys while handling them. - Vector keys = std::move(m_pending_keys); - for (auto& key : keys) + try { if (debug_keys) write_to_debug_buffer(format("Client '{}' got key '{}'", @@ -81,12 +80,13 @@ void Client::process_pending_inputs() else m_input_handler.handle_key(key); } + catch (Kakoune::runtime_error& error) + { + context().print_status({ error.what().str(), get_face("Error") }); + context().hooks().run_hook("RuntimeError", error.what(), context()); + } } - catch (Kakoune::runtime_error& error) - { - context().print_status({ error.what().str(), get_face("Error") }); - context().hooks().run_hook("RuntimeError", error.what(), context()); - } + return not keys.empty(); } void Client::print_status(DisplayLine status_line, bool immediate) diff --git a/src/client.hh b/src/client.hh index 2ee7a867..7b2b36bd 100644 --- a/src/client.hh +++ b/src/client.hh @@ -34,7 +34,7 @@ public: Client(Client&&) = delete; - void process_pending_inputs(); + bool process_pending_inputs(); void menu_show(Vector choices, BufferCoord anchor, MenuStyle style); void menu_select(int selected); diff --git a/src/client_manager.cc b/src/client_manager.cc index a77d7d13..8edaeb2f 100644 --- a/src/client_manager.cc +++ b/src/client_manager.cc @@ -63,8 +63,15 @@ Client* ClientManager::create_client(std::unique_ptr&& ui, void ClientManager::process_pending_inputs() const { - for (auto& client : m_clients) - client->process_pending_inputs(); + while (true) + { + bool had_input = false; + for (auto& client : m_clients) + had_input = client->process_pending_inputs() or had_input; + + if (not had_input) + break; + } } void ClientManager::remove_client(Client& client, bool graceful)