aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2025-04-20 12:57:07 +0530
committerAkshay Nair <phenax5@gmail.com>2025-05-02 16:15:17 +0530
commitb4b6a646b3a7a7f6c7e990c67f208b76f4b5f748 (patch)
tree7f18775a63594acf0187668af63766dd72b9f66f
parent75157006bf6f1176f64e87695343980b16908bb6 (diff)
downloadnull-browser-b4b6a646b3a7a7f6c7e990c67f208b76f4b5f748.tar.gz
null-browser-b4b6a646b3a7a7f6c7e990c67f208b76f4b5f748.zip
Refactor + expose managing mode to inside lua
Diffstat (limited to '')
-rw-r--r--config.lua10
-rw-r--r--lua/null-browser/api.lua7
-rw-r--r--spec/KeymapEvaluatorSpec.cpp35
-rw-r--r--spec/LuaRuntimeApiSpec.cpp67
-rw-r--r--src/LuaRuntime.hpp3
-rw-r--r--src/LuaRuntimeApi.hpp21
-rw-r--r--src/WindowActionRouter.cpp64
-rw-r--r--src/WindowActionRouter.hpp11
-rw-r--r--src/WindowMediator.cpp11
-rw-r--r--src/WindowMediator.hpp10
-rw-r--r--src/keymap/KeymapEvaluator.cpp31
-rw-r--r--src/keymap/KeymapEvaluator.hpp23
-rw-r--r--src/utils.hpp17
-rw-r--r--src/widgets/BrowserWindow.cpp17
-rw-r--r--src/widgets/BrowserWindow.hpp2
-rw-r--r--src/widgets/WebView.hpp4
16 files changed, 207 insertions, 126 deletions
diff --git a/config.lua b/config.lua
index 50f4fe4..e1b4308 100644
--- a/config.lua
+++ b/config.lua
@@ -22,6 +22,11 @@ web.set('close_window_when_no_views', true)
web.set('user_agent', 'MacOS | Safari - $500 edition')
web.set('downloads_dir', os.getenv('HOME') .. '/Downloads/firefox')
+-- Switch modes
+web.keymap.set_mode('n') -- Start in normal mode
+web.keymap.set('n', 'i', function() web.keymap.set_mode('i') end)
+web.keymap.set('i', '<esc>', function() web.keymap.set_mode('n') end)
+
web.event.add_listener('UrlChanged', {
callback = function(opts)
print('url change', web.inspect(opts));
@@ -35,10 +40,11 @@ local function trim(s)
end
local function to_url(url)
+ url = trim(url)
if string.match(url, "^https?://") then
- return trim(url)
+ return url
end
- return "https://" .. trim(url)
+ return "https://" .. url
end
-- Search
diff --git a/lua/null-browser/api.lua b/lua/null-browser/api.lua
index 59a702f..7a3efb1 100644
--- a/lua/null-browser/api.lua
+++ b/lua/null-browser/api.lua
@@ -1,3 +1,4 @@
+--- Internal api (unstable)
--- @type table
__internals = __internals
@@ -198,4 +199,10 @@ function web.search.previous(view_id) return __internals.search_previous(view_id
-- TODO: Documentation please
function web.view.open_devtools(view_id) return __internals.view_open_devtools(view_id) end
+-- TODO: Documentation please
+function web.keymap.set_mode(mode) return __internals.keymap_set_mode(mode) end
+
+-- TODO: Documentation please
+function web.keymap.get_mode() return __internals.keymap_get_mode() end
+
print("api loaded")
diff --git a/spec/KeymapEvaluatorSpec.cpp b/spec/KeymapEvaluatorSpec.cpp
index 0483e99..37f7ec8 100644
--- a/spec/KeymapEvaluatorSpec.cpp
+++ b/spec/KeymapEvaluatorSpec.cpp
@@ -13,9 +13,7 @@ private slots:
it("calls mapping") {
auto keymap_was_called = false;
KeymapEvaluator evaluator;
- evaluator.add_keymap(KeyMode::Normal, "<c-t>", [&keymap_was_called]() {
- keymap_was_called = true;
- });
+ evaluator.add_keymap("n", "<c-t>", [&keymap_was_called]() { keymap_was_called = true; });
evaluator.evaluate(Qt::ControlModifier, Qt::Key_T);
@@ -26,9 +24,7 @@ private slots:
it("does not call mapping") {
auto keymap_was_called = false;
KeymapEvaluator evaluator;
- evaluator.add_keymap(KeyMode::Normal, "<c-t>", [&keymap_was_called]() {
- keymap_was_called = true;
- });
+ evaluator.add_keymap("n", "<c-t>", [&keymap_was_called]() { keymap_was_called = true; });
evaluator.evaluate(Qt::ControlModifier, Qt::Key_K);
@@ -41,9 +37,7 @@ private slots:
it("calls mapping") {
auto keymap_was_called = false;
KeymapEvaluator evaluator;
- evaluator.add_keymap(KeyMode::Normal, "<c-t>a", [&keymap_was_called]() {
- keymap_was_called = true;
- });
+ evaluator.add_keymap("n", "<c-t>a", [&keymap_was_called]() { keymap_was_called = true; });
evaluator.evaluate(Qt::ControlModifier, Qt::Key_T);
evaluator.evaluate(Qt::NoModifier, Qt::Key_A);
@@ -55,9 +49,7 @@ private slots:
it("does not call mapping") {
auto keymap_was_called = false;
KeymapEvaluator evaluator;
- evaluator.add_keymap(KeyMode::Normal, "<c-t>a", [&keymap_was_called]() {
- keymap_was_called = true;
- });
+ evaluator.add_keymap("n", "<c-t>a", [&keymap_was_called]() { keymap_was_called = true; });
evaluator.evaluate(Qt::ControlModifier, Qt::Key_T);
@@ -68,9 +60,7 @@ private slots:
it("does not call mapping") {
auto keymap_was_called = false;
KeymapEvaluator evaluator;
- evaluator.add_keymap(KeyMode::Normal, "<c-t>a", [&keymap_was_called]() {
- keymap_was_called = true;
- });
+ evaluator.add_keymap("n", "<c-t>a", [&keymap_was_called]() { keymap_was_called = true; });
evaluator.evaluate(Qt::ControlModifier, Qt::Key_K);
@@ -81,9 +71,7 @@ private slots:
it("does not call mapping") {
auto keymap_was_called = false;
KeymapEvaluator evaluator;
- evaluator.add_keymap(KeyMode::Normal, "<c-t>a", [&keymap_was_called]() {
- keymap_was_called = true;
- });
+ evaluator.add_keymap("n", "<c-t>a", [&keymap_was_called]() { keymap_was_called = true; });
evaluator.evaluate(Qt::ControlModifier, Qt::Key_T);
evaluator.evaluate(Qt::NoModifier, Qt::Key_B);
@@ -95,9 +83,7 @@ private slots:
it("calls mapping") {
auto keymap_was_called = false;
KeymapEvaluator evaluator;
- evaluator.add_keymap(KeyMode::Normal, "<c-t>a", [&keymap_was_called]() {
- keymap_was_called = true;
- });
+ evaluator.add_keymap("n", "<c-t>a", [&keymap_was_called]() { keymap_was_called = true; });
evaluator.evaluate(Qt::ControlModifier, Qt::Key_T);
evaluator.evaluate(Qt::NoModifier, Qt::Key_B);
@@ -108,14 +94,11 @@ private slots:
}
// TODO: maybe fix this behavior
- context(
- "when partial mapped sequence is entered before an entire sequence");
+ context("when partial mapped sequence is entered before an entire sequence");
it("does not call mapping") {
auto keymap_was_called = false;
KeymapEvaluator evaluator;
- evaluator.add_keymap(KeyMode::Normal, "<c-t>a", [&keymap_was_called]() {
- keymap_was_called = true;
- });
+ evaluator.add_keymap("n", "<c-t>a", [&keymap_was_called]() { keymap_was_called = true; });
evaluator.evaluate(Qt::ControlModifier, Qt::Key_T);
evaluator.evaluate(Qt::ControlModifier, Qt::Key_T);
diff --git a/spec/LuaRuntimeApiSpec.cpp b/spec/LuaRuntimeApiSpec.cpp
index b7424ea..936244f 100644
--- a/spec/LuaRuntimeApiSpec.cpp
+++ b/spec/LuaRuntimeApiSpec.cpp
@@ -144,6 +144,73 @@ private slots:
QVERIFY(wait_for_lua_to_be_true("return not _G.event2_called"));
}
}
+
+ void lua_api_view_set_url() {
+ context("when called with a url and view id");
+ it("emits url_opened for the given view id") {
+ auto &lua = LuaRuntime::instance();
+ QSignalSpy url_opened(&lua, &LuaRuntime::url_opened);
+
+ lua.evaluate(R"(
+ web.view.set_url("https://updated-url.com", 42)
+ )");
+
+ QVERIFY(url_opened.wait());
+ QCOMPARE(url_opened.first()[0], "https://updated-url.com");
+ QCOMPARE(url_opened.first()[1], OpenType::OpenUrl);
+ QCOMPARE(url_opened.first()[2], 42);
+ }
+
+ context("when called with a url");
+ it("emits url_opened with the url and view id = 0") {
+ auto &lua = LuaRuntime::instance();
+ QSignalSpy url_opened(&lua, &LuaRuntime::url_opened);
+
+ lua.evaluate(R"(
+ web.view.set_url("https://updated-url.com")
+ )");
+
+ QVERIFY(url_opened.wait());
+ QCOMPARE(url_opened.first()[0], "https://updated-url.com");
+ QCOMPARE(url_opened.first()[1], OpenType::OpenUrl);
+ QCOMPARE(url_opened.first()[2], 0);
+ }
+
+ context("when called without a url");
+ it("emits url_opened with empty url and view id = 0") {
+ auto &lua = LuaRuntime::instance();
+ QSignalSpy url_opened(&lua, &LuaRuntime::url_opened);
+
+ lua.evaluate(R"(
+ web.view.set_url()
+ )");
+
+ QVERIFY(url_opened.wait());
+ QCOMPARE(url_opened.first()[0], "");
+ QCOMPARE(url_opened.first()[1], OpenType::OpenUrl);
+ QCOMPARE(url_opened.first()[2], 0);
+ }
+ }
+
+ void lua_api_view_current() {
+ context("when called without a window id");
+ it("emits url_opened for the given view id") {
+ auto &lua = LuaRuntime::instance();
+ QSignalSpy evaluation_completed_spy(&lua, &LuaRuntime::evaluation_completed);
+
+ lua.evaluate(R"(
+ return web.view.current()
+ )");
+ QVERIFY(evaluation_completed_spy.wait());
+
+ qDebug() << evaluation_completed_spy.first().first();
+
+ // QCOMPARE(evaluation_completed_spy.first().first(), 1);
+ // QCOMPARE(url_opened.first()[0], "https://updated-url.com");
+ // QCOMPARE(url_opened.first()[1], OpenType::OpenUrl);
+ // QCOMPARE(url_opened.first()[2], 42);
+ }
+ }
};
QTEST_REGISTER(LuaRuntimeApiSpec)
diff --git a/src/LuaRuntime.hpp b/src/LuaRuntime.hpp
index 0d05a1d..d7ec1ae 100644
--- a/src/LuaRuntime.hpp
+++ b/src/LuaRuntime.hpp
@@ -47,7 +47,8 @@ signals:
void history_back_requested(WebViewId webview_id, qsizetype history_index);
void history_forward_requested(WebViewId webview_id, qsizetype history_index);
- void keymap_added(QString mode, QString keyseq, std::function<void()>);
+ void keymap_add_requested(QString mode, QString keyseq, std::function<void()>);
+ void keymap_mode_update_requested(const QString &mode);
void url_opened(QString url, OpenType open_type, WebViewId webview_id);
void webview_closed(WebViewId webview_id);
void webview_selected(WebViewId webview_id);
diff --git a/src/LuaRuntimeApi.hpp b/src/LuaRuntimeApi.hpp
index 3b67f36..80e8bc2 100644
--- a/src/LuaRuntimeApi.hpp
+++ b/src/LuaRuntimeApi.hpp
@@ -64,7 +64,7 @@ int lua_api_keymap_set(lua_State *state) {
// TODO: Cleanup function ref on after keymap clear
auto &runtime = LuaRuntime::instance();
- emit runtime.keymap_added(mode, keyseq, action);
+ emit runtime.keymap_add_requested(mode, keyseq, action);
return 1;
}
@@ -224,24 +224,41 @@ int lua_api_search_get_text(lua_State *state) {
return 1;
}
+int lua_api_keymap_get_mode(lua_State *state) {
+ auto &router = WindowActionRouter::instance();
+ auto search_text = router.fetch_current_mode();
+ lua_pushstring(state, search_text.toStdString().c_str());
+ return 1;
+}
+
+int lua_api_keymap_set_mode(lua_State *state) {
+ const auto *mode = lua_tostring(state, 1);
+ auto &runtime = LuaRuntime::instance();
+ emit runtime.keymap_mode_update_requested(mode);
+ lua_pushnil(state);
+ return 1;
+}
+
// NOLINTNEXTLINE
static luaL_Reg internals_api[] = {
luaL_Reg{"event_add_listener", &lua_event_register},
luaL_Reg{"config_set", &lua_api_config_set},
luaL_Reg{"config_get", &lua_api_config_get},
luaL_Reg{"keymap_set", &lua_api_keymap_set},
+ luaL_Reg{"keymap_get_mode", &lua_api_keymap_get_mode},
+ luaL_Reg{"keymap_set_mode", &lua_api_keymap_set_mode},
luaL_Reg{"view_close", &lua_view_close},
luaL_Reg{"view_create", &lua_api_view_create},
luaL_Reg{"view_current", &lua_api_view_current},
luaL_Reg{"view_list", &lua_view_list},
luaL_Reg{"view_select", &lua_view_select},
luaL_Reg{"view_set_url", &lua_api_view_set_url},
+ luaL_Reg{"view_open_devtools", &lua_api_view_open_devtools},
luaL_Reg{"history_back", &lua_history_back},
luaL_Reg{"history_forward", &lua_history_forward},
luaL_Reg{"search_get_text", &lua_api_search_get_text},
luaL_Reg{"search_set_text", &lua_api_search_set_text},
luaL_Reg{"search_previous", &lua_api_search_previous},
luaL_Reg{"search_next", &lua_api_search_next},
- luaL_Reg{"view_open_devtools", &lua_api_view_open_devtools},
luaL_Reg{nullptr, nullptr},
};
diff --git a/src/WindowActionRouter.cpp b/src/WindowActionRouter.cpp
index 05d0218..424dda9 100644
--- a/src/WindowActionRouter.cpp
+++ b/src/WindowActionRouter.cpp
@@ -18,8 +18,11 @@ void WindowActionRouter::initialize(Configuration *config) {
auto &runtime = LuaRuntime::instance();
configuration = config;
- connect(&runtime, &LuaRuntime::keymap_added, this, &WindowActionRouter::add_keymap);
+ connect(&runtime, &LuaRuntime::keymap_add_requested, this, &WindowActionRouter::add_keymap);
+ connect(&runtime, &LuaRuntime::keymap_mode_update_requested, this,
+ [](const QString &mode) { KeymapEvaluator::instance().set_current_mode(mode); });
+ // Configuration
connect(&runtime, &LuaRuntime::config_updated, configuration, &Configuration::set_config);
connect(configuration, &Configuration::user_agent_updated, this,
[this](const QString &user_agent) {
@@ -32,56 +35,56 @@ void WindowActionRouter::initialize(Configuration *config) {
win_match.second->mediator()->update_downloads_dir(downloads_dir);
});
+ // History
connect(&runtime, &LuaRuntime::history_back_requested, this,
[this](WebViewId webview_id, qsizetype history_index) {
- WITH_WEBVIEW_WINDOW(webview_id, window, {
- emit window->mediator()->history_back_requested(webview_id, history_index);
- });
+ WITH_WEBVIEW_WINDOW(webview_id, window,
+ { window->mediator()->history_back(webview_id, history_index); });
});
connect(&runtime, &LuaRuntime::history_forward_requested, this,
[this](WebViewId webview_id, qsizetype history_index) {
WITH_WEBVIEW_WINDOW(webview_id, window, {
- emit window->mediator()->history_forward_requested(webview_id, history_index);
+ window->mediator()->history_forward(webview_id, history_index);
});
});
+
+ // Webview action
connect(&runtime, &LuaRuntime::url_opened, this,
[this](const QString &url, OpenType open_type, WebViewId webview_id) {
- WITH_WEBVIEW_WINDOW(webview_id, window, {
- emit window->mediator()->url_opened(url, open_type, webview_id);
- });
+ WITH_WEBVIEW_WINDOW(webview_id, window,
+ { window->mediator()->open_url(url, open_type, webview_id); });
});
connect(&runtime, &LuaRuntime::webview_closed, this, [this](WebViewId webview_id) {
- WITH_WEBVIEW_WINDOW(webview_id, window,
- { emit window->mediator()->webview_closed(webview_id); });
+ WITH_WEBVIEW_WINDOW(webview_id, window, { window->mediator()->close_webview(webview_id); });
});
connect(&runtime, &LuaRuntime::webview_selected, this, [this](WebViewId webview_id) {
- WITH_WEBVIEW_WINDOW(webview_id, window,
- { emit window->mediator()->webview_selected(webview_id); });
+ WITH_WEBVIEW_WINDOW(webview_id, window, { window->mediator()->select_webview(webview_id); });
});
+
+ // Search
connect(&runtime, &LuaRuntime::search_requested, this,
[this](const QString &text, WebViewId webview_id) {
- WITH_WEBVIEW_WINDOW(webview_id, window, {
- auto *mediator = win_match.second->mediator();
- this->current_search_text = text.trimmed();
- mediator->set_search_text(this->current_search_text, webview_id, true);
- })
+ current_search_text = text.trimmed();
+ find_current_search_text(webview_id, true);
});
- connect(&runtime, &LuaRuntime::search_next_requested, this, [this](WebViewId webview_id) {
- WITH_WEBVIEW_WINDOW(webview_id, window, {
- win_match.second->mediator()->set_search_text(this->current_search_text, webview_id, true);
- })
- });
- connect(&runtime, &LuaRuntime::search_previous_requested, this, [this](WebViewId webview_id) {
- WITH_WEBVIEW_WINDOW(webview_id, window, {
- win_match.second->mediator()->set_search_text(this->current_search_text, webview_id, false);
- })
- });
+ connect(&runtime, &LuaRuntime::search_next_requested, this,
+ [this](WebViewId webview_id) { find_current_search_text(webview_id, true); });
+ connect(&runtime, &LuaRuntime::search_previous_requested, this,
+ [this](WebViewId webview_id) { find_current_search_text(webview_id, false); });
+
+ // Devtools
connect(&runtime, &LuaRuntime::devtools_requested, this, [this](WebViewId webview_id) {
WITH_WEBVIEW_WINDOW(webview_id, window,
{ win_match.second->mediator()->open_devtools(webview_id); })
});
}
+void WindowActionRouter::find_current_search_text(WebViewId webview_id, bool forward) {
+ WITH_WEBVIEW_WINDOW(webview_id, window, {
+ win_match.second->mediator()->set_search_text(current_search_text, webview_id, forward);
+ })
+}
+
void WindowActionRouter::add_window(BrowserWindow *window) {
auto win_id = last_id;
last_id++;
@@ -110,8 +113,7 @@ const WindowMap &WindowActionRouter::windows() { return window_map; }
void WindowActionRouter::add_keymap(const QString &mode_string, const QString &keyseq,
std::function<void()> action) {
auto &keymap_evaluator = KeymapEvaluator::instance();
- const KeyMode mode = keymap_evaluator.mode_from_string(mode_string);
- keymap_evaluator.add_keymap(mode, keyseq, std::move(action));
+ keymap_evaluator.add_keymap(mode_string, keyseq, std::move(action));
}
WebViewId WindowActionRouter::fetch_current_view_id(WindowId win_id) {
@@ -138,4 +140,6 @@ QList<WebViewData> WindowActionRouter::fetch_webview_data_list(WindowId win_id)
return {};
}
-QString WindowActionRouter::fetch_current_search_text() const { return current_search_text; }
+KeyMode WindowActionRouter::fetch_current_mode() const {
+ return KeymapEvaluator::instance().get_current_mode();
+}
diff --git a/src/WindowActionRouter.hpp b/src/WindowActionRouter.hpp
index 65124ef..b749642 100644
--- a/src/WindowActionRouter.hpp
+++ b/src/WindowActionRouter.hpp
@@ -7,6 +7,8 @@
#include <mutex>
#include "EventQueue.hpp"
+#include "keymap/KeymapEvaluator.hpp"
+#include "utils.hpp"
#include "widgets/BrowserWindow.hpp"
#include "widgets/WebViewStack.hpp"
@@ -35,15 +37,18 @@ public:
WebViewId fetch_current_view_id(WindowId win_id = 0);
QList<WebViewData> fetch_webview_data_list(WindowId win_id = 0);
QVariant fetch_config_value(const QString &key);
- QString fetch_current_search_text() const;
+ KeyMode fetch_current_mode() const;
- DELEGATE((&event_queue), dispatch_event, dispatch_event);
- DELEGATE((&event_queue), register_event, register_event)
+ DEFINE_GETTER(fetch_current_search_text, current_search_text)
+
+ DELEGATE(&event_queue, dispatch_event, dispatch_event)
+ DELEGATE(&event_queue, register_event, register_event)
protected:
WindowActionRouter() = default;
void add_keymap(const QString &mode_string, const QString &keyseq, std::function<void()> action);
+ void find_current_search_text(WebViewId webview_id, bool forward);
signals:
void new_window_requested(const QUrl &url);
diff --git a/src/WindowMediator.cpp b/src/WindowMediator.cpp
index f27e009..cb677ee 100644
--- a/src/WindowMediator.cpp
+++ b/src/WindowMediator.cpp
@@ -7,16 +7,6 @@
#include "widgets/WebViewStack.hpp"
WindowMediator::WindowMediator(WebViewStack *webview_stack) : webview_stack(webview_stack) {
- connect(this, &WindowMediator::history_back_requested, webview_stack,
- &WebViewStack::webview_history_back);
- connect(this, &WindowMediator::history_forward_requested, webview_stack,
- &WebViewStack::webview_history_forward);
-
- connect(this, &WindowMediator::url_opened, webview_stack, &WebViewStack::open_url);
- connect(this, &WindowMediator::webview_closed, webview_stack, &WebViewStack::close);
- connect(this, &WindowMediator::webview_selected, webview_stack, &WebViewStack::focus_webview);
-
- // Delegate signal
connect(webview_stack, &WebViewStack::new_window_requested, this,
&WindowMediator::new_window_requested);
connect(webview_stack, &WebViewStack::close_window_requested, this,
@@ -29,7 +19,6 @@ void WindowMediator::update_user_agent(const QString &user_agent) {
}
void WindowMediator::update_downloads_dir(const QString &downloads_dir) {
- qDebug() << "::: dl in med" << downloads_dir;
auto *profile = webview_stack->get_profile();
profile->setDownloadPath(downloads_dir);
}
diff --git a/src/WindowMediator.hpp b/src/WindowMediator.hpp
index 2e341c0..6046292 100644
--- a/src/WindowMediator.hpp
+++ b/src/WindowMediator.hpp
@@ -18,13 +18,13 @@ public:
DELEGATE(webview_stack, get_webview_list, get_webview_list)
DELEGATE(webview_stack, set_search_text, set_search_text)
DELEGATE(webview_stack, open_devtools, open_devtools)
+ DELEGATE(webview_stack, open_url, open_url)
+ DELEGATE(webview_stack, webview_history_back, history_back)
+ DELEGATE(webview_stack, webview_history_forward, history_forward)
+ DELEGATE(webview_stack, close, close_webview)
+ DELEGATE(webview_stack, focus_webview, select_webview)
signals:
- void history_back_requested(WebViewId webview_id, qsizetype history_index);
- void history_forward_requested(WebViewId webview_id, qsizetype history_index);
- void url_opened(QString url, OpenType open_type, WebViewId webview_id);
- void webview_closed(WebViewId webview_id);
- void webview_selected(WebViewId webview_id);
void new_window_requested(const QUrl &url);
void close_window_requested();
diff --git a/src/keymap/KeymapEvaluator.cpp b/src/keymap/KeymapEvaluator.cpp
index e42ec3c..0bd6f93 100644
--- a/src/keymap/KeymapEvaluator.cpp
+++ b/src/keymap/KeymapEvaluator.cpp
@@ -6,15 +6,14 @@
#include "keymap/KeymapEvaluator.hpp"
// TODO: Clear mapping after some time
+// TODO: Forward current keysequence with partial key after timeout (only passthrough kind)
-void KeymapEvaluator::add_keymap(KeyMode mode, const QString &key, KeyAction action) {
+void KeymapEvaluator::add_keymap(const KeyMode &mode, const QString &key, KeyAction action) {
if (!modal_keys.contains(mode))
- modal_keys.insert(mode, {});
-
- qDebug() << " " << mode << key;
+ modal_keys[mode] = {.keymap = {}, .config = {.passthrough = false}};
auto key_seq = key_seq_parser.parse(key);
- modal_keys[mode].append(KeyMap{.key_sequence = key_seq, .action = std::move(action)});
+ modal_keys[mode].keymap.append(KeyMap{.key_sequence = key_seq, .action = std::move(action)});
}
bool KeymapEvaluator::evaluate(Qt::KeyboardModifiers modifiers, Qt::Key key) {
@@ -43,25 +42,29 @@ bool KeymapEvaluator::evaluate(Qt::KeyboardModifiers modifiers, Qt::Key key) {
if (!found_pending_matches)
active_key_sequence.clear();
- if (is_insertable_mode())
+ if (is_passthrough_mode())
return found_pending_matches;
return true;
}
-bool KeymapEvaluator::is_insertable_mode() { return current_mode == KeyMode::Insert; }
+bool KeymapEvaluator::is_passthrough_mode() {
+ if (!modal_keys.contains(current_mode))
+ return false;
+
+ return modal_keys[current_mode].config.passthrough;
+}
const QList<KeyMap> *KeymapEvaluator::current_mode_keys() {
if (!modal_keys.contains(current_mode))
return new QList<KeyMap>();
- return &modal_keys[current_mode];
+ return &modal_keys[current_mode].keymap;
}
-KeyMode KeymapEvaluator::mode_from_string(const QString &mode_string) {
- if (mode_string == "n")
- return KeyMode::Normal;
- if (mode_string == "i")
- return KeyMode::Insert;
- return KeyMode::Normal;
+void KeymapEvaluator::define_mode(const KeyMode &mode, const KeyModeConfig &config) {
+ if (!modal_keys.contains(current_mode))
+ modal_keys[current_mode] = {.keymap = {}, .config = config};
+ else
+ modal_keys[mode].config = config;
}
diff --git a/src/keymap/KeymapEvaluator.hpp b/src/keymap/KeymapEvaluator.hpp
index 34f4ae5..a7a100b 100644
--- a/src/keymap/KeymapEvaluator.hpp
+++ b/src/keymap/KeymapEvaluator.hpp
@@ -2,8 +2,8 @@
#include <QWidget>
#include <QtCore>
-#include <cstdint>
#include <functional>
+#include <unordered_map>
#include "keymap/KeySeqParser.hpp"
#include "utils.hpp"
@@ -15,7 +15,16 @@ struct KeyMap {
KeyAction action;
};
-enum KeyMode : uint8_t { Normal, Insert };
+using KeyMode = QString;
+
+struct KeyModeConfig {
+ bool passthrough;
+};
+
+struct KeyModeState {
+ QList<KeyMap> keymap;
+ KeyModeConfig config;
+};
class KeymapEvaluator : public QObject {
Q_OBJECT
@@ -28,20 +37,20 @@ public:
return keymap_evaluator;
}
- void add_keymap(KeyMode mode, const QString &key, KeyAction action);
+ void add_keymap(const KeyMode &mode, const QString &key, KeyAction action);
bool evaluate(Qt::KeyboardModifiers modifiers, Qt::Key key);
- KeyMode mode_from_string(const QString &mode_string);
+ void define_mode(const KeyMode &mode, const KeyModeConfig &config);
DEFINE_SETTER(set_current_mode, current_mode)
DEFINE_GETTER(get_current_mode, current_mode)
protected:
const QList<KeyMap> *current_mode_keys();
- bool is_insertable_mode();
+ bool is_passthrough_mode();
private:
- QMap<KeyMode, QList<KeyMap>> modal_keys;
+ std::unordered_map<KeyMode, KeyModeState> modal_keys;
KeySeqParser key_seq_parser;
- KeyMode current_mode = KeyMode::Normal;
+ KeyMode current_mode = "i";
KeySequence active_key_sequence;
};
diff --git a/src/utils.hpp b/src/utils.hpp
index d7ca4c0..2a49bd3 100644
--- a/src/utils.hpp
+++ b/src/utils.hpp
@@ -2,16 +2,15 @@
#include <memory>
-#define DELEGATE(OBJ, METHOD, METHOD_AS) \
- template <typename... Args> decltype(auto) METHOD_AS(Args &&...args) { \
- return OBJ->METHOD(std::forward<Args>(args)...); \
+#define DELEGATE(OBJ, METHOD, METHOD_AS) \
+ template <typename... Args> inline decltype(auto) METHOD_AS(Args &&...args) { \
+ return (OBJ)->METHOD(std::forward<Args>(args)...); \
}
-#define DEFINE_SETTER(METHOD, PROPERTY) \
- template <typename Arg> void METHOD(Arg val) { PROPERTY = val; }
+#define DEFINE_SETTER(METHOD, PROPERTY) \
+ template <typename Arg> inline void METHOD(Arg val) { PROPERTY = val; }
-#define DEFINE_GETTER(METHOD, EXPR) \
- decltype(auto) METHOD() { return EXPR; }
+#define DEFINE_GETTER(METHOD, EXPR) \
+ decltype(auto) inline METHOD() const { return EXPR; }
-#define DEFER(DEFERRED_BLOCK) \
- std::shared_ptr<void> __deferred(nullptr, [](...) DEFERRED_BLOCK);
+#define DEFER(DEFERRED_BLOCK) std::shared_ptr<void> __deferred(nullptr, [](...) DEFERRED_BLOCK);
diff --git a/src/widgets/BrowserWindow.cpp b/src/widgets/BrowserWindow.cpp
index 5a8a062..f4ea97d 100644
--- a/src/widgets/BrowserWindow.cpp
+++ b/src/widgets/BrowserWindow.cpp
@@ -26,7 +26,7 @@ BrowserWindow::BrowserWindow(const Configuration &configuration, const QStringLi
profile->setDownloadPath(configuration.downloads_dir());
profile->setHttpUserAgent(configuration.user_agent());
- // Web engine
+ // Stack of web views
auto *webview_stack = new WebViewStack(&configuration, profile);
layout->addWidget(webview_stack);
@@ -40,16 +40,9 @@ BrowserWindow::BrowserWindow(const Configuration &configuration, const QStringLi
}
// Default keymaps
- auto &keymap_evaluator = KeymapEvaluator::instance();
-
- // TODO: remove
- keymap_evaluator.add_keymap(KeyMode::Normal, "i", [&keymap_evaluator]() {
- keymap_evaluator.set_current_mode(KeyMode::Insert);
- });
- keymap_evaluator.add_keymap(KeyMode::Insert, "<esc>", [&keymap_evaluator]() {
- keymap_evaluator.set_current_mode(KeyMode::Normal);
- });
- keymap_evaluator.add_keymap(KeyMode::Normal, "<c-t>a", []() { qDebug() << "Stuff"; });
+ auto &keymap = KeymapEvaluator::instance();
+ keymap.define_mode("n", {.passthrough = false});
+ keymap.define_mode("i", {.passthrough = true});
win_mediator = new WindowMediator(webview_stack);
@@ -63,8 +56,6 @@ BrowserWindow::BrowserWindow(const Configuration &configuration, const QStringLi
});
}
-void BrowserWindow::closeEvent(QCloseEvent * /*event*/) { emit closed(); }
-
bool BrowserWindow::on_window_key_event(QKeyEvent *event) {
auto &keymap_evaluator = KeymapEvaluator::instance();
const bool should_skip = keymap_evaluator.evaluate(event->modifiers(), (Qt::Key)event->key());
diff --git a/src/widgets/BrowserWindow.hpp b/src/widgets/BrowserWindow.hpp
index 638d8de..6f20e4b 100644
--- a/src/widgets/BrowserWindow.hpp
+++ b/src/widgets/BrowserWindow.hpp
@@ -20,7 +20,7 @@ public:
bool on_window_key_event(QKeyEvent *event);
- void closeEvent(QCloseEvent * /*event*/) override;
+ void closeEvent(QCloseEvent * /*event*/) override { emit closed(); };
signals:
void closed();
diff --git a/src/widgets/WebView.hpp b/src/widgets/WebView.hpp
index 16c039c..c861b6e 100644
--- a/src/widgets/WebView.hpp
+++ b/src/widgets/WebView.hpp
@@ -36,10 +36,10 @@ class WebView : public QWebEngineView {
public:
WebView(uint32_t webview_id, QWebEngineProfile *profile, QWidget *parent_node = nullptr);
- DEFINE_GETTER(get_id, id)
-
void open_devtools();
+ DEFINE_GETTER(get_id, id)
+
private:
uint32_t id;