move input watching responsibility into UserInterface implementations
This commit is contained in:
parent
d2f0e2de66
commit
310ec1f791
|
@ -27,7 +27,7 @@ String ClientManager::generate_name() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
|
void ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
|
||||||
int event_fd, const String& init_commands)
|
const String& init_commands)
|
||||||
{
|
{
|
||||||
Buffer& buffer = **BufferManager::instance().begin();
|
Buffer& buffer = **BufferManager::instance().begin();
|
||||||
m_clients.emplace_back(new Client{std::move(ui), get_unused_window_for_buffer(buffer),
|
m_clients.emplace_back(new Client{std::move(ui), get_unused_window_for_buffer(buffer),
|
||||||
|
@ -47,11 +47,10 @@ void ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
|
||||||
catch (Kakoune::client_removed&)
|
catch (Kakoune::client_removed&)
|
||||||
{
|
{
|
||||||
m_clients.pop_back();
|
m_clients.pop_back();
|
||||||
close(event_fd);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new FDWatcher(event_fd, [input_handler, context, this](FDWatcher& watcher) {
|
context->ui().set_input_callback([input_handler, context, this]() {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
input_handler->handle_available_inputs(*context);
|
input_handler->handle_available_inputs(*context);
|
||||||
|
@ -64,8 +63,6 @@ void ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
|
||||||
catch (Kakoune::client_removed&)
|
catch (Kakoune::client_removed&)
|
||||||
{
|
{
|
||||||
ClientManager::instance().remove_client_by_context(*context);
|
ClientManager::instance().remove_client_by_context(*context);
|
||||||
close(watcher.fd());
|
|
||||||
delete &watcher;
|
|
||||||
}
|
}
|
||||||
ClientManager::instance().redraw_clients();
|
ClientManager::instance().redraw_clients();
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,7 +13,7 @@ class ClientManager : public Singleton<ClientManager>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void create_client(std::unique_ptr<UserInterface>&& ui,
|
void create_client(std::unique_ptr<UserInterface>&& ui,
|
||||||
int event_fd, const String& init_cmd);
|
const String& init_cmd);
|
||||||
|
|
||||||
bool empty() const { return m_clients.empty(); }
|
bool empty() const { return m_clients.empty(); }
|
||||||
size_t count() const { return m_clients.size(); }
|
size_t count() const { return m_clients.size(); }
|
||||||
|
|
|
@ -517,6 +517,8 @@ public:
|
||||||
|
|
||||||
DisplayCoord dimensions() override { return { 0, 0 }; }
|
DisplayCoord dimensions() override { return { 0, 0 }; }
|
||||||
|
|
||||||
|
void set_input_callback(InputCallback callback) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const KeyList& m_keys;
|
const KeyList& m_keys;
|
||||||
size_t m_pos;
|
size_t m_pos;
|
||||||
|
|
13
src/main.cc
13
src/main.cc
|
@ -685,7 +685,7 @@ void create_local_client(const String& init_command)
|
||||||
|
|
||||||
UserInterface* ui = new LocalNCursesUI{};
|
UserInterface* ui = new LocalNCursesUI{};
|
||||||
ClientManager::instance().create_client(
|
ClientManager::instance().create_client(
|
||||||
std::unique_ptr<UserInterface>{ui}, 0, init_command);
|
std::unique_ptr<UserInterface>{ui}, init_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteClient* connect_to(const String& pid, const String& init_command)
|
RemoteClient* connect_to(const String& pid, const String& init_command)
|
||||||
|
@ -703,17 +703,6 @@ RemoteClient* connect_to(const String& pid, const String& init_command)
|
||||||
NCursesUI* ui = new NCursesUI{};
|
NCursesUI* ui = new NCursesUI{};
|
||||||
RemoteClient* remote_client = new RemoteClient{sock, ui, init_command};
|
RemoteClient* remote_client = new RemoteClient{sock, ui, init_command};
|
||||||
|
|
||||||
new FDWatcher{0, [=](FDWatcher& ev) {
|
|
||||||
try
|
|
||||||
{
|
|
||||||
remote_client->write_next_key();
|
|
||||||
}
|
|
||||||
catch (Kakoune::runtime_error& error)
|
|
||||||
{
|
|
||||||
ui->print_status(error.description(), -1);
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
|
|
||||||
return remote_client;
|
return remote_client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ void on_sigint(int)
|
||||||
}
|
}
|
||||||
|
|
||||||
NCursesUI::NCursesUI()
|
NCursesUI::NCursesUI()
|
||||||
|
: m_stdin_watcher{0, [this](FDWatcher&){ if (m_input_callback) m_input_callback(); }}
|
||||||
{
|
{
|
||||||
//setlocale(LC_CTYPE, "");
|
//setlocale(LC_CTYPE, "");
|
||||||
initscr();
|
initscr();
|
||||||
|
@ -468,4 +469,9 @@ DisplayCoord NCursesUI::dimensions()
|
||||||
return m_dimensions;
|
return m_dimensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NCursesUI::set_input_callback(InputCallback callback)
|
||||||
|
{
|
||||||
|
m_input_callback = std::move(callback);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "user_interface.hh"
|
#include "user_interface.hh"
|
||||||
#include "display_buffer.hh"
|
#include "display_buffer.hh"
|
||||||
|
#include "event_manager.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
@ -35,6 +36,8 @@ public:
|
||||||
const DisplayCoord& anchor, MenuStyle style) override;
|
const DisplayCoord& anchor, MenuStyle style) override;
|
||||||
void info_hide() override;
|
void info_hide() override;
|
||||||
|
|
||||||
|
void set_input_callback(InputCallback callback) override;
|
||||||
|
|
||||||
DisplayCoord dimensions() override;
|
DisplayCoord dimensions() override;
|
||||||
private:
|
private:
|
||||||
friend void on_term_resize(int);
|
friend void on_term_resize(int);
|
||||||
|
@ -55,6 +58,9 @@ private:
|
||||||
int m_menu_bg;
|
int m_menu_bg;
|
||||||
|
|
||||||
WINDOW* m_info_win = nullptr;
|
WINDOW* m_info_win = nullptr;
|
||||||
|
|
||||||
|
FDWatcher m_stdin_watcher;
|
||||||
|
InputCallback m_input_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,26 +187,30 @@ public:
|
||||||
Key get_key() override;
|
Key get_key() override;
|
||||||
DisplayCoord dimensions() override;
|
DisplayCoord dimensions() override;
|
||||||
|
|
||||||
|
void set_input_callback(InputCallback callback) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_socket;
|
FDWatcher m_socket_watcher;
|
||||||
DisplayCoord m_dimensions;
|
DisplayCoord m_dimensions;
|
||||||
|
InputCallback m_input_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
RemoteUI::RemoteUI(int socket)
|
RemoteUI::RemoteUI(int socket)
|
||||||
: m_socket(socket)
|
: m_socket_watcher(socket, [this](FDWatcher&) { if (m_input_callback) m_input_callback(); })
|
||||||
{
|
{
|
||||||
write_debug("remote client connected: " + int_to_str(m_socket));
|
write_debug("remote client connected: " + int_to_str(m_socket_watcher.fd()));
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteUI::~RemoteUI()
|
RemoteUI::~RemoteUI()
|
||||||
{
|
{
|
||||||
write_debug("remote client disconnected: " + int_to_str(m_socket));
|
write_debug("remote client disconnected: " + int_to_str(m_socket_watcher.fd()));
|
||||||
|
close(m_socket_watcher.fd());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteUI::print_status(const String& status, CharCount cursor_pos)
|
void RemoteUI::print_status(const String& status, CharCount cursor_pos)
|
||||||
{
|
{
|
||||||
Message msg(m_socket);
|
Message msg(m_socket_watcher.fd());
|
||||||
msg.write(RemoteUIMsg::PrintStatus);
|
msg.write(RemoteUIMsg::PrintStatus);
|
||||||
msg.write(status);
|
msg.write(status);
|
||||||
msg.write(cursor_pos);
|
msg.write(cursor_pos);
|
||||||
|
@ -215,7 +219,7 @@ void RemoteUI::print_status(const String& status, CharCount cursor_pos)
|
||||||
void RemoteUI::menu_show(const memoryview<String>& choices,
|
void RemoteUI::menu_show(const memoryview<String>& choices,
|
||||||
const DisplayCoord& anchor, MenuStyle style)
|
const DisplayCoord& anchor, MenuStyle style)
|
||||||
{
|
{
|
||||||
Message msg(m_socket);
|
Message msg(m_socket_watcher.fd());
|
||||||
msg.write(RemoteUIMsg::MenuShow);
|
msg.write(RemoteUIMsg::MenuShow);
|
||||||
msg.write(choices);
|
msg.write(choices);
|
||||||
msg.write(anchor);
|
msg.write(anchor);
|
||||||
|
@ -224,21 +228,21 @@ void RemoteUI::menu_show(const memoryview<String>& choices,
|
||||||
|
|
||||||
void RemoteUI::menu_select(int selected)
|
void RemoteUI::menu_select(int selected)
|
||||||
{
|
{
|
||||||
Message msg(m_socket);
|
Message msg(m_socket_watcher.fd());
|
||||||
msg.write(RemoteUIMsg::MenuSelect);
|
msg.write(RemoteUIMsg::MenuSelect);
|
||||||
msg.write(selected);
|
msg.write(selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteUI::menu_hide()
|
void RemoteUI::menu_hide()
|
||||||
{
|
{
|
||||||
Message msg(m_socket);
|
Message msg(m_socket_watcher.fd());
|
||||||
msg.write(RemoteUIMsg::MenuHide);
|
msg.write(RemoteUIMsg::MenuHide);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteUI::info_show(const String& content,
|
void RemoteUI::info_show(const String& content,
|
||||||
const DisplayCoord& anchor, MenuStyle style)
|
const DisplayCoord& anchor, MenuStyle style)
|
||||||
{
|
{
|
||||||
Message msg(m_socket);
|
Message msg(m_socket_watcher.fd());
|
||||||
msg.write(RemoteUIMsg::InfoShow);
|
msg.write(RemoteUIMsg::InfoShow);
|
||||||
msg.write(content);
|
msg.write(content);
|
||||||
msg.write(anchor);
|
msg.write(anchor);
|
||||||
|
@ -247,14 +251,14 @@ void RemoteUI::info_show(const String& content,
|
||||||
|
|
||||||
void RemoteUI::info_hide()
|
void RemoteUI::info_hide()
|
||||||
{
|
{
|
||||||
Message msg(m_socket);
|
Message msg(m_socket_watcher.fd());
|
||||||
msg.write(RemoteUIMsg::InfoHide);
|
msg.write(RemoteUIMsg::InfoHide);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteUI::draw(const DisplayBuffer& display_buffer,
|
void RemoteUI::draw(const DisplayBuffer& display_buffer,
|
||||||
const String& mode_line)
|
const String& mode_line)
|
||||||
{
|
{
|
||||||
Message msg(m_socket);
|
Message msg(m_socket_watcher.fd());
|
||||||
msg.write(RemoteUIMsg::Draw);
|
msg.write(RemoteUIMsg::Draw);
|
||||||
msg.write(display_buffer);
|
msg.write(display_buffer);
|
||||||
msg.write(mode_line);
|
msg.write(mode_line);
|
||||||
|
@ -267,18 +271,19 @@ bool RemoteUI::is_key_available()
|
||||||
timeval tv;
|
timeval tv;
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
|
|
||||||
|
int sock = m_socket_watcher.fd();
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(m_socket, &rfds);
|
FD_SET(sock, &rfds);
|
||||||
|
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
int res = select(m_socket+1, &rfds, NULL, NULL, &tv);
|
int res = select(sock+1, &rfds, NULL, NULL, &tv);
|
||||||
return res == 1;
|
return res == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key RemoteUI::get_key()
|
Key RemoteUI::get_key()
|
||||||
{
|
{
|
||||||
Key key = read<Key>(m_socket);
|
Key key = read<Key>(m_socket_watcher.fd());
|
||||||
if (key.modifiers == resize_modifier)
|
if (key.modifiers == resize_modifier)
|
||||||
{
|
{
|
||||||
m_dimensions = { (int)(key.key >> 16), (int)(key.key & 0xFFFF) };
|
m_dimensions = { (int)(key.key >> 16), (int)(key.key & 0xFFFF) };
|
||||||
|
@ -292,6 +297,11 @@ DisplayCoord RemoteUI::dimensions()
|
||||||
return m_dimensions;
|
return m_dimensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoteUI::set_input_callback(InputCallback callback)
|
||||||
|
{
|
||||||
|
m_input_callback = std::move(callback);
|
||||||
|
}
|
||||||
|
|
||||||
RemoteClient::RemoteClient(int socket, UserInterface* ui,
|
RemoteClient::RemoteClient(int socket, UserInterface* ui,
|
||||||
const String& init_command)
|
const String& init_command)
|
||||||
: m_ui(ui), m_dimensions(ui->dimensions()),
|
: m_ui(ui), m_dimensions(ui->dimensions()),
|
||||||
|
@ -301,6 +311,8 @@ RemoteClient::RemoteClient(int socket, UserInterface* ui,
|
||||||
msg.write(init_command);
|
msg.write(init_command);
|
||||||
Key key{ resize_modifier, Codepoint(((int)m_dimensions.line << 16) | (int)m_dimensions.column) };
|
Key key{ resize_modifier, Codepoint(((int)m_dimensions.line << 16) | (int)m_dimensions.column) };
|
||||||
msg.write(key);
|
msg.write(key);
|
||||||
|
|
||||||
|
m_ui->set_input_callback([this]{ write_next_key(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteClient::process_next_message()
|
void RemoteClient::process_next_message()
|
||||||
|
@ -370,12 +382,12 @@ void RemoteClient::write_next_key()
|
||||||
void handle_remote(FDWatcher& watcher)
|
void handle_remote(FDWatcher& watcher)
|
||||||
{
|
{
|
||||||
int socket = watcher.fd();
|
int socket = watcher.fd();
|
||||||
|
delete &watcher;
|
||||||
String init_command = read<String>(socket);
|
String init_command = read<String>(socket);
|
||||||
|
|
||||||
RemoteUI* ui = new RemoteUI{socket};
|
RemoteUI* ui = new RemoteUI{socket};
|
||||||
delete &watcher;
|
|
||||||
ClientManager::instance().create_client(
|
ClientManager::instance().create_client(
|
||||||
std::unique_ptr<UserInterface>{ui}, socket, init_command);
|
std::unique_ptr<UserInterface>{ui}, init_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ enum class MenuStyle
|
||||||
Inline
|
Inline
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using InputCallback = std::function<void()>;
|
||||||
|
|
||||||
class UserInterface : public SafeCountable
|
class UserInterface : public SafeCountable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -39,6 +41,8 @@ public:
|
||||||
virtual DisplayCoord dimensions() = 0;
|
virtual DisplayCoord dimensions() = 0;
|
||||||
virtual bool is_key_available() = 0;
|
virtual bool is_key_available() = 0;
|
||||||
virtual Key get_key() = 0;
|
virtual Key get_key() = 0;
|
||||||
|
|
||||||
|
virtual void set_input_callback(InputCallback callback) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user