diff options
| author | Felix (xq) Queißner <git@mq32.de> | 2021-03-06 15:26:07 +0100 |
|---|---|---|
| committer | Felix (xq) Queißner <git@mq32.de> | 2021-03-06 15:26:07 +0100 |
| commit | 9457e720f24d8365ed6a1e82b016078b0bc17eb6 (patch) | |
| tree | d810dcd8189ce508a9a0e666f7d819f3c63bcbca /src | |
| parent | e16c85887a58381f225d706a8d740bf96a5fdf6a (diff) | |
| download | kristall-9457e720f24d8365ed6a1e82b016078b0bc17eb6.tar.gz | |
Implements proper multi-window support.
Diffstat (limited to 'src')
| -rw-r--r-- | src/about/updates.gemini | 5 | ||||
| -rw-r--r-- | src/kristall.hpp | 15 | ||||
| -rw-r--r-- | src/main.cpp | 98 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 56 | ||||
| -rw-r--r-- | src/mainwindow.hpp | 7 | ||||
| -rw-r--r-- | src/mainwindow.ui | 54 |
6 files changed, 178 insertions, 57 deletions
diff --git a/src/about/updates.gemini b/src/about/updates.gemini index c0d3f1f..46a9445 100644 --- a/src/about/updates.gemini +++ b/src/about/updates.gemini @@ -16,7 +16,10 @@ -- There's a lot missing here still -* Adds single-session mode so opening links will open them in the currently focuse kristall window instead of a new instance every time. +* Adds single-session mode so opening links will open them in the currently focused window instead of a new instance every time. +* Adds the option to open multiple kristall windows in one session. +* Adds --new-window command line option to open urls into a new kristall window instead of opening them as a new tab +* Adds --isolated command line option to start a separated instance of kristall ## 0.3 - TLS and security * Adds support for transient client certificates diff --git a/src/kristall.hpp b/src/kristall.hpp index 88ae95d..f9d1c15 100644 --- a/src/kristall.hpp +++ b/src/kristall.hpp @@ -148,6 +148,10 @@ namespace kristall extern QDir styles; } + //! Forwards the current settings to all windows + void applySettings(); + + //! Saves the current settings to disk void saveSettings(); void setTheme(Theme theme); @@ -162,6 +166,17 @@ namespace kristall //! that can be tracked by the application. void registerAppWindow(MainWindow * window); + //! Opens a new window with the default page open. + //! @param load_default Loads the default/start page instead of about:blank + MainWindow * openNewWindow(bool load_default); + + //! Opens a new window with the given url. + MainWindow * openNewWindow(QUrl const & url); + + //! Opens a new window with the given list of urls. + //! If the list is empty, no new tab will spawned. + MainWindow * openNewWindow(QVector<QUrl> const & urls); + extern QString default_font_family, default_font_family_fixed; //! Whether emojis are supprted in current build configuration diff --git a/src/main.cpp b/src/main.cpp index 5bc2426..e1098bd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -115,10 +115,27 @@ void forAllAppWindows(F const & f) MainWindow * getFocusedAppWindow() { assert(qApp != nullptr); + // first, check if we have currently active window: auto * main_window = qobject_cast<MainWindow *>(qApp->activeWindow()); if(main_window != nullptr) return main_window; - return last_focused_window; + + // if not, fall back to the window we focused last: + if(::last_focused_window != nullptr) + return ::last_focused_window; + + // and if we have none, we just take the first window we can find if + // any: + forAllAppWindows([&main_window](MainWindow * w) { + if(main_window == nullptr) + main_window = w; + }); + if(main_window != nullptr) + return main_window; + + qCritical() << "could not find a focused/foreground window!"; + + return main_window; } @@ -234,18 +251,17 @@ namespace ipc break; } case Message::open_in_window: { - auto * const window = getFocusedAppWindow(); + QVector<QUrl> urls; for(auto const & data : payload.split('\n')) { QUrl url { QString::fromUtf8(data) }; if(url.isValid()) { - // TODO: Implement opening these urls in a new - // window instead of a new tab! - if(window != nullptr) { - window->addNewTab(true, url); - } + urls.append(url); } } + if(urls.size() > 0) { + kristall::openNewWindow(urls); + } break; } @@ -311,6 +327,36 @@ void kristall::registerAppWindow(MainWindow * window) }); } +MainWindow * kristall::openNewWindow(bool load_default) +{ + auto * const window = openNewWindow(QVector<QUrl>{}); + window->addEmptyTab(true, load_default); + return window; +} + +//! Opens a new window with the given url. +MainWindow * kristall::openNewWindow(QUrl const & url) +{ + return openNewWindow(QVector<QUrl>{url}); +} + +//! Opens a new window with the given list of urls. +//! If the list is empty, no new tab will spawned. +MainWindow * kristall::openNewWindow(QVector<QUrl> const & urls) +{ + MainWindow * const window = new MainWindow(qApp); + + for(int i = 0; i < urls.length(); i++) + { + window->addNewTab((i == 0), urls.at(i)); + } + + window->show(); + + return window; +} + + int main(int argc, char *argv[]) { QApplication app(argc, argv); @@ -461,7 +507,7 @@ int main(int argc, char *argv[]) QSettings app_settings { kristall::dirs::config_root.absoluteFilePath("config.ini"), - QSettings::IniFormat + QSettings::IniFormat }; app_settings_ptr = &app_settings; @@ -613,8 +659,6 @@ int main(int argc, char *argv[]) kristall::setTheme(kristall::options.theme); - MainWindow w(&app); - if(ipc_server != nullptr) { QObject::connect(ipc_server.get(), &QLocalServer::newConnection, [&ipc_server]() { auto * const socket = ipc_server->nextPendingConnection(); @@ -632,24 +676,20 @@ int main(int argc, char *argv[]) // Open all URLs in the new window if(urls.size() > 0) { - for(const auto & url : urls) { - w.addNewTab(false, url); - } + kristall::openNewWindow(urls); } else { - w.addEmptyTab(true, true); + kristall::openNewWindow(true); } - app_settings.beginGroup("Window State"); - if(app_settings.contains("geometry")) { - w.restoreGeometry(app_settings.value("geometry").toByteArray()); - } - if(app_settings.contains("state")) { - w.restoreState(app_settings.value("state").toByteArray()); - } - app_settings.endGroup(); - - w.show(); + //app_settings.beginGroup("Window State"); + //if(app_settings.contains("geometry")) { + // w.restoreGeometry(app_settings.value("geometry").toByteArray()); + //} + //if(app_settings.contains("state")) { + // w.restoreState(app_settings.value("state").toByteArray()); + //} + //app_settings.endGroup(); int exit_code = app.exec(); @@ -780,6 +820,16 @@ void GenericSettings::save(QSettings &settings) const } } +void kristall::applySettings() +{ + kristall::setTheme(kristall::options.theme); + kristall::setUiDensity(kristall::options.ui_density, false); + + forAllAppWindows([](MainWindow * window) + { + window->applySettings(); + }); +} void kristall::saveSettings() { diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index bd33153..6f39b42 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -253,7 +253,8 @@ void MainWindow::setUiDensity(UIDensity density, bool previewing) if (previewing) { - if (!this->curTab()) return; + if (not this->curTab()) + return; this->curTab()->setUiDensity(density); } else @@ -278,6 +279,27 @@ QString MainWindow::newGroupDialog() return dialog.textValue(); } +void MainWindow::applySettings() +{ + // Flag open tabs for re-render so theme + // changes are instantly applied. + for (int i = 0; i < this->ui->browser_tabs->count(); ++i) + { + BrowserTab *t = this->tabAt(i); + t->refreshOptionalToolbarItems(); + t->refreshToolbarIcons(); + t->needs_rerender = true; + } + + // Re-render the currently-open tab if we have one. + BrowserTab * tab = this->curTab(); + if (tab) + tab->rerenderPage(); + + // Update new-tab button visibility. + this->ui->browser_tabs->tab_bar->new_tab_btn->setVisible(kristall::options.enable_newtab_btn); +} + void MainWindow::mousePressEvent(QMouseEvent *event) { QMainWindow::mousePressEvent(event); @@ -439,27 +461,9 @@ void MainWindow::on_actionSettings_triggered() kristall::protocols = dialog.protocols(); kristall::document_style = dialog.geminiStyle(); - kristall::saveSettings(); - - kristall::setTheme(kristall::options.theme); - this->setUiDensity(kristall::options.ui_density, false); + kristall::applySettings(); - // Flag open tabs for re-render so theme - // changes are instantly applied. - for (int i = 0; i < this->ui->browser_tabs->count(); ++i) - { - BrowserTab *t = this->tabAt(i); - t->refreshOptionalToolbarItems(); - t->refreshToolbarIcons(); - t->needs_rerender = true; - } - // Re-render the currently-open tab if we have one. - BrowserTab * tab = this->curTab(); - if (tab) tab->rerenderPage(); - - // Update new-tab button visibility. - this->ui->browser_tabs->tab_bar->new_tab_btn - ->setVisible(kristall::options.enable_newtab_btn); + kristall::saveSettings(); } void MainWindow::on_actionNew_Tab_triggered() @@ -777,3 +781,13 @@ void MainWindow::on_actionShow_document_source_triggered() { this->viewPageSource(); } + +void MainWindow::on_actionNew_window_triggered() +{ + kristall::openNewWindow(false); +} + +void MainWindow::on_actionClose_Window_triggered() +{ + this->deleteLater(); +} diff --git a/src/mainwindow.hpp b/src/mainwindow.hpp index 7113587..a268ec7 100644 --- a/src/mainwindow.hpp +++ b/src/mainwindow.hpp @@ -45,6 +45,9 @@ public: QString newGroupDialog(); + //! Applies setting changes to the window. + void applySettings(); + void mousePressEvent(QMouseEvent *event) override; void closeEvent(QCloseEvent *event) override; @@ -100,6 +103,10 @@ private slots: void on_actionShow_document_source_triggered(); + void on_actionNew_window_triggered(); + + void on_actionClose_Window_triggered(); + private: // slots void on_tab_fileLoaded(DocumentStats const & stats); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 48c6bfc..2659a65 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -189,6 +189,7 @@ <string>File</string> </property> <addaction name="actionNew_Tab"/> + <addaction name="actionNew_window"/> <addaction name="separator"/> <addaction name="actionSave_as"/> <addaction name="actionClose_Tab"/> @@ -196,6 +197,7 @@ <addaction name="actionManage_Certificates"/> <addaction name="actionSettings"/> <addaction name="separator"/> + <addaction name="actionClose_Window"/> <addaction name="actionQuit"/> </widget> <widget class="QMenu" name="menuHelp"> @@ -236,7 +238,8 @@ </widget> <action name="actionAbout"> <property name="icon"> - <iconset theme="help-about"/> + <iconset theme="help-about"> + <normaloff>.</normaloff>.</iconset> </property> <property name="text"> <string>About...</string> @@ -244,7 +247,8 @@ </action> <action name="actionQuit"> <property name="icon"> - <iconset theme="application-exit"/> + <iconset theme="application-exit"> + <normaloff>.</normaloff>.</iconset> </property> <property name="text"> <string>Quit</string> @@ -263,7 +267,8 @@ </action> <action name="actionClose_Tab"> <property name="icon"> - <iconset theme="window-close"/> + <iconset theme="window-close"> + <normaloff>.</normaloff>.</iconset> </property> <property name="text"> <string>Close Tab</string> @@ -286,7 +291,8 @@ </action> <action name="actionBackward"> <property name="icon"> - <iconset theme="go-previous"/> + <iconset theme="go-previous"> + <normaloff>.</normaloff>.</iconset> </property> <property name="text"> <string>Back</string> @@ -300,7 +306,8 @@ </action> <action name="actionForward"> <property name="icon"> - <iconset theme="go-next"/> + <iconset theme="go-next"> + <normaloff>.</normaloff>.</iconset> </property> <property name="text"> <string>Forward</string> @@ -314,7 +321,8 @@ </action> <action name="actionRoot"> <property name="icon"> - <iconset theme="go-top"/> + <iconset theme="go-top"> + <normaloff>.</normaloff>.</iconset> </property> <property name="text"> <string>Root</string> @@ -328,7 +336,8 @@ </action> <action name="actionParent"> <property name="icon"> - <iconset theme="go-up"/> + <iconset theme="go-up"> + <normaloff>.</normaloff>.</iconset> </property> <property name="text"> <string>Parent</string> @@ -342,7 +351,8 @@ </action> <action name="actionRefresh"> <property name="icon"> - <iconset theme="view-refresh"/> + <iconset theme="view-refresh"> + <normaloff>.</normaloff>.</iconset> </property> <property name="text"> <string>Refresh</string> @@ -362,7 +372,8 @@ </action> <action name="actionSave_as"> <property name="icon"> - <iconset theme="document-save-as"/> + <iconset theme="document-save-as"> + <normaloff>.</normaloff>.</iconset> </property> <property name="text"> <string>Save as...</string> @@ -388,7 +399,8 @@ </action> <action name="actionGo_to_home"> <property name="icon"> - <iconset theme="go-home"/> + <iconset theme="go-home"> + <normaloff>.</normaloff>.</iconset> </property> <property name="text"> <string>Go to home</string> @@ -420,7 +432,8 @@ </action> <action name="actionManage_Certificates"> <property name="icon"> - <iconset theme="view-certificate"/> + <iconset theme="view-certificate"> + <normaloff>.</normaloff>.</iconset> </property> <property name="text"> <string>Manage Certificates…</string> @@ -434,6 +447,25 @@ <string>Ctrl+U</string> </property> </action> + <action name="actionNew_window"> + <property name="text"> + <string>New Window</string> + </property> + <property name="toolTip"> + <string>Opens a new window</string> + </property> + <property name="shortcut"> + <string>Ctrl+N</string> + </property> + </action> + <action name="actionClose_Window"> + <property name="text"> + <string>Close Window</string> + </property> + <property name="shortcut"> + <string>Alt+F4</string> + </property> + </action> </widget> <customwidgets> <customwidget> |
