From 2080784dd109179adfae2aabe484c0830ac285ac Mon Sep 17 00:00:00 2001 From: Andrew Hayzen Date: Tue, 2 Mar 2021 22:48:14 +0000 Subject: [PATCH 1/5] Do not wait for tray to become available Closes #1024 --- src/gui/src/main.cpp | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/src/gui/src/main.cpp b/src/gui/src/main.cpp index 73251d52..5bf5898c 100644 --- a/src/gui/src/main.cpp +++ b/src/gui/src/main.cpp @@ -16,9 +16,6 @@ * along with this program. If not, see . */ -#define TRAY_RETRY_COUNT 5 -#define TRAY_RETRY_WAIT 2000 - #include "QBarrierApplication.h" #include "MainWindow.h" #include "AppConfig.h" @@ -47,8 +44,6 @@ public: } }; -int waitForTray(); - #if defined(Q_OS_MAC) bool checkMacAssistiveDevices(); #endif @@ -93,14 +88,12 @@ int main(int argc, char* argv[]) } #endif - int trayAvailable = waitForTray(); - QApplication::setQuitOnLastWindowClosed(false); QSettings settings; AppConfig appConfig (&settings); - if (appConfig.getAutoHide() && !trayAvailable) + if (appConfig.getAutoHide() && !QSystemTrayIcon::isSystemTrayAvailable()) { // force auto hide to false - otherwise there is no way to get the GUI back fprintf(stdout, "System tray not available, force disabling auto hide!\n"); @@ -124,29 +117,6 @@ int main(int argc, char* argv[]) return app.exec(); } -int waitForTray() -{ - // on linux, the system tray may not be available immediately after logging in, - // so keep retrying but give up after a short time. - int trayAttempts = 0; - while (true) - { - if (QSystemTrayIcon::isSystemTrayAvailable()) - { - break; - } - - if (++trayAttempts > TRAY_RETRY_COUNT) - { - fprintf(stdout, "System tray is unavailable.\n"); - return false; - } - - QThreadImpl::msleep(TRAY_RETRY_WAIT); - } - return true; -} - #if defined(Q_OS_MAC) bool checkMacAssistiveDevices() { From 00565fa7eac050f19f71cdd407abbb51c347bf6c Mon Sep 17 00:00:00 2001 From: Andrew Hayzen Date: Tue, 2 Mar 2021 22:48:58 +0000 Subject: [PATCH 2/5] When the last window closes if there is no system tray close the app --- src/gui/src/QBarrierApplication.cpp | 15 +++++++++++++++ src/gui/src/QBarrierApplication.h | 3 +++ src/gui/src/main.cpp | 2 -- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/gui/src/QBarrierApplication.cpp b/src/gui/src/QBarrierApplication.cpp index f9362c74..7a6ec970 100644 --- a/src/gui/src/QBarrierApplication.cpp +++ b/src/gui/src/QBarrierApplication.cpp @@ -29,6 +29,12 @@ QBarrierApplication::QBarrierApplication(int& argc, char** argv) : m_Translator(NULL) { s_Instance = this; + + // By default do not quit when the last window is closed as we minimise + // to the system tray, but listen for the lastWindow closing so that + // if the system tray is not available we can quit. + setQuitOnLastWindowClosed(false); + connect(this, &QApplication::lastWindowClosed, this, &QBarrierApplication::onLastWindowClosed); } QBarrierApplication::~QBarrierApplication() @@ -69,3 +75,12 @@ void QBarrierApplication::setTranslator(QTranslator* translator) m_Translator = translator; installTranslator(m_Translator); } + +void QBarrierApplication::onLastWindowClosed() +{ + // If there is no system tray available then quit when the last window is closed + if (!QSystemTrayIcon::isSystemTrayAvailable()) + { + quit(); + } +} diff --git a/src/gui/src/QBarrierApplication.h b/src/gui/src/QBarrierApplication.h index 1b06ba08..03c941c9 100644 --- a/src/gui/src/QBarrierApplication.h +++ b/src/gui/src/QBarrierApplication.h @@ -37,6 +37,9 @@ class QBarrierApplication : public QApplication static QBarrierApplication* getInstance(); + private Q_SLOTS: + void onLastWindowClosed(); + private: QTranslator* m_Translator; diff --git a/src/gui/src/main.cpp b/src/gui/src/main.cpp index 5bf5898c..729e4837 100644 --- a/src/gui/src/main.cpp +++ b/src/gui/src/main.cpp @@ -88,8 +88,6 @@ int main(int argc, char* argv[]) } #endif - QApplication::setQuitOnLastWindowClosed(false); - QSettings settings; AppConfig appConfig (&settings); From 35cc645637b11579cf1723d1d7706b9a0ace0b17 Mon Sep 17 00:00:00 2001 From: Andrew Hayzen Date: Tue, 2 Mar 2021 22:49:20 +0000 Subject: [PATCH 3/5] Do not hide the window to system tray when minimising if not available --- src/gui/src/MainWindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index a3962aa8..3438c24c 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -1277,7 +1277,8 @@ void MainWindow::bonjourInstallFinished() void MainWindow::windowStateChanged() { - if (windowState() == Qt::WindowMinimized && appConfig().getMinimizeToTray()) + // If we are minimising and minimise to tray is enabled and system tray is available then hide the window + if (windowState() == Qt::WindowMinimized && appConfig().getMinimizeToTray() && QSystemTrayIcon::isSystemTrayAvailable()) hide(); } From 3e7e7b1af3215965430cdda60682a8bdc1e98526 Mon Sep 17 00:00:00 2001 From: Andrew Hayzen Date: Tue, 2 Mar 2021 22:49:45 +0000 Subject: [PATCH 4/5] Disable system tray related settings if not available --- src/gui/src/SettingsDialog.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/src/SettingsDialog.cpp b/src/gui/src/SettingsDialog.cpp index 1caeae5d..37c34714 100644 --- a/src/gui/src/SettingsDialog.cpp +++ b/src/gui/src/SettingsDialog.cpp @@ -52,6 +52,10 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) : m_pCheckBoxMinimizeToTray->setChecked(appConfig().getMinimizeToTray()); m_pCheckBoxEnableCrypto->setChecked(m_appConfig.getCryptoEnabled()); + // Don't allow auto hide or minimise to tray if it's not available + m_pCheckBoxAutoHide->setEnabled(QSystemTrayIcon::isSystemTrayAvailable()); + m_pCheckBoxMinimizeToTray->setEnabled(QSystemTrayIcon::isSystemTrayAvailable()); + #if defined(Q_OS_WIN) m_pComboElevate->setCurrentIndex(static_cast(appConfig().elevateMode())); #else From d0df87137336f4ac61872cb4857478e2a827cba4 Mon Sep 17 00:00:00 2001 From: Andrew Hayzen Date: Tue, 2 Mar 2021 23:14:59 +0000 Subject: [PATCH 5/5] Ensure that window is not hidden with no system tray after startup Before in all cases we would wait for the system tray for a period of time, this would block users who don't have autohide enabled and don't have a system tray from seeing the window. Instead flip this around to either hide the window at startup if autohide is enabled and show if it isn't. Then if we have opened hidden wait a period of time and check if system tray is available, if it isn't then force the window to be shown. This provides much better UX for the general cases. Closes #1024 --- src/gui/src/MainWindow.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/gui/src/MainWindow.h | 3 +++ src/gui/src/main.cpp | 7 ------- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 3438c24c..10e919d0 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -52,6 +52,7 @@ #include #endif +static const int systemTrayWaitTime = 10000; static const QString allFilesFilter(QObject::tr("All files (*.*)")); #if defined(Q_OS_WIN) static const char barrierConfigName[] = "barrier.sgc"; @@ -156,6 +157,9 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) : m_pComboServerList->hide(); m_pLabelPadlock->hide(); + m_OpenHiddenTrayTimer.setSingleShot(true); + connect(&m_OpenHiddenTrayTimer, &QTimer::timeout, this, &MainWindow::on_m_OpenHiddenTrayTimer_triggered); + updateSSLFingerprint(); // resize window to smallest reasonable size @@ -190,6 +194,28 @@ void MainWindow::open() if (appConfig().getAutoHide()) { hide(); + + // If system tray is not available, start a timer to ensure we don't become + // stuck in a hidden state + // + // The previous solution for this would wait at the startup of the app to + // see if the system tray becomes available before showing any window - even + // if the user didn't have autohide enabled. + // + // This solution instead, hides the window if they have autohide enabled, or shows + // the window if they don't. Then if the user has selected to autohide the window + // it checks after a period of time if the system tray is not available - if it + // isn't then it forces the window to show. + // + // This provides a much better UX for the two main use cases (user starting app with + // autohide enabled with system tray available and user starting app with autohide + // disabled with no system tray available). And provides a workaround for the edge + // case of a user enabling autohide with no system tray available (this should now + // be harder to do as the option in settings will become disabled). + if (!QSystemTrayIcon::isSystemTrayAvailable()) + { + m_OpenHiddenTrayTimer.start(systemTrayWaitTime); + } } else { showNormal(); } @@ -208,6 +234,18 @@ void MainWindow::open() } } +void MainWindow::on_m_OpenHiddenTrayTimer_triggered() +{ + // If the system tray is still not available then force window to show + if (!QSystemTrayIcon::isSystemTrayAvailable()) + { + fprintf(stdout, "System tray not available, force disabling auto hide!\n"); + m_AppConfig->setAutoHide(false); + + showNormal(); + } +} + void MainWindow::setStatus(const QString &status) { m_pStatusLabel->setText(status); diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index c115b912..06aac977 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -25,6 +25,7 @@ #include #include #include +#include #include "ui_MainWindowBase.h" @@ -201,11 +202,13 @@ public slots: SslCertificate* m_pSslCertificate; QStringList m_PendingClientNames; LogWindow *m_pLogWindow; + QTimer m_OpenHiddenTrayTimer; private slots: void on_m_pCheckBoxAutoConfig_toggled(bool checked); void on_m_pComboServerList_currentIndexChanged(QString ); void on_m_pButtonReload_clicked(); + void on_m_OpenHiddenTrayTimer_triggered(); void installBonjour(); }; diff --git a/src/gui/src/main.cpp b/src/gui/src/main.cpp index 729e4837..498c2100 100644 --- a/src/gui/src/main.cpp +++ b/src/gui/src/main.cpp @@ -91,13 +91,6 @@ int main(int argc, char* argv[]) QSettings settings; AppConfig appConfig (&settings); - if (appConfig.getAutoHide() && !QSystemTrayIcon::isSystemTrayAvailable()) - { - // force auto hide to false - otherwise there is no way to get the GUI back - fprintf(stdout, "System tray not available, force disabling auto hide!\n"); - appConfig.setAutoHide(false); - } - app.switchTranslator(appConfig.language()); MainWindow mainWindow(settings, appConfig);