diff options
| author | Akshay Nair <phenax5@gmail.com> | 2025-04-20 12:57:07 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2025-05-02 16:15:17 +0530 |
| commit | b4b6a646b3a7a7f6c7e990c67f208b76f4b5f748 (patch) | |
| tree | 7f18775a63594acf0187668af63766dd72b9f66f | |
| parent | 75157006bf6f1176f64e87695343980b16908bb6 (diff) | |
| download | null-browser-b4b6a646b3a7a7f6c7e990c67f208b76f4b5f748.tar.gz null-browser-b4b6a646b3a7a7f6c7e990c67f208b76f4b5f748.zip | |
Refactor + expose managing mode to inside lua
Diffstat (limited to '')
| -rw-r--r-- | config.lua | 10 | ||||
| -rw-r--r-- | lua/null-browser/api.lua | 7 | ||||
| -rw-r--r-- | spec/KeymapEvaluatorSpec.cpp | 35 | ||||
| -rw-r--r-- | spec/LuaRuntimeApiSpec.cpp | 67 | ||||
| -rw-r--r-- | src/LuaRuntime.hpp | 3 | ||||
| -rw-r--r-- | src/LuaRuntimeApi.hpp | 21 | ||||
| -rw-r--r-- | src/WindowActionRouter.cpp | 64 | ||||
| -rw-r--r-- | src/WindowActionRouter.hpp | 11 | ||||
| -rw-r--r-- | src/WindowMediator.cpp | 11 | ||||
| -rw-r--r-- | src/WindowMediator.hpp | 10 | ||||
| -rw-r--r-- | src/keymap/KeymapEvaluator.cpp | 31 | ||||
| -rw-r--r-- | src/keymap/KeymapEvaluator.hpp | 23 | ||||
| -rw-r--r-- | src/utils.hpp | 17 | ||||
| -rw-r--r-- | src/widgets/BrowserWindow.cpp | 17 | ||||
| -rw-r--r-- | src/widgets/BrowserWindow.hpp | 2 | ||||
| -rw-r--r-- | src/widgets/WebView.hpp | 4 |
16 files changed, 207 insertions, 126 deletions
@@ -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; |
