diff options
| author | Akshay Nair <phenax5@gmail.com> | 2025-04-05 23:45:55 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2025-04-06 00:47:02 +0530 |
| commit | bbde1438e9c31cc83d8c4835ea97a0eaeae4e192 (patch) | |
| tree | 88840b73176dee8bd7da70c36f19a32bafdd5d6c | |
| parent | b77a6444f94ce8d05962af9039c31851e224be5c (diff) | |
| download | null-browser-bbde1438e9c31cc83d8c4835ea97a0eaeae4e192.tar.gz null-browser-bbde1438e9c31cc83d8c4835ea97a0eaeae4e192.zip | |
Close window when no tabs left
Diffstat (limited to '')
| -rw-r--r-- | TODO.org | 4 | ||||
| -rw-r--r-- | config.lua | 7 | ||||
| -rw-r--r-- | lua/null-browser/extras/dmenu.lua | 3 | ||||
| -rw-r--r-- | lua/null-browser/extras/history.lua | 4 | ||||
| -rw-r--r-- | spec/WebViewStackSpec.cpp | 9 | ||||
| -rw-r--r-- | src/Configuration.hpp | 2 | ||||
| -rw-r--r-- | src/WindowActionRouter.cpp | 18 | ||||
| -rw-r--r-- | src/WindowActionRouter.hpp | 2 | ||||
| -rw-r--r-- | src/WindowMediator.cpp | 14 | ||||
| -rw-r--r-- | src/WindowMediator.hpp | 1 | ||||
| -rw-r--r-- | src/widgets/BrowserWindow.cpp | 3 | ||||
| -rw-r--r-- | src/widgets/WebViewStack.cpp | 11 | ||||
| -rw-r--r-- | src/widgets/WebViewStack.hpp | 1 |
13 files changed, 54 insertions, 25 deletions
@@ -18,7 +18,8 @@ - [X] Url changed event - [X] History storage - [X] History completion -- [ ] Close window if last tab closed +- [X] Close window if last tab closed +- [ ] Configuration lua api - [ ] Switch to __internals - [ ] Tests for api - [ ] Log stdout, errors and results from lua somewhere @@ -88,4 +89,5 @@ web.history.back(1, { win = 1 }) -- Back for current tab in win 1 web.keymap.set('n', '<c-r>', ..., { tab = 1 }) -- Set keymap for tab 1 web.keymap.set('n', '<c-r>', ..., { win = 1 }) -- Set keymap for win 1 +web.opt.new_tab_url = 'https://duckduckgo.com' #+end_src @@ -43,6 +43,13 @@ web.keymap.set('n', '<s-o>', function() web.tabs.set_url(trim(result)) end) end) +-- Delete from history +web.keymap.set('n', '<c-h>d', function() + dmenu.select(history.list(), { prompt = 'Delete history:' }, function(err, result) + if err or not result then return end + history.delete(trim(result)) + end) +end) -- Update current url web.keymap.set('n', '<c-l>', function() local tabs = web.tabs.list() diff --git a/lua/null-browser/extras/dmenu.lua b/lua/null-browser/extras/dmenu.lua index 1bd467f..d08eb6a 100644 --- a/lua/null-browser/extras/dmenu.lua +++ b/lua/null-browser/extras/dmenu.lua @@ -1,3 +1,6 @@ +--- @type table +local uv = uv + local dmenu = {} function dmenu.select(list, opts, callback) diff --git a/lua/null-browser/extras/history.lua b/lua/null-browser/extras/history.lua index fe3f72f..4304dc0 100644 --- a/lua/null-browser/extras/history.lua +++ b/lua/null-browser/extras/history.lua @@ -14,7 +14,7 @@ function history.list() for line in string.gmatch(data, '[^\r\n]+') do local already_exists = false for _, url in ipairs(urls) do - if url == line then already_exists = true end + if url == line or url .. '/' == line then already_exists = true end end if #urls >= history.max_entires then break end if not already_exists then @@ -43,7 +43,7 @@ end function history.delete(url_to_delete) history.update(function(urls) - for index, url in urls do + for index, url in ipairs(urls) do if url == url_to_delete then table.remove(urls, index) return urls diff --git a/spec/WebViewStackSpec.cpp b/spec/WebViewStackSpec.cpp index 0559b43..0563a5f 100644 --- a/spec/WebViewStackSpec.cpp +++ b/spec/WebViewStackSpec.cpp @@ -132,18 +132,17 @@ private slots: context("when close is called on current webview"); context("- and there is only 1 tab"); - it("closes the tab and opens empty tab in its place") { + it("requests closing window") { Configuration configuration; WebViewStack webview_stack(&configuration); + QSignalSpy close_window_requested_spy(&webview_stack, &WebViewStack::close_window_requested); webview_stack.open_url(QUrl("https://a.com")); QCOMPARE(webview_stack.count(), 1); webview_stack.close(webview_stack.current_webview_id()); + close_window_requested_spy.wait(100); - QCOMPARE(webview_stack.count(), 1); - QCOMPARE(webview_stack.urls(), (std::vector<QUrl>{configuration.new_tab_url})); - QCOMPARE(webview_stack.current_webview_index(), 0); - QCOMPARE(webview_stack.current_url(), configuration.new_tab_url); + QCOMPARE(close_window_requested_spy.count(), 1); } context("when close is called"); diff --git a/src/Configuration.hpp b/src/Configuration.hpp index 032d12e..837e3e6 100644 --- a/src/Configuration.hpp +++ b/src/Configuration.hpp @@ -9,4 +9,6 @@ public: using QObject::QObject; QUrl new_tab_url = QUrl("https://lite.duckduckgo.com"); + + bool close_window_when_no_tabs = true; }; diff --git a/src/WindowActionRouter.cpp b/src/WindowActionRouter.cpp index c1051ad..d1cd816 100644 --- a/src/WindowActionRouter.cpp +++ b/src/WindowActionRouter.cpp @@ -46,9 +46,21 @@ void WindowActionRouter::add_window(BrowserWindow *window) { auto win_id = last_id; last_id++; - window_map.insert({win_id, window}); window->set_id(win_id); - connect(window, &BrowserWindow::closed, this, [this, win_id]() { window_map.erase(win_id); }); + { + const std::lock_guard<std::mutex> lock(window_map_mutex); + window_map.insert({win_id, window}); + } + + connect(window, &BrowserWindow::closed, this, [this, window]() { + window->disconnect(); + LuaRuntime::instance().queue_task([this, window]() { + const std::lock_guard<std::mutex> lock(window_map_mutex); + window_map.erase(window->get_id()); + }); + }); + connect(window->mediator(), &WindowMediator::close_window_requested, window, + [window]() { window->close(); }); connect(window->mediator(), &WindowMediator::new_window_requested, this, &WindowActionRouter::new_window_requested); } @@ -63,6 +75,7 @@ void WindowActionRouter::add_keymap(const QString &mode_string, const QString &k } WebViewId WindowActionRouter::fetch_current_tab_id(WindowId win_id) { + const std::lock_guard<std::mutex> lock(window_map_mutex); for (auto &pair : window_map) { auto *win = pair.second; auto is_current_window = win_id == win->get_id() || (win_id == 0 && win->isActiveWindow()); @@ -74,6 +87,7 @@ WebViewId WindowActionRouter::fetch_current_tab_id(WindowId win_id) { } QList<WebViewData> WindowActionRouter::fetch_webview_data_list(WindowId win_id) { + const std::lock_guard<std::mutex> lock(window_map_mutex); for (auto &pair : window_map) { auto *win = pair.second; auto is_current_window = win_id == win->get_id() || (win_id == 0 && win->isActiveWindow()); diff --git a/src/WindowActionRouter.hpp b/src/WindowActionRouter.hpp index c72aaaf..3c82b28 100644 --- a/src/WindowActionRouter.hpp +++ b/src/WindowActionRouter.hpp @@ -4,6 +4,7 @@ #include <QtCore> #include <cstdint> #include <functional> +#include <mutex> #include "EventQueue.hpp" #include "widgets/BrowserWindow.hpp" @@ -46,6 +47,7 @@ signals: void new_window_requested(const QUrl &url); private: + std::mutex window_map_mutex; WindowMap window_map; uint64_t last_id = 1; Configuration *configuration; diff --git a/src/WindowMediator.cpp b/src/WindowMediator.cpp index 0596d28..942207d 100644 --- a/src/WindowMediator.cpp +++ b/src/WindowMediator.cpp @@ -5,23 +5,21 @@ #include "WindowMediator.hpp" #include "widgets/WebViewStack.hpp" -WindowMediator::WindowMediator(WebViewStack *webview_stack) - : webview_stack(webview_stack) { +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); + 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, + &WindowMediator::close_window_requested); } WindowMediator::~WindowMediator() { diff --git a/src/WindowMediator.hpp b/src/WindowMediator.hpp index e8050e9..ea1dd52 100644 --- a/src/WindowMediator.hpp +++ b/src/WindowMediator.hpp @@ -24,6 +24,7 @@ signals: void webview_closed(WebViewId webview_id); void webview_selected(WebViewId webview_id); void new_window_requested(const QUrl &url); + void close_window_requested(); private: WebViewStack *webview_stack; diff --git a/src/widgets/BrowserWindow.cpp b/src/widgets/BrowserWindow.cpp index aad551d..f1b786b 100644 --- a/src/widgets/BrowserWindow.cpp +++ b/src/widgets/BrowserWindow.cpp @@ -2,6 +2,7 @@ #include <QStackedLayout> #include <QVBoxLayout> #include <QtCore> +#include <qmainwindow.h> #include "Configuration.hpp" #include "WindowMediator.hpp" @@ -10,7 +11,7 @@ #include "widgets/WebViewStack.hpp" BrowserWindow::BrowserWindow(const Configuration &configuration, const QStringList &urls) - : configuration(configuration) { + : QMainWindow(nullptr), configuration(configuration) { setCentralWidget(new QWidget()); // Root stacked layout diff --git a/src/widgets/WebViewStack.cpp b/src/widgets/WebViewStack.cpp index ae95ea6..8c432f1 100644 --- a/src/widgets/WebViewStack.cpp +++ b/src/widgets/WebViewStack.cpp @@ -125,13 +125,12 @@ void WebViewStack::close(WebViewId webview_id) { disconnect(webview->page()); webview->deleteLater(); - // TODO: Focus on different webview - // focus_webview(); - - // TODO: Close window on empty if (webview_list.isEmpty()) { - // window()->close(); - create_new_webview(configuration->new_tab_url, true); + if (configuration->close_window_when_no_tabs) { + emit close_window_requested(); + } else { + create_new_webview(configuration->new_tab_url, true); + } } } diff --git a/src/widgets/WebViewStack.hpp b/src/widgets/WebViewStack.hpp index 23b9382..7cc2143 100644 --- a/src/widgets/WebViewStack.hpp +++ b/src/widgets/WebViewStack.hpp @@ -47,6 +47,7 @@ public: signals: void current_webview_title_changed(int index); void new_window_requested(const QUrl &url); + void close_window_requested(); protected: void set_current_url(const QUrl &url); |
