Do not block when waiting for next event if we have pending input
Handle next event should never block if we have already accumulated input that we want to process. As we can accumulate new input in lots of places (everytime we run a shell process for example, we might end up reading input keys. That can be triggered during the mode line generation which takes place during display of the window) Fixes #1804
This commit is contained in:
parent
43f50c0852
commit
299e22ca7c
|
@ -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<DisplayLine> choices, BufferCoord anchor, MenuStyle style);
|
||||
void menu_select(int selected);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue
Block a user