diff options
| author | Akshay Nair <phenax5@gmail.com> | 2025-03-29 11:45:18 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2025-03-29 11:45:18 +0530 |
| commit | bcecbced7e1af9d99443a7e823f18328c7943f09 (patch) | |
| tree | 612fac477acfa38358e15916bd4a44f386dc9206 /src | |
| parent | f7392096d2d84be7143947d386528bf4f487ee83 (diff) | |
| download | null-browser-bcecbced7e1af9d99443a7e823f18328c7943f09.tar.gz null-browser-bcecbced7e1af9d99443a7e823f18328c7943f09.zip | |
Add window action router for multi-window
Diffstat (limited to 'src')
| -rw-r--r-- | src/InputMediator.hpp | 29 | ||||
| -rw-r--r-- | src/LuaRuntime.cpp | 22 | ||||
| -rw-r--r-- | src/LuaRuntime.hpp | 1 | ||||
| -rw-r--r-- | src/WindowActionRouter.cpp | 73 | ||||
| -rw-r--r-- | src/WindowActionRouter.hpp | 30 | ||||
| -rw-r--r-- | src/WindowMediator.cpp (renamed from src/InputMediator.cpp) | 32 | ||||
| -rw-r--r-- | src/WindowMediator.hpp | 38 | ||||
| -rw-r--r-- | src/keymap/KeymapEvaluator.cpp | 1 | ||||
| -rw-r--r-- | src/keymap/KeymapEvaluator.hpp | 5 | ||||
| -rw-r--r-- | src/main.cpp | 3 | ||||
| -rw-r--r-- | src/widgets/BrowserApp.cpp | 16 | ||||
| -rw-r--r-- | src/widgets/BrowserApp.hpp | 9 | ||||
| -rw-r--r-- | src/widgets/BrowserWindow.cpp (renamed from src/widgets/MainWindow.cpp) | 19 | ||||
| -rw-r--r-- | src/widgets/BrowserWindow.hpp | 20 | ||||
| -rw-r--r-- | src/widgets/MainWindow.hpp | 17 | ||||
| -rw-r--r-- | src/widgets/WebViewStack.cpp | 9 | ||||
| -rw-r--r-- | src/widgets/WebViewStack.hpp | 5 |
17 files changed, 220 insertions, 109 deletions
diff --git a/src/InputMediator.hpp b/src/InputMediator.hpp deleted file mode 100644 index 63c7a76..0000000 --- a/src/InputMediator.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include <QWidget> -#include <QtCore> - -#include "LuaRuntime.hpp" -#include "keymap/KeymapEvaluator.hpp" -#include "utils.hpp" -#include "widgets/WebViewStack.hpp" - -class InputMediator : public QObject { - Q_OBJECT - -public: - InputMediator(WebViewStack *webview_stack, LuaRuntime *lua_runtime, - KeymapEvaluator *keymap_evaluator); - ~InputMediator() override; - - DELEGATE(keymap_evaluator, evaluate, evaluate_keymap) - -protected slots: - void add_keymap(const QString &mode_string, const QString &keyseq, - std::function<void()> action); - -private: - WebViewStack *webview_stack; - LuaRuntime *lua_runtime; - KeymapEvaluator *keymap_evaluator; -}; diff --git a/src/LuaRuntime.cpp b/src/LuaRuntime.cpp index edf3b74..523fe59 100644 --- a/src/LuaRuntime.cpp +++ b/src/LuaRuntime.cpp @@ -1,4 +1,3 @@ -#include "widgets/WebViewStack.hpp" #include <QtCore> #include <lua.hpp> extern "C" { @@ -207,12 +206,7 @@ int LuaRuntime::lua_history_back(lua_State *state) { qsizetype history_index = lua_isnoneornil(state, 1) ? 1 : lua_tointeger(state, 1); - WebViewId tab_id; - if (lua_isnoneornil(state, 2)) { - tab_id = runtime->fetch_current_tab_id(); - } else { - tab_id = lua_tointeger(state, 2); - } + WebViewId tab_id = lua_isnoneornil(state, 2) ? 0 : lua_tointeger(state, 2); emit runtime->history_back_requested(tab_id, history_index); return 1; @@ -224,12 +218,7 @@ int LuaRuntime::lua_history_forward(lua_State *state) { qsizetype history_index = lua_isnoneornil(state, 1) ? 1 : lua_tointeger(state, 1); - WebViewId tab_id; - if (lua_isnoneornil(state, 2)) { - tab_id = runtime->fetch_current_tab_id(); - } else { - tab_id = lua_tointeger(state, 2); - } + WebViewId tab_id = lua_isnoneornil(state, 2) ? 0 : lua_tointeger(state, 2); emit runtime->history_forward_requested(tab_id, history_index); return 1; @@ -238,12 +227,7 @@ int LuaRuntime::lua_history_forward(lua_State *state) { int LuaRuntime::lua_tab_close(lua_State *state) { auto *runtime = LuaRuntime::instance(); - WebViewId tab_id; - if (lua_isnoneornil(state, 1)) { - tab_id = runtime->fetch_current_tab_id(); - } else { - tab_id = lua_tointeger(state, 1); - } + WebViewId tab_id = lua_isnoneornil(state, 1) ? 0 : lua_tointeger(state, 1); emit runtime->webview_closed(tab_id); return 1; diff --git a/src/LuaRuntime.hpp b/src/LuaRuntime.hpp index e534d0e..7ad96df 100644 --- a/src/LuaRuntime.hpp +++ b/src/LuaRuntime.hpp @@ -42,6 +42,7 @@ public: signals: void evaluation_completed(QVariant value); void evaluation_failed(QString value); + 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()>); diff --git a/src/WindowActionRouter.cpp b/src/WindowActionRouter.cpp new file mode 100644 index 0000000..160164d --- /dev/null +++ b/src/WindowActionRouter.cpp @@ -0,0 +1,73 @@ +#include <QWidget> +#include <QtCore> + +#include "LuaRuntime.hpp" +#include "WindowActionRouter.hpp" + +WindowActionRouter::WindowActionRouter() { + auto *runtime = LuaRuntime::instance(); + + connect(runtime, &LuaRuntime::keymap_added, this, + [this](const QString &mode, const QString &keyseq, + const std::function<void()> &callback) { + for (auto &win : window_map) { + auto *mediator = win.second->mediator(); + emit mediator->keymap_added(mode, keyseq, callback); + } + }); + + connect(runtime, &LuaRuntime::history_back_requested, this, + [this](WebViewId webview_id, qsizetype history_index) { + for (auto &win : window_map) { + auto *mediator = win.second->mediator(); + qDebug() << "BACK" << webview_id; + if (mediator->has_webview(webview_id)) { + emit mediator->history_back_requested(webview_id, + history_index); + } + } + }); + connect(runtime, &LuaRuntime::history_forward_requested, this, + [this](WebViewId webview_id, qsizetype history_index) { + for (auto &win : window_map) { + auto *mediator = win.second->mediator(); + if (mediator->has_webview(webview_id)) { + emit mediator->history_forward_requested(webview_id, + history_index); + } + } + }); + + connect(runtime, &LuaRuntime::url_opened, this, + [this](const QString &url, OpenType open_type) { + for (auto &win : window_map) { + auto *mediator = win.second->mediator(); + emit mediator->url_opened(url, open_type); + } + }); + connect(runtime, &LuaRuntime::webview_closed, this, + [this](WebViewId webview_id) { + for (auto &win : window_map) { + auto *mediator = win.second->mediator(); + if (mediator->has_webview(webview_id)) { + emit mediator->webview_closed(webview_id); + } + } + }); + connect(runtime, &LuaRuntime::webview_selected, this, + [this](WebViewId webview_id) { + for (auto &win : window_map) { + auto *mediator = win.second->mediator(); + if (mediator->has_webview(webview_id)) { + emit mediator->webview_selected(webview_id); + } + } + }); +} + +void WindowActionRouter::add_window(BrowserWindow *window) { + window_map.insert({last_id, window}); + last_id++; +} + +const WindowMap &WindowActionRouter::windows() { return window_map; } diff --git a/src/WindowActionRouter.hpp b/src/WindowActionRouter.hpp new file mode 100644 index 0000000..b6cd731 --- /dev/null +++ b/src/WindowActionRouter.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "widgets/BrowserWindow.hpp" +#include <QWidget> +#include <QtCore> +#include <cstdint> +#include <unordered_map> + +using WindowId = uint64_t; +using WindowMap = std::unordered_map<uint64_t, BrowserWindow *>; + +class WindowActionRouter : public QWidget { + Q_OBJECT + +public: + static WindowActionRouter *instance() { + static auto *router = new WindowActionRouter; + return router; + } + + void add_window(BrowserWindow *window); + const WindowMap &windows(); + +protected: + WindowActionRouter(); + +private: + WindowMap window_map; + uint64_t last_id = 1; +}; diff --git a/src/InputMediator.cpp b/src/WindowMediator.cpp index 175a1b4..8c49e94 100644 --- a/src/InputMediator.cpp +++ b/src/WindowMediator.cpp @@ -2,30 +2,30 @@ #include <QWidget> #include <QtCore> -#include "InputMediator.hpp" #include "LuaRuntime.hpp" +#include "WindowMediator.hpp" #include "keymap/KeymapEvaluator.hpp" #include "widgets/WebViewStack.hpp" -// TODO: Rename this -InputMediator::InputMediator(WebViewStack *webview_stack, - LuaRuntime *lua_runtime, - KeymapEvaluator *keymap_evaluator) +WindowMediator::WindowMediator(WebViewStack *webview_stack, + LuaRuntime *lua_runtime, + KeymapEvaluator *keymap_evaluator) : webview_stack(webview_stack), lua_runtime(lua_runtime), keymap_evaluator(keymap_evaluator) { - connect(lua_runtime, &LuaRuntime::keymap_added, this, - &InputMediator::add_keymap); - connect(lua_runtime, &LuaRuntime::history_back_requested, webview_stack, + connect(this, &WindowMediator::keymap_added, this, + &WindowMediator::add_keymap); + + connect(this, &WindowMediator::history_back_requested, webview_stack, &WebViewStack::webview_history_back); - connect(lua_runtime, &LuaRuntime::history_forward_requested, webview_stack, + connect(this, &WindowMediator::history_forward_requested, webview_stack, &WebViewStack::webview_history_forward); - connect(lua_runtime, &LuaRuntime::url_opened, webview_stack, + connect(this, &WindowMediator::url_opened, webview_stack, &WebViewStack::open_url); - connect(lua_runtime, &LuaRuntime::webview_closed, webview_stack, + connect(this, &WindowMediator::webview_closed, webview_stack, &WebViewStack::close); - connect(lua_runtime, &LuaRuntime::webview_selected, webview_stack, + connect(this, &WindowMediator::webview_selected, webview_stack, &WebViewStack::focus_webview); // TODO: Think of how to handle this for multi-window @@ -35,11 +35,11 @@ InputMediator::InputMediator(WebViewStack *webview_stack, [this]() { return this->webview_stack->get_webview_list(); }); } -void InputMediator::add_keymap(const QString &mode_string, - const QString &keyseq, - std::function<void()> action) { +void WindowMediator::add_keymap(const QString &mode_string, + const QString &keyseq, + std::function<void()> action) { const KeyMode mode = keymap_evaluator->mode_from_string(mode_string); keymap_evaluator->add_keymap(mode, keyseq, std::move(action)); } -InputMediator::~InputMediator() { delete webview_stack; } +WindowMediator::~WindowMediator() { delete webview_stack; } diff --git a/src/WindowMediator.hpp b/src/WindowMediator.hpp new file mode 100644 index 0000000..3c35de2 --- /dev/null +++ b/src/WindowMediator.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include <QWidget> +#include <QtCore> + +#include "LuaRuntime.hpp" +#include "keymap/KeymapEvaluator.hpp" +#include "utils.hpp" +#include "widgets/WebViewStack.hpp" + +class WindowMediator : public QObject { + Q_OBJECT + +public: + WindowMediator(WebViewStack *webview_stack, LuaRuntime *lua_runtime, + KeymapEvaluator *keymap_evaluator); + ~WindowMediator() override; + + DELEGATE(keymap_evaluator, evaluate, evaluate_keymap) + DELEGATE(webview_stack, has_webview, has_webview) + +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 url_opened(QString url, OpenType open_type); + void webview_closed(WebViewId webview_id); + void webview_selected(WebViewId webview_id); + +protected slots: + void add_keymap(const QString &mode_string, const QString &keyseq, + std::function<void()> action); + +private: + WebViewStack *webview_stack; + LuaRuntime *lua_runtime; + KeymapEvaluator *keymap_evaluator; +}; diff --git a/src/keymap/KeymapEvaluator.cpp b/src/keymap/KeymapEvaluator.cpp index 912c84d..396e494 100644 --- a/src/keymap/KeymapEvaluator.cpp +++ b/src/keymap/KeymapEvaluator.cpp @@ -34,6 +34,7 @@ bool KeymapEvaluator::evaluate(Qt::KeyboardModifiers modifiers, Qt::Key key) { active_key_sequence); if (match_type == KeyMatchType::Match) { + qDebug() << "CALLED" << key; keymap.action(); active_key_sequence.clear(); return true; diff --git a/src/keymap/KeymapEvaluator.hpp b/src/keymap/KeymapEvaluator.hpp index 4f8184b..75ded60 100644 --- a/src/keymap/KeymapEvaluator.hpp +++ b/src/keymap/KeymapEvaluator.hpp @@ -23,6 +23,11 @@ class KeymapEvaluator : public QObject { public: KeymapEvaluator() = default; + static KeymapEvaluator *instance() { + static auto *keymap_evaluator = new KeymapEvaluator; + return keymap_evaluator; + } + void add_keymap(KeyMode mode, const QString &key, KeyAction action); bool evaluate(Qt::KeyboardModifiers modifiers, Qt::Key key); KeyMode mode_from_string(const QString &mode_string); diff --git a/src/main.cpp b/src/main.cpp index 9409583..8c30b31 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,5 +9,8 @@ int main(int argc, char *argv[]) { browser.create_window(); browser.create_window(); + // NOTE: TMP + LuaRuntime::instance()->load_file("./config.lua"); + return QApplication::exec(); } diff --git a/src/widgets/BrowserApp.cpp b/src/widgets/BrowserApp.cpp index 0a82de0..3cd06b4 100644 --- a/src/widgets/BrowserApp.cpp +++ b/src/widgets/BrowserApp.cpp @@ -2,8 +2,9 @@ #include <QtCore> #include "LuaRuntime.hpp" +#include "WindowActionRouter.hpp" #include "widgets/BrowserApp.hpp" -#include "widgets/MainWindow.hpp" +#include "widgets/BrowserWindow.hpp" BrowserApp::BrowserApp() { auto *lua = LuaRuntime::instance(); @@ -11,16 +12,13 @@ BrowserApp::BrowserApp() { // Global event filter qApp->installEventFilter(this); - - // NOTE: TMP - lua->load_file("./config.lua"); }; -MainWindow *BrowserApp::create_window() { - auto *win = new MainWindow((const Configuration &)configuration); +BrowserWindow *BrowserApp::create_window() { + auto *win = new BrowserWindow((const Configuration &)configuration); win->setWindowTitle("null-browser"); - windows.insert({last_id, win}); - last_id++; + auto *router = WindowActionRouter::instance(); + router->add_window(win); win->show(); return win; } @@ -29,7 +27,7 @@ bool BrowserApp::eventFilter(QObject *target, QEvent *event) { if (event->type() != QEvent::KeyPress) return false; - for (auto &match : windows) { + for (const auto &match : WindowActionRouter::instance()->windows()) { auto *win = match.second; if (auto *target_widget = dynamic_cast<QWidget *>(target); diff --git a/src/widgets/BrowserApp.hpp b/src/widgets/BrowserApp.hpp index e4fcf99..f124a71 100644 --- a/src/widgets/BrowserApp.hpp +++ b/src/widgets/BrowserApp.hpp @@ -1,8 +1,6 @@ #pragma once -#include <unordered_map> - -#include "widgets/MainWindow.hpp" +#include "widgets/BrowserWindow.hpp" class BrowserApp : public QObject { Q_OBJECT @@ -10,14 +8,11 @@ class BrowserApp : public QObject { public: BrowserApp(); - MainWindow *create_window(); + BrowserWindow *create_window(); protected: bool eventFilter(QObject *target, QEvent *event) override; private: - std::unordered_map<uint64_t, MainWindow *> windows; - uint64_t last_id = 1; - Configuration configuration; }; diff --git a/src/widgets/MainWindow.cpp b/src/widgets/BrowserWindow.cpp index 2d17557..3ff4d3c 100644 --- a/src/widgets/MainWindow.cpp +++ b/src/widgets/BrowserWindow.cpp @@ -4,15 +4,14 @@ #include <QtCore> #include "Configuration.hpp" -#include "InputMediator.hpp" +#include "WindowMediator.hpp" #include "keymap/KeymapEvaluator.hpp" -#include "widgets/MainWindow.hpp" +#include "widgets/BrowserWindow.hpp" #include "widgets/WebViewStack.hpp" -MainWindow::MainWindow(const Configuration &configuration) +BrowserWindow::BrowserWindow(const Configuration &configuration) : configuration(configuration) { - setStyleSheet("background-color: #000; color: #fff;"); - setCentralWidget(new QWidget()); // TODO: manage widget memory + setCentralWidget(new QWidget()); // Root stacked layout auto *layout = new QStackedLayout(); @@ -26,10 +25,7 @@ MainWindow::MainWindow(const Configuration &configuration) new WebViewStack(&configuration, new QWebEngineProfile("null-browser")); layout->addWidget(web_view_stack); - auto *keymap_evaluator = new KeymapEvaluator; - - input_mediator = new InputMediator(web_view_stack, LuaRuntime::instance(), - keymap_evaluator); + auto *keymap_evaluator = KeymapEvaluator::instance(); // TODO: remoev web_view_stack->open_url(QUrl("https://duckduckgo.com"), OpenType::OpenUrl); @@ -47,9 +43,12 @@ MainWindow::MainWindow(const Configuration &configuration) }); keymap_evaluator->add_keymap(KeyMode::Normal, "<c-t>a", []() { qDebug() << "Stuff"; }); + + input_mediator = new WindowMediator(web_view_stack, LuaRuntime::instance(), + keymap_evaluator); } -bool MainWindow::on_window_key_event(QKeyEvent *event) { +bool BrowserWindow::on_window_key_event(QKeyEvent *event) { const bool should_skip = input_mediator->evaluate_keymap( event->modifiers(), (Qt::Key)event->key()); diff --git a/src/widgets/BrowserWindow.hpp b/src/widgets/BrowserWindow.hpp new file mode 100644 index 0000000..6036ec1 --- /dev/null +++ b/src/widgets/BrowserWindow.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include <QMainWindow> + +#include "Configuration.hpp" +#include "WindowMediator.hpp" +#include "utils.hpp" + +class BrowserWindow : public QMainWindow { +public: + BrowserWindow(const Configuration &configuration); + + DEFINE_GETTER(mediator, input_mediator) + + bool on_window_key_event(QKeyEvent *event); + +private: + WindowMediator *input_mediator; + const Configuration &configuration; +}; diff --git a/src/widgets/MainWindow.hpp b/src/widgets/MainWindow.hpp deleted file mode 100644 index 7aaca2b..0000000 --- a/src/widgets/MainWindow.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include <QMainWindow> - -#include "Configuration.hpp" -#include "InputMediator.hpp" - -class MainWindow : public QMainWindow { -public: - MainWindow(const Configuration &configuration); - - bool on_window_key_event(QKeyEvent *event); - -private: - InputMediator *input_mediator; - const Configuration &configuration; -}; diff --git a/src/widgets/WebViewStack.cpp b/src/widgets/WebViewStack.cpp index aee4af9..f1c799f 100644 --- a/src/widgets/WebViewStack.cpp +++ b/src/widgets/WebViewStack.cpp @@ -36,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(next_id++, profile); + auto *webview = new WebView(next_webview_id++, profile); webview->setUrl(url); layout->addWidget(webview); webview_list.append(webview); @@ -77,6 +77,9 @@ void WebViewStack::on_new_webview_request( } int32_t WebViewStack::get_webview_index(WebViewId webview_id) { + if (webview_id == 0 && window()->isActiveWindow()) + webview_id = current_webview_id(); + int index = 0; for (auto &webview : webview_list) { if (webview->get_id() == webview_id) @@ -177,6 +180,10 @@ WebView *WebViewStack::get_webview(WebViewId webview_id) { return webview_list.at(webview_index); } +bool WebViewStack::has_webview(WebViewId webview_id) { + return get_webview(webview_id) != nullptr; +} + QUrl WebViewStack::current_url() { auto *webview = current_webview(); if (webview == nullptr) { diff --git a/src/widgets/WebViewStack.hpp b/src/widgets/WebViewStack.hpp index 9df088e..f9ce397 100644 --- a/src/widgets/WebViewStack.hpp +++ b/src/widgets/WebViewStack.hpp @@ -23,6 +23,8 @@ struct WebViewData { QString title; }; +static WebViewId next_webview_id = 1; + class WebViewStack : public QWidget { Q_OBJECT @@ -37,6 +39,8 @@ public: uint32_t count(); QUrl current_url(); + bool has_webview(WebViewId webview_id); + /// @deprecated TODO: Remove std::vector<QUrl> urls(); /// @deprecated TODO: Remove @@ -63,5 +67,4 @@ private: QWebEngineProfile *profile; QStackedLayout *layout; QList<WebView *> webview_list; - WebViewId next_id = 1; }; |
