diff --git a/src/MainApplicationWindow.qml b/src/MainApplicationWindow.qml index 17e3a9d09ebebb39c47b1f2430114ec2d48e4fe0..7808b21aab3a26a1f8039ff9a8546e52939d1468 100644 --- a/src/MainApplicationWindow.qml +++ b/src/MainApplicationWindow.qml @@ -52,6 +52,8 @@ ApplicationWindow { appContainer: appContainer } + property bool windowSettingsLoaded: false + function checkLoadedSource() { var sourceString = mainApplicationLoader.source.toString() @@ -80,35 +82,20 @@ ApplicationWindow { // is set, then we can quit if (force || !UtilsAdapter.getAppValue(Settings.MinimizeOnClose) || !UtilsAdapter.getAccountListSize()) { + // Save the window geometry and state before quitting. + var geometry = Qt.rect(appWindow.x, appWindow.y, + appWindow.width, appWindow.height) + AppSettingsManager.setValue(Settings.WindowGeometry, geometry) + AppSettingsManager.setValue(Settings.WindowState, appWindow.visibility) Qt.quit() - } else + } else { hide() + } } title: JamiStrings.appTitle - width: { - if (checkLoadedSource() === MainApplicationWindow.LoadedSource.WizardView) - return JamiTheme.wizardViewMinWidth - return JamiTheme.mainViewPreferredWidth - } - height: { - if (checkLoadedSource() === MainApplicationWindow.LoadedSource.WizardView) - return JamiTheme.wizardViewMinHeight - return JamiTheme.mainViewPreferredHeight - } - minimumWidth: { - if (checkLoadedSource() === MainApplicationWindow.LoadedSource.WizardView) - return JamiTheme.wizardViewMinWidth - return JamiTheme.mainViewMinWidth - } - minimumHeight: { - if (checkLoadedSource() === MainApplicationWindow.LoadedSource.WizardView) - return JamiTheme.wizardViewMinHeight - return JamiTheme.mainViewMinHeight - } - - visible: mainApplicationLoader.status === Loader.Ready + visible: mainApplicationLoader.status === Loader.Ready && windowSettingsLoaded // To facilitate reparenting of the callview during // fullscreen mode, we need QQuickItem based object. @@ -143,10 +130,47 @@ ApplicationWindow { } } + // Set `visible = false` when loading a new QML file. + onSourceChanged: windowSettingsLoaded = false + onLoaded: { if (UtilsAdapter.getAppValue(Settings.StartMinimized)) { showMinimized() + } else { + if (checkLoadedSource() === MainApplicationWindow.LoadedSource.WizardView) { + appWindow.width = JamiTheme.wizardViewMinWidth + appWindow.height = JamiTheme.wizardViewMinHeight + appWindow.minimumWidth = JamiTheme.wizardViewMinWidth + appWindow.minimumHeight = JamiTheme.wizardViewMinHeight + } else { + // Main window, load settings if possible. + var geometry = AppSettingsManager.getValue(Settings.WindowGeometry) + + // Position. + if (!isNaN(geometry.x) && !isNaN(geometry.y)) { + appWindow.x = geometry.x + appWindow.y = geometry.y + } + + // Dimensions. + appWindow.width = geometry.width ? + geometry.width : + JamiTheme.mainViewPreferredWidth + appWindow.height = geometry.height ? + geometry.height : + JamiTheme.mainViewPreferredHeight + appWindow.minimumWidth = JamiTheme.mainViewMinWidth + appWindow.minimumHeight = JamiTheme.mainViewMinHeight + + // State. + const visibilityStr = AppSettingsManager.getValue(Settings.WindowState) + appWindow.visibility = parseInt(visibilityStr) + } } + + // This will trigger `visible = true`. + windowSettingsLoaded = true + // Quiet check for updates on start if set to. if (UtilsAdapter.getAppValue(Settings.AutoUpdate)) { UpdateManager.checkForUpdates(true) @@ -170,6 +194,14 @@ ApplicationWindow { } } + Connections { + target: MainApplication + + function onCloseRequested() { + close(true) + } + } + Connections { target: { if (Qt.platform.os !== "windows" && Qt.platform.os !== "macos") diff --git a/src/appsettingsmanager.cpp b/src/appsettingsmanager.cpp index e719a19f61d076af65608f59db75765110ab191f..614a027c8b478f6d8a1e309b1d92f05a294dc23f 100644 --- a/src/appsettingsmanager.cpp +++ b/src/appsettingsmanager.cpp @@ -1,4 +1,4 @@ -/*! +/* * Copyright (C) 2021-2022 Savoir-faire Linux Inc. * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> * @@ -20,6 +20,9 @@ #include "appsettingsmanager.h" +const QString defaultDownloadPath = QStandardPaths::writableLocation( + QStandardPaths::DownloadLocation); + AppSettingsManager::AppSettingsManager(QObject* parent) : QObject(parent) , settings_(new QSettings("jami.net", "Jami", this)) diff --git a/src/appsettingsmanager.h b/src/appsettingsmanager.h index b18e02dd555e2399b9bf4f76d8d4799338bb8638..5c6586b1924e573bde4ac83401f48f26d45ad434 100644 --- a/src/appsettingsmanager.h +++ b/src/appsettingsmanager.h @@ -1,4 +1,4 @@ -/*! +/* * Copyright (C) 2020-2022 Savoir-faire Linux Inc. * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> * @@ -26,9 +26,9 @@ #include <QObject> #include <QString> #include <QStandardPaths> +#include <QWindow> // for QWindow::AutomaticVisibility -const QString defaultDownloadPath = QStandardPaths::writableLocation( - QStandardPaths::DownloadLocation); +extern const QString defaultDownloadPath; // clang-format off #define KEYS \ @@ -44,11 +44,13 @@ const QString defaultDownloadPath = QStandardPaths::writableLocation( X(EnableDarkTheme, false) \ X(AutoUpdate, true) \ X(StartMinimized, false) \ - X(NeverShowMeAgain, false) + X(NeverShowMeAgain, false) \ + X(WindowGeometry, QRectF(qQNaN(), qQNaN(), 0., 0.)) \ + X(WindowState, QWindow::AutomaticVisibility) /* * A class to expose settings keys in both c++ and QML. - * Note: this using a non-constructable class instead of a + * Note: this is using a non-constructable class instead of a * namespace allows for QML enum auto-completion in QtCreator. * This works well when there is only one enum class. Otherwise, * to prevent element name collision when defining multiple enums, diff --git a/src/lrcinstance.cpp b/src/lrcinstance.cpp index d5b52c80e2340f5f07bfa7a993bcfd5d20f162dd..2318d37cf7bee15abe8cdc31d51cb195e5c47ec7 100644 --- a/src/lrcinstance.cpp +++ b/src/lrcinstance.cpp @@ -25,7 +25,6 @@ #include <QObject> #include <QPixmap> #include <QRegularExpression> -#include <QSettings> #include <QtConcurrent/QtConcurrent> LRCInstance::LRCInstance(migrateCallback willMigrateCb, diff --git a/src/mainapplication.cpp b/src/mainapplication.cpp index 27aa5f4c93211abb83b23977c351909fbf1e5aa2..918200badbd6c674cd5b9d94477c3271a02afaa3 100644 --- a/src/mainapplication.cpp +++ b/src/mainapplication.cpp @@ -248,7 +248,8 @@ MainApplication::init() initQmlLayer(); - settingsManager_->setValue(Settings::Key::StartMinimized, results[opts::STARTMINIMIZED].toBool()); + settingsManager_->setValue(Settings::Key::StartMinimized, + results[opts::STARTMINIMIZED].toBool()); initSystray(); @@ -441,13 +442,14 @@ MainApplication::initSystray() #endif QAction* quitAction = new QAction(quitString, this); - connect(quitAction, &QAction::triggered, this, &MainApplication::cleanup); + connect(quitAction, &QAction::triggered, this, &MainApplication::closeRequested); QAction* restoreAction = new QAction(tr("&Show Jami"), this); connect(restoreAction, &QAction::triggered, this, &MainApplication::restoreApp); connect(systemTray_.get(), &QSystemTrayIcon::activated, + this, [this](QSystemTrayIcon::ActivationReason reason) { if (reason != QSystemTrayIcon::ActivationReason::Context) { #ifdef Q_OS_WINDOWS diff --git a/src/mainapplication.h b/src/mainapplication.h index 2c0baf50a37c5162064a9b27a097c75855791cc8..53a1ceb0736aa4e570fc4112fa7dcc37c6463f42 100644 --- a/src/mainapplication.h +++ b/src/mainapplication.h @@ -65,6 +65,9 @@ public: bool init(); void restoreApp(); +Q_SIGNALS: + void closeRequested(); + private: void vsConsoleDebug(); void fileDebug(QFile* debugFile); diff --git a/src/qmlregister.cpp b/src/qmlregister.cpp index 9375c8d0700990f4643d5fe8254cab2daa9a0ac4..fd4dab1223076cf8ba53796e76693f1393b2248d 100644 --- a/src/qmlregister.cpp +++ b/src/qmlregister.cpp @@ -103,7 +103,7 @@ registerTypes(QQmlEngine* engine, AppSettingsManager* settingsManager, PreviewEngine* previewEngine, ScreenInfo* screenInfo, - QObject* parent) + MainApplication* parent) { // setup the adapters (their lifetimes are that of MainApplication) auto callAdapter = new CallAdapter(systemTray, lrcInstance, parent); @@ -180,6 +180,7 @@ registerTypes(QQmlEngine* engine, QML_REGISTERSINGLETONTYPE_URL(NS_CONSTANTS, "qrc:/src/constant/JamiResources.qml", JamiResources); QML_REGISTERSINGLETONTYPE_URL(NS_CONSTANTS, "qrc:/src/constant/MsgSeq.qml", MsgSeq); + QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, parent, "MainApplication") QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, screenInfo, "CurrentScreenInfo") QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, lrcInstance, "LRCInstance") QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, settingsManager, "AppSettingsManager") diff --git a/src/qmlregister.h b/src/qmlregister.h index 31eded091b867c3e04c78e92c3d9bf8c818bc074..38bfd091e834c8727463a3d1dc6d3f88a5059d1a 100644 --- a/src/qmlregister.h +++ b/src/qmlregister.h @@ -35,6 +35,7 @@ class LRCInstance; class AppSettingsManager; class PreviewEngine; class ScreenInfo; +class MainApplication; // Hack for QtCreator autocomplete (part 1) // https://bugreports.qt.io/browse/QTCREATORBUG-20569 @@ -66,5 +67,5 @@ void registerTypes(QQmlEngine* engine, AppSettingsManager* appSettingsManager, PreviewEngine* previewEngine, ScreenInfo* screenInfo, - QObject* parent); + MainApplication* parent); }