diff --git a/src/client.hh b/src/client.hh index b12bd854..d7db0391 100644 --- a/src/client.hh +++ b/src/client.hh @@ -38,6 +38,7 @@ public: Client(Client&&) = delete; bool process_pending_inputs(); + bool has_pending_inputs() const { return not m_pending_keys.empty(); } 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 c721f1db..9cb5f8e5 100644 --- a/src/client_manager.cc +++ b/src/client_manager.cc @@ -90,6 +90,11 @@ void ClientManager::process_pending_inputs() const } } +bool ClientManager::has_pending_inputs() const +{ + return contains_that(m_clients, [](auto&& c) { return c->has_pending_inputs(); }); +} + void ClientManager::remove_client(Client& client, bool graceful, int status) { auto it = find(m_clients, &client); diff --git a/src/client_manager.hh b/src/client_manager.hh index 5508b519..f6fb30e3 100644 --- a/src/client_manager.hh +++ b/src/client_manager.hh @@ -36,6 +36,7 @@ public: void redraw_clients() const; void process_pending_inputs() const; + bool has_pending_inputs() const; Client* get_client_ifp(StringView name); Client& get_client(StringView name); diff --git a/src/event_manager.cc b/src/event_manager.cc index 63f47858..cb69fc5e 100644 --- a/src/event_manager.cc +++ b/src/event_manager.cc @@ -69,7 +69,7 @@ EventManager::~EventManager() kak_assert(m_timers.empty()); } -void EventManager::handle_next_events(EventMode mode, sigset_t* sigmask) +void EventManager::handle_next_events(EventMode mode, sigset_t* sigmask, bool block) { int max_fd = 0; fd_set rfds, wfds, efds; @@ -92,7 +92,7 @@ void EventManager::handle_next_events(EventMode mode, sigset_t* sigmask) bool with_timeout = false; timespec ts{}; - if (not m_timers.empty()) + if (block and not m_timers.empty()) { auto next_date = (*std::min_element( m_timers.begin(), m_timers.end(), [](Timer* lhs, Timer* rhs) { @@ -109,7 +109,7 @@ void EventManager::handle_next_events(EventMode mode, sigset_t* sigmask) } } int res = pselect(max_fd + 1, &rfds, &wfds, &efds, - with_timeout ? &ts : nullptr, sigmask); + not block or with_timeout ? &ts : nullptr, sigmask); // copy forced fds *after* select, so that signal handlers can write to // m_forced_fd, interupt select, and directly be serviced. diff --git a/src/event_manager.hh b/src/event_manager.hh index 5d8c1ca5..857cb863 100644 --- a/src/event_manager.hh +++ b/src/event_manager.hh @@ -86,7 +86,7 @@ public: EventManager(); ~EventManager(); - void handle_next_events(EventMode mode, sigset_t* sigmask = nullptr); + void handle_next_events(EventMode mode, sigset_t* sigmask = nullptr, bool block = true); // force the watchers associated with fd to be executed // on next handle_next_events call. diff --git a/src/main.cc b/src/main.cc index ad5646f8..e98a09b4 100644 --- a/src/main.cc +++ b/src/main.cc @@ -683,7 +683,8 @@ int run_server(StringView session, StringView server_init, (flags & ServerFlags::Daemon))) { client_manager.redraw_clients(); - event_manager.handle_next_events(EventMode::Normal); + event_manager.handle_next_events(EventMode::Normal, nullptr, + not client_manager.has_pending_inputs()); client_manager.process_pending_inputs(); client_manager.clear_client_trash(); client_manager.clear_window_trash();