aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2025-03-29 11:45:18 +0530
committerAkshay Nair <phenax5@gmail.com>2025-03-29 11:45:18 +0530
commitbcecbced7e1af9d99443a7e823f18328c7943f09 (patch)
tree612fac477acfa38358e15916bd4a44f386dc9206 /src
parentf7392096d2d84be7143947d386528bf4f487ee83 (diff)
downloadnull-browser-bcecbced7e1af9d99443a7e823f18328c7943f09.tar.gz
null-browser-bcecbced7e1af9d99443a7e823f18328c7943f09.zip
Add window action router for multi-window
Diffstat (limited to '')
-rw-r--r--src/InputMediator.hpp29
-rw-r--r--src/LuaRuntime.cpp22
-rw-r--r--src/LuaRuntime.hpp1
-rw-r--r--src/WindowActionRouter.cpp73
-rw-r--r--src/WindowActionRouter.hpp30
-rw-r--r--src/WindowMediator.cpp (renamed from src/InputMediator.cpp)32
-rw-r--r--src/WindowMediator.hpp38
-rw-r--r--src/keymap/KeymapEvaluator.cpp1
-rw-r--r--src/keymap/KeymapEvaluator.hpp5
-rw-r--r--src/main.cpp3
-rw-r--r--src/widgets/BrowserApp.cpp16
-rw-r--r--src/widgets/BrowserApp.hpp9
-rw-r--r--src/widgets/BrowserWindow.cpp (renamed from src/widgets/MainWindow.cpp)19
-rw-r--r--src/widgets/BrowserWindow.hpp20
-rw-r--r--src/widgets/MainWindow.hpp17
-rw-r--r--src/widgets/WebViewStack.cpp9
-rw-r--r--src/widgets/WebViewStack.hpp5
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;
};