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);
}
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)
{
if (mode == EventMode::Normal)
{
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())
if (mode == EventMode::Urgent)
{
Key key = m_ui->get_key();
if (key == ctrl('c'))
killpg(getpgrp(), SIGINT);
else
m_pending_keys.push_back(key);
}
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();
}
}
context().window().forget_timestamp();
}
}
}
catch (Kakoune::runtime_error& 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);
}
}
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)

View File

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

View File

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

View File

@ -35,7 +35,7 @@ public:
void redraw_clients() 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(StringView name);

View File

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

View File

@ -12,23 +12,23 @@ namespace Kakoune
enum class EventMode
{
Normal = 1 << 0,
Urgent = 1 << 1
Normal,
Urgent,
Pending
};
template<> struct WithBitOps<EventMode> : std::true_type {};
class FDWatcher
{
public:
using Callback = std::function<void (FDWatcher& watcher, EventMode mode)>;
FDWatcher(int fd, Callback callback);
FDWatcher(const FDWatcher&) = delete;
FDWatcher& operator=(const FDWatcher&) = delete;
~FDWatcher();
int fd() const { return m_fd; }
void run(EventMode mode);
private:
FDWatcher(const FDWatcher&) = delete;
int m_fd;
Callback m_callback;
@ -44,6 +44,8 @@ public:
Timer(TimePoint date, Callback callback,
EventMode mode = EventMode::Normal);
Timer(const Timer&) = delete;
Timer& operator=(const Timer&) = delete;
~Timer();
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))
{
event_manager.handle_next_events(EventMode::Normal);
client_manager.handle_available_inputs();
client_manager.handle_pending_inputs();
client_manager.clear_mode_trashes();
buffer_manager.clear_buffer_trash();
client_manager.redraw_clients();