diff options
Diffstat (limited to '')
| -rw-r--r-- | .clang-tidy | 1 | ||||
| -rw-r--r-- | config.lua | 3 | ||||
| -rw-r--r-- | spec/WebViewStackSpec.cpp | 176 | ||||
| -rw-r--r-- | src/InputMediator.cpp | 9 | ||||
| -rw-r--r-- | src/InputMediator.hpp | 8 | ||||
| -rw-r--r-- | src/LuaRuntime.cpp | 47 | ||||
| -rw-r--r-- | src/LuaRuntime.hpp | 5 | ||||
| -rw-r--r-- | src/widgets/WebView.cpp | 5 | ||||
| -rw-r--r-- | src/widgets/WebView.hpp | 10 | ||||
| -rw-r--r-- | src/widgets/WebViewStack.cpp | 97 | ||||
| -rw-r--r-- | src/widgets/WebViewStack.hpp | 22 |
11 files changed, 220 insertions, 163 deletions
diff --git a/.clang-tidy b/.clang-tidy index b4cca2b..b5dd4f7 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -15,6 +15,7 @@ Checks: > , -readability-convert-member-functions-to-static , -readability-implicit-bool-conversion , -bugprone-easily-swappable-parameters + , -readability-math-missing-parentheses # , cppcoreguidelines-owning-memory # , cppcoreguidelines-* @@ -47,7 +47,7 @@ local urls = { web.keymap.set('n', 't', function() Dmenu.select(urls, { prompt = 'Open tab:' }, function(err, result) if err or not result then return end - web.tabopen(trim(result)) + web.tabs.new(trim(result)) end) end) -- Open in current tab @@ -71,6 +71,7 @@ end) -- History back/forward web.keymap.set('n', '<s-h>', function() web.history.back(); end) web.keymap.set('n', '<s-l>', function() web.history.forward(); end) +web.keymap.set('n', '<c-w>', function() web.tabs.close(); end) -- Dummy test keymap web.keymap.set('n', 'm', function() diff --git a/spec/WebViewStackSpec.cpp b/spec/WebViewStackSpec.cpp index 6e46db6..4324976 100644 --- a/spec/WebViewStackSpec.cpp +++ b/spec/WebViewStackSpec.cpp @@ -80,91 +80,97 @@ private slots: } } - void test_next_navigation() { - context("when nextWebView is called"); - context("- and there is only 1 tab"); - it("does nothing") { - Configuration configuration; - WebViewStack webview_stack(&configuration); - - webview_stack.next(); - - QCOMPARE(webview_stack.current_webview_index(), 0); - QCOMPARE(webview_stack.current_url(), configuration.new_tab_url); - } - - context("when nextWebView is called"); - context("- and there are tabs after the current tab"); - it("goes to the next tab") { - Configuration configuration; - WebViewStack webview_stack(&configuration); - webview_stack.open_url(QUrl("http://a1.com"), OpenType::OpenUrlInBgTab); - webview_stack.open_url(QUrl("http://a2.com"), OpenType::OpenUrlInBgTab); - - webview_stack.next(); - - QCOMPARE(webview_stack.current_webview_index(), 1); - QCOMPARE(webview_stack.current_url(), QUrl("http://a1.com")); - } - - context("when nextWebView is called"); - context("- and current tab is the last tab"); - it("jumps to the first tab") { - Configuration configuration; - WebViewStack webview_stack(&configuration); - webview_stack.open_url(QUrl("http://a1.com"), OpenType::OpenUrlInBgTab); - webview_stack.open_url(QUrl("http://a2.com"), OpenType::OpenUrlInTab); - QCOMPARE(webview_stack.current_webview_index(), 2); - - webview_stack.next(); - - QCOMPARE(webview_stack.current_webview_index(), 0); - QCOMPARE(webview_stack.current_url(), configuration.new_tab_url); - } - } - - void test_previous_navigation() { - context("when previousWebView is called"); - context("- and there is only 1 tab"); - it("does nothing") { - Configuration configuration; - WebViewStack webview_stack(&configuration); - - webview_stack.previous(); - - QCOMPARE(webview_stack.current_webview_index(), 0); - QCOMPARE(webview_stack.current_url(), configuration.new_tab_url); - } - - context("when previousWebView is called"); - context("- and there are tabs before the current tab"); - it("goes to the next tab") { - Configuration configuration; - WebViewStack webview_stack(&configuration); - webview_stack.open_url(QUrl("http://a1.com"), OpenType::OpenUrlInBgTab); - webview_stack.open_url(QUrl("http://a2.com"), OpenType::OpenUrlInTab); - QCOMPARE(webview_stack.current_webview_index(), 2); - - webview_stack.previous(); - - QCOMPARE(webview_stack.current_webview_index(), 1); - QCOMPARE(webview_stack.current_url(), QUrl("http://a1.com")); - } - - context("when previousWebView is called"); - context("- and current tab is the last tab"); - it("jumps to the last tab") { - Configuration configuration; - WebViewStack webview_stack(&configuration); - webview_stack.open_url(QUrl("http://a1.com"), OpenType::OpenUrlInBgTab); - webview_stack.open_url(QUrl("http://a2.com"), OpenType::OpenUrlInBgTab); - - webview_stack.previous(); - - QCOMPARE(webview_stack.current_webview_index(), 2); - QCOMPARE(webview_stack.current_url(), QUrl("http://a2.com")); - } - } + // void test_next_navigation() { + // context("when nextWebView is called"); + // context("- and there is only 1 tab"); + // it("does nothing") { + // Configuration configuration; + // WebViewStack webview_stack(&configuration); + // + // webview_stack.next(); + // + // QCOMPARE(webview_stack.current_webview_index(), 0); + // QCOMPARE(webview_stack.current_url(), configuration.new_tab_url); + // } + // + // context("when nextWebView is called"); + // context("- and there are tabs after the current tab"); + // it("goes to the next tab") { + // Configuration configuration; + // WebViewStack webview_stack(&configuration); + // webview_stack.open_url(QUrl("http://a1.com"), + // OpenType::OpenUrlInBgTab); + // webview_stack.open_url(QUrl("http://a2.com"), + // OpenType::OpenUrlInBgTab); + // + // webview_stack.next(); + // + // QCOMPARE(webview_stack.current_webview_index(), 1); + // QCOMPARE(webview_stack.current_url(), QUrl("http://a1.com")); + // } + // + // context("when nextWebView is called"); + // context("- and current tab is the last tab"); + // it("jumps to the first tab") { + // Configuration configuration; + // WebViewStack webview_stack(&configuration); + // webview_stack.open_url(QUrl("http://a1.com"), + // OpenType::OpenUrlInBgTab); + // webview_stack.open_url(QUrl("http://a2.com"), OpenType::OpenUrlInTab); + // QCOMPARE(webview_stack.current_webview_index(), 2); + // + // webview_stack.next(); + // + // QCOMPARE(webview_stack.current_webview_index(), 0); + // QCOMPARE(webview_stack.current_url(), configuration.new_tab_url); + // } + // } + // + // void test_previous_navigation() { + // context("when previousWebView is called"); + // context("- and there is only 1 tab"); + // it("does nothing") { + // Configuration configuration; + // WebViewStack webview_stack(&configuration); + // + // webview_stack.previous(); + // + // QCOMPARE(webview_stack.current_webview_index(), 0); + // QCOMPARE(webview_stack.current_url(), configuration.new_tab_url); + // } + // + // context("when previousWebView is called"); + // context("- and there are tabs before the current tab"); + // it("goes to the next tab") { + // Configuration configuration; + // WebViewStack webview_stack(&configuration); + // webview_stack.open_url(QUrl("http://a1.com"), + // OpenType::OpenUrlInBgTab); + // webview_stack.open_url(QUrl("http://a2.com"), OpenType::OpenUrlInTab); + // QCOMPARE(webview_stack.current_webview_index(), 2); + // + // webview_stack.previous(); + // + // QCOMPARE(webview_stack.current_webview_index(), 1); + // QCOMPARE(webview_stack.current_url(), QUrl("http://a1.com")); + // } + // + // context("when previousWebView is called"); + // context("- and current tab is the last tab"); + // it("jumps to the last tab") { + // Configuration configuration; + // WebViewStack webview_stack(&configuration); + // webview_stack.open_url(QUrl("http://a1.com"), + // OpenType::OpenUrlInBgTab); + // webview_stack.open_url(QUrl("http://a2.com"), + // OpenType::OpenUrlInBgTab); + // + // webview_stack.previous(); + // + // QCOMPARE(webview_stack.current_webview_index(), 2); + // QCOMPARE(webview_stack.current_url(), QUrl("http://a2.com")); + // } + // } void test_close_webview() { context("when closeWebView is called"); diff --git a/src/InputMediator.cpp b/src/InputMediator.cpp index 1d86a2a..2a36665 100644 --- a/src/InputMediator.cpp +++ b/src/InputMediator.cpp @@ -15,16 +15,17 @@ InputMediator::InputMediator(WebViewStack *webview_stack, keymap_evaluator(keymap_evaluator) { connect(lua_runtime, &LuaRuntime::url_opened, webview_stack, &WebViewStack::open_url); - connect(lua_runtime, &LuaRuntime::keymap_add_requested, this, + connect(lua_runtime, &LuaRuntime::keymap_added, this, &InputMediator::add_keymap); connect(lua_runtime, &LuaRuntime::history_back_requested, webview_stack, &WebViewStack::webview_history_back); connect(lua_runtime, &LuaRuntime::history_forward_requested, webview_stack, &WebViewStack::webview_history_forward); + connect(lua_runtime, &LuaRuntime::webview_closed, webview_stack, + &WebViewStack::close); - lua_runtime->set_current_tab_id_fetcher([this]() { - return this->webview_stack->current_webview_index(); - }); + lua_runtime->set_current_tab_id_fetcher( + [this]() { return this->webview_stack->current_webview_id(); }); } void InputMediator::add_keymap(const QString &mode_string, diff --git a/src/InputMediator.hpp b/src/InputMediator.hpp index 5933bd7..d1dc122 100644 --- a/src/InputMediator.hpp +++ b/src/InputMediator.hpp @@ -16,11 +16,9 @@ public: KeymapEvaluator *keymap_evaluator); ~InputMediator() override; - DELEGATE(webview_stack, open_url, open_url) - DELEGATE(webview_stack, current_url, current_url) - DELEGATE(webview_stack, next, next_webview) - DELEGATE(webview_stack, previous, previous_webview) - DELEGATE(webview_stack, close_current, close_current_webview) + // DELEGATE(webview_stack, open_url, open_url) + // DELEGATE(webview_stack, current_url, current_url) + // DELEGATE(webview_stack, close_current, close_current_webview) DELEGATE(keymap_evaluator, evaluate, evaluate_keymap) protected: diff --git a/src/LuaRuntime.cpp b/src/LuaRuntime.cpp index 0149e10..1fb722a 100644 --- a/src/LuaRuntime.cpp +++ b/src/LuaRuntime.cpp @@ -107,7 +107,7 @@ int LuaRuntime::lua_add_keymap(lua_State *state) { // TODO: Cleanup function ref on after keymap clear auto *runtime = LuaRuntime::instance(); - emit runtime->keymap_add_requested(mode, keyseq, action); + emit runtime->keymap_added(mode, keyseq, action); return 1; } @@ -127,36 +127,41 @@ void LuaRuntime::init_web_lib() { // NOLINTBEGIN(modernize-avoid-c-arrays) // web - luaL_Reg weblib[] = { + luaL_Reg web[] = { {"open", &LuaRuntime::lua_on_url_open}, - {"tabopen", &LuaRuntime::lua_on_url_tab_open}, {nullptr, nullptr}, }; - luaL_newlib(state, weblib); // NOLINT(readability-math-missing-parentheses) + luaL_newlib(state, web); lua_setglobal(state, web_global_name); - - // web.keymap lua_getglobal(state, web_global_name); - luaL_Reg keymaplib[] = { + + // Keymap api (web.keymap) + luaL_Reg webkeymap[] = { {"set", &LuaRuntime::lua_add_keymap}, + {nullptr, nullptr}, }; - luaL_newlib(state, keymaplib); // NOLINT(readability-math-missing-parentheses) + luaL_newlib(state, webkeymap); lua_setfield(state, -2, "keymap"); - // lua_pop(state, 1); - luaL_Reg tabslib[] = { + // Tab actions (web.tabs) + luaL_Reg webtabs[] = { + {"close", &LuaRuntime::lua_tab_closed}, + {"new", &LuaRuntime::lua_on_url_tab_open}, {"current", &LuaRuntime::lua_get_current_tab_id}, + {nullptr, nullptr}, }; - luaL_newlib(state, tabslib); // NOLINT(readability-math-missing-parentheses) + luaL_newlib(state, webtabs); lua_setfield(state, -2, "tabs"); - luaL_Reg historylib[] = { + // History navigation + luaL_Reg webhistory[] = { {"back", &LuaRuntime::lua_history_back}, {"forward", &LuaRuntime::lua_history_forward}, + {nullptr, nullptr}, }; - luaL_newlib(state, // NOLINT(readability-math-missing-parentheses) - historylib); + luaL_newlib(state, webhistory); lua_setfield(state, -2, "history"); + // NOLINTEND(modernize-avoid-c-arrays) } @@ -201,6 +206,20 @@ int LuaRuntime::lua_history_forward(lua_State *state) { return 1; } +int LuaRuntime::lua_tab_closed(lua_State *state) { + auto *runtime = LuaRuntime::instance(); + + qsizetype tab_id; + if (lua_isnoneornil(state, 2)) { + tab_id = runtime->fetch_current_tab_id(); + } else { + tab_id = lua_tointeger(state, 2); + } + + emit runtime->webview_closed(tab_id); + return 1; +} + LuaRuntime::~LuaRuntime() { stop_event_loop(); lua_close(state); diff --git a/src/LuaRuntime.hpp b/src/LuaRuntime.hpp index c90049e..a13fe1e 100644 --- a/src/LuaRuntime.hpp +++ b/src/LuaRuntime.hpp @@ -42,10 +42,10 @@ signals: void url_opened(QString url, OpenType open_type); void evaluation_completed(QVariant value); void evaluation_failed(QString value); - void keymap_add_requested(QString mode, QString keyseq, - std::function<void()>); + void keymap_added(QString mode, QString keyseq, std::function<void()>); void history_back_requested(WebViewId webview_id, qsizetype history_index); void history_forward_requested(WebViewId webview_id, qsizetype history_index); + void webview_closed(WebViewId webview_id); // void output_produced(QVariant value); protected: @@ -58,6 +58,7 @@ protected: static int lua_get_current_tab_id(lua_State *state); static int lua_history_back(lua_State *state); static int lua_history_forward(lua_State *state); + static int lua_tab_closed(lua_State *state); private: lua_State *state; diff --git a/src/widgets/WebView.cpp b/src/widgets/WebView.cpp index 9c542f8..2ba5c4c 100644 --- a/src/widgets/WebView.cpp +++ b/src/widgets/WebView.cpp @@ -3,5 +3,6 @@ #include "widgets/WebView.hpp" -WebView::WebView(QWebEngineProfile *profile, QWidget *parent_node) - : QWebEngineView(profile, parent_node) {} +WebView::WebView(uint32_t webview_id, QWebEngineProfile *profile, + QWidget *parent_node) + : QWebEngineView(profile, parent_node), id(webview_id) {} diff --git a/src/widgets/WebView.hpp b/src/widgets/WebView.hpp index f0457fd..0f2aae6 100644 --- a/src/widgets/WebView.hpp +++ b/src/widgets/WebView.hpp @@ -2,10 +2,18 @@ #include <QWebEngineView> #include <QtCore> +#include <cstdint> + +#include "utils.hpp" class WebView : public QWebEngineView { Q_OBJECT public: - WebView(QWebEngineProfile *profile, QWidget *parent_node = nullptr); + WebView(uint32_t webview_id, QWebEngineProfile *profile, + QWidget *parent_node = nullptr); + DEFINE_GETTER(get_id, id) + +private: + uint32_t id; }; diff --git a/src/widgets/WebViewStack.cpp b/src/widgets/WebViewStack.cpp index 2d3722a..1d0a35e 100644 --- a/src/widgets/WebViewStack.cpp +++ b/src/widgets/WebViewStack.cpp @@ -2,6 +2,7 @@ #include <QWebEngineHistory> #include <QWebEngineNewWindowRequest> #include <QWebEngineProfile> +#include <cstdint> #include <cstdlib> #include <vector> @@ -35,7 +36,7 @@ void WebViewStack::open_url(const QUrl &url, OpenType open_type) { } WebView *WebViewStack::create_new_webview(const QUrl &url, bool focus) { - auto *webview = new WebView(profile); + auto *webview = new WebView(next_id++, profile); webview->setUrl(url); layout->addWidget(webview); webview_list.append(webview); @@ -44,7 +45,7 @@ WebView *WebViewStack::create_new_webview(const QUrl &url, bool focus) { &WebViewStack::on_new_webview_request); if (focus) - focus_webview(webview_list.length() - 1); + focus_webview(webview->get_id()); return webview; } @@ -73,37 +74,32 @@ void WebViewStack::on_new_webview_request( } } -void WebViewStack::next() { - if (webview_list.isEmpty()) - return; - auto index = current_webview_index() + 1; - auto total = webview_list.length(); - index = index >= total ? index % total : index; - focus_webview(index); +int32_t WebViewStack::get_webview_index(WebViewId webview_id) { + int index = 0; + for (auto &webview : webview_list) { + if (webview->get_id() == webview_id) + return index; + index++; + } + return -1; } -void WebViewStack::previous() { - if (webview_list.isEmpty()) +void WebViewStack::close(WebViewId webview_id) { + auto *webview = get_webview(webview_id); + if (webview == nullptr) return; - auto index = current_webview_index() - 1; - auto total = webview_list.length(); - index = index < 0 ? total + index : index; - focus_webview(index); -} - -void WebViewStack::close_current() { close(current_webview_index()); } -void WebViewStack::close(WebViewId index) { - if (index < 0 || index >= webview_list.length()) + auto webview_index = get_webview_index(webview_id); + if (webview_index < 0) return; - auto *webview = webview_list.at(index); layout->removeWidget(webview); - webview_list.removeAt(index); + webview_list.removeAt(webview_index); disconnect(webview->page()); webview->deleteLater(); - focus_webview(current_webview_index()); + // TODO: Focus on different webview + // focus_webview(); if (webview_list.isEmpty()) { create_new_webview(configuration->new_tab_url, true); @@ -112,11 +108,13 @@ void WebViewStack::close(WebViewId index) { void WebViewStack::webview_history_back(WebViewId webview_id, qsizetype history_index) { - if (webview_id < 0 || webview_id >= webview_list.length()) + auto *webview = get_webview(webview_id); + if (webview == nullptr) { + qDebug() << "Invalid webview id" << webview_id; return; + } // TODO: Change this - auto *webview = webview_list.at(webview_id); auto *history = webview->history(); for (auto i = abs(history_index); i > 0; i--) if (history->canGoBack()) @@ -125,11 +123,13 @@ void WebViewStack::webview_history_back(WebViewId webview_id, void WebViewStack::webview_history_forward(WebViewId webview_id, qsizetype history_index) { - if (webview_id < 0 || webview_id >= webview_list.length()) + auto *webview = get_webview(webview_id); + if (webview == nullptr) { + qDebug() << "Invalid webview id" << webview_id; return; + } // TODO: Change this - auto *webview = webview_list.at(webview_id); auto *history = webview->history(); for (auto i = abs(history_index); i > 0; i--) if (history->canGoForward()) @@ -143,32 +143,53 @@ std::vector<QUrl> WebViewStack::urls() { return urls; } +WebViewId WebViewStack::current_webview_id() { + if (webview_list.empty()) + return -1; + return current_webview()->get_id(); +} + +WebView *WebViewStack::current_webview() { + if (webview_list.empty()) + return nullptr; + return webview_list.at(current_webview_index()); +} + uint32_t WebViewStack::current_webview_index() { - qDebug() << "CIRR" << layout->currentIndex(); return layout->currentIndex(); } uint32_t WebViewStack::count() { return webview_list.length(); } -void WebViewStack::focus_webview(WebViewId index) { - if (webview_list.isEmpty()) - return; +void WebViewStack::focus_webview(WebViewId webview_id) { + auto webview_index = get_webview_index(webview_id); + if (webview_index >= 0) + layout->setCurrentIndex((int)webview_index); +} - index = std::max((long long)0, - std::min((long long)index, webview_list.length() - 1)); - layout->setCurrentIndex((int)index); +WebView *WebViewStack::get_webview(WebViewId webview_id) { + auto webview_index = get_webview_index(webview_id); + if (webview_index < 0) + return nullptr; + return webview_list.at(webview_index); } QUrl WebViewStack::current_url() { - if (current_webview_index() >= webview_list.length()) + auto *webview = current_webview(); + if (webview == nullptr) { + qDebug() << "No current webview"; return QUrl{}; + } - return webview_list.at(current_webview_index())->url(); + return webview->url(); } void WebViewStack::set_current_url(const QUrl &url) { - if (current_webview_index() >= webview_list.length()) + auto *webview = current_webview(); + if (webview == nullptr) { + qDebug() << "No current webview"; return; + } - webview_list.at(current_webview_index())->setUrl(url); + webview->setUrl(url); } diff --git a/src/widgets/WebViewStack.hpp b/src/widgets/WebViewStack.hpp index c975d16..3c69888 100644 --- a/src/widgets/WebViewStack.hpp +++ b/src/widgets/WebViewStack.hpp @@ -30,23 +30,21 @@ public: QWebEngineProfile *profile = new QWebEngineProfile, QWidget *parent = nullptr); - void open_url(const QUrl &url, OpenType open_type = OpenType::OpenUrl); - - std::vector<QUrl> urls(); + std::vector<QUrl> urls(); // TODO: Remove QList<Tab> get_webview_list(); - uint32_t current_webview_index(); + WebView *current_webview(); + WebViewId current_webview_id(); uint32_t count(); QUrl current_url(); + WebView *get_webview(WebViewId webview_id); + uint32_t current_webview_index(); - void focus_webview(WebViewId index); - void next(); - void previous(); - - void close(WebViewId index); - void close_current(); - +public slots: // NOLINT(readability-redundant-access-specifiers) + void open_url(const QUrl &url, OpenType open_type = OpenType::OpenUrl); void webview_history_back(WebViewId webview_id, qsizetype history_index); void webview_history_forward(WebViewId webview_id, qsizetype history_index); + void close(WebViewId webview_id); + void focus_webview(WebViewId webview_id); private slots: void on_new_webview_request(const QWebEngineNewWindowRequest &request); @@ -54,10 +52,12 @@ private slots: protected: void set_current_url(const QUrl &url); WebView *create_new_webview(const QUrl &url, bool focus = false); + int32_t get_webview_index(WebViewId webview_id); private: const Configuration *configuration; QWebEngineProfile *profile; QStackedLayout *layout; QList<WebView *> webview_list; + WebViewId next_id = 1; }; |
