Rework client pending key handling, fix insert/normal timers

This commit is contained in:
Maxime Coste 2014-11-29 20:14:52 +00:00
parent 77e2e8a31e
commit a3b3001d8f
7 changed files with 40 additions and 31 deletions

View File

@ -38,32 +38,45 @@ Client::~Client()
m_window->options().unregister_watcher(*this); m_window->options().unregister_watcher(*this);
} }
Optional<Key> Client::get_next_key(EventMode mode)
{
if (not m_pending_keys.empty())
{
Key key = m_pending_keys.front();
m_pending_keys.erase(m_pending_keys.begin());
return key;
}
if (mode != EventMode::Pending and m_ui->is_key_available())
return m_ui->get_key();
return {};
}
void Client::handle_available_input(EventMode mode) void Client::handle_available_input(EventMode mode)
{ {
if (mode == EventMode::Normal) if (mode == EventMode::Urgent)
{
try
{
for (auto& key : m_pending_keys)
{
m_input_handler.handle_key(key);
m_input_handler.clear_mode_trash();
}
m_pending_keys.clear();
while (m_ui->is_key_available())
{ {
Key key = m_ui->get_key(); Key key = m_ui->get_key();
if (key == ctrl('c')) if (key == ctrl('c'))
killpg(getpgrp(), SIGINT); killpg(getpgrp(), SIGINT);
else
m_pending_keys.push_back(key);
}
else else
{ {
m_input_handler.handle_key(key); try
{
while (Optional<Key> key = get_next_key(mode))
{
if (*key == ctrl('c'))
killpg(getpgrp(), SIGINT);
else
{
m_input_handler.handle_key(*key);
m_input_handler.clear_mode_trash(); m_input_handler.clear_mode_trash();
}
}
context().window().forget_timestamp(); context().window().forget_timestamp();
} }
}
}
catch (Kakoune::runtime_error& error) catch (Kakoune::runtime_error& error)
{ {
context().print_status({ error.what(), get_face("Error") }); context().print_status({ error.what(), get_face("Error") });
@ -74,14 +87,6 @@ void Client::handle_available_input(EventMode mode)
ClientManager::instance().remove_client(*this); ClientManager::instance().remove_client(*this);
} }
} }
else
{
Key key = m_ui->get_key();
if (key == ctrl('c'))
killpg(getpgrp(), SIGINT);
else
m_pending_keys.push_back(key);
}
} }
void Client::print_status(DisplayLine status_line) void Client::print_status(DisplayLine status_line)

View File

@ -55,6 +55,8 @@ public:
private: private:
void on_option_changed(const Option& option) override; void on_option_changed(const Option& option) override;
Optional<Key> get_next_key(EventMode mode);
DisplayLine generate_mode_line() const; DisplayLine generate_mode_line() const;
std::unique_ptr<UserInterface> m_ui; std::unique_ptr<UserInterface> m_ui;

View File

@ -57,10 +57,10 @@ Client* ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
return client; return client;
} }
void ClientManager::handle_available_inputs() const void ClientManager::handle_pending_inputs() const
{ {
for (auto& client : m_clients) for (auto& client : m_clients)
client->handle_available_input(EventMode::Normal); client->handle_available_input(EventMode::Pending);
} }
void ClientManager::remove_client(Client& client) void ClientManager::remove_client(Client& client)

View File

@ -35,7 +35,7 @@ public:
void redraw_clients() const; void redraw_clients() const;
void clear_mode_trashes() const; void clear_mode_trashes() const;
void handle_available_inputs() const; void handle_pending_inputs() const;
Client* get_client_ifp(StringView name); Client* get_client_ifp(StringView name);
Client& get_client(StringView name); Client& get_client(StringView name);

View File

@ -36,7 +36,7 @@ Timer::~Timer()
void Timer::run(EventMode mode) void Timer::run(EventMode mode)
{ {
if (mode & m_mode) if (mode == m_mode)
{ {
m_date = TimePoint::max(); m_date = TimePoint::max();
m_callback(*this); m_callback(*this);

View File

@ -12,23 +12,23 @@ namespace Kakoune
enum class EventMode enum class EventMode
{ {
Normal = 1 << 0, Normal,
Urgent = 1 << 1 Urgent,
Pending
}; };
template<> struct WithBitOps<EventMode> : std::true_type {};
class FDWatcher class FDWatcher
{ {
public: public:
using Callback = std::function<void (FDWatcher& watcher, EventMode mode)>; using Callback = std::function<void (FDWatcher& watcher, EventMode mode)>;
FDWatcher(int fd, Callback callback); FDWatcher(int fd, Callback callback);
FDWatcher(const FDWatcher&) = delete;
FDWatcher& operator=(const FDWatcher&) = delete;
~FDWatcher(); ~FDWatcher();
int fd() const { return m_fd; } int fd() const { return m_fd; }
void run(EventMode mode); void run(EventMode mode);
private: private:
FDWatcher(const FDWatcher&) = delete;
int m_fd; int m_fd;
Callback m_callback; Callback m_callback;
@ -44,6 +44,8 @@ public:
Timer(TimePoint date, Callback callback, Timer(TimePoint date, Callback callback,
EventMode mode = EventMode::Normal); EventMode mode = EventMode::Normal);
Timer(const Timer&) = delete;
Timer& operator=(const Timer&) = delete;
~Timer(); ~Timer();
TimePoint next_date() const { return m_date; } TimePoint next_date() const { return m_date; }

View File

@ -408,7 +408,7 @@ int run_server(StringView session, StringView init_command,
while (not terminate and (not client_manager.empty() or daemon)) while (not terminate and (not client_manager.empty() or daemon))
{ {
event_manager.handle_next_events(EventMode::Normal); event_manager.handle_next_events(EventMode::Normal);
client_manager.handle_available_inputs(); client_manager.handle_pending_inputs();
client_manager.clear_mode_trashes(); client_manager.clear_mode_trashes();
buffer_manager.clear_buffer_trash(); buffer_manager.clear_buffer_trash();
client_manager.redraw_clients(); client_manager.redraw_clients();