This commit is contained in:
Andrew Hayzen 2021-09-30 20:42:37 +02:00 committed by GitHub
commit 5f32a7d72c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 40 deletions

View File

@ -52,6 +52,7 @@
#include <Windows.h> #include <Windows.h>
#endif #endif
static const int systemTrayWaitTime = 10000;
static const QString allFilesFilter(QObject::tr("All files (*.*)")); static const QString allFilesFilter(QObject::tr("All files (*.*)"));
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
static const char barrierConfigName[] = "barrier.sgc"; static const char barrierConfigName[] = "barrier.sgc";
@ -156,6 +157,9 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
m_pComboServerList->hide(); m_pComboServerList->hide();
m_pLabelPadlock->hide(); m_pLabelPadlock->hide();
m_OpenHiddenTrayTimer.setSingleShot(true);
connect(&m_OpenHiddenTrayTimer, &QTimer::timeout, this, &MainWindow::on_m_OpenHiddenTrayTimer_triggered);
updateSSLFingerprint(); updateSSLFingerprint();
// resize window to smallest reasonable size // resize window to smallest reasonable size
@ -190,6 +194,28 @@ void MainWindow::open()
if (appConfig().getAutoHide()) { if (appConfig().getAutoHide()) {
hide(); 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 { } else {
showNormal(); 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) void MainWindow::setStatus(const QString &status)
{ {
m_pStatusLabel->setText(status); m_pStatusLabel->setText(status);
@ -1277,7 +1315,8 @@ void MainWindow::bonjourInstallFinished()
void MainWindow::windowStateChanged() 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(); hide();
} }

View File

@ -25,6 +25,7 @@
#include <QSettings> #include <QSettings>
#include <QProcess> #include <QProcess>
#include <QThread> #include <QThread>
#include <QTimer>
#include "ui_MainWindowBase.h" #include "ui_MainWindowBase.h"
@ -201,11 +202,13 @@ public slots:
SslCertificate* m_pSslCertificate; SslCertificate* m_pSslCertificate;
QStringList m_PendingClientNames; QStringList m_PendingClientNames;
LogWindow *m_pLogWindow; LogWindow *m_pLogWindow;
QTimer m_OpenHiddenTrayTimer;
private slots: private slots:
void on_m_pCheckBoxAutoConfig_toggled(bool checked); void on_m_pCheckBoxAutoConfig_toggled(bool checked);
void on_m_pComboServerList_currentIndexChanged(QString ); void on_m_pComboServerList_currentIndexChanged(QString );
void on_m_pButtonReload_clicked(); void on_m_pButtonReload_clicked();
void on_m_OpenHiddenTrayTimer_triggered();
void installBonjour(); void installBonjour();
}; };

View File

@ -29,6 +29,12 @@ QBarrierApplication::QBarrierApplication(int& argc, char** argv) :
m_Translator(NULL) m_Translator(NULL)
{ {
s_Instance = this; 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() QBarrierApplication::~QBarrierApplication()
@ -69,3 +75,12 @@ void QBarrierApplication::setTranslator(QTranslator* translator)
m_Translator = translator; m_Translator = translator;
installTranslator(m_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();
}
}

View File

@ -37,6 +37,9 @@ class QBarrierApplication : public QApplication
static QBarrierApplication* getInstance(); static QBarrierApplication* getInstance();
private Q_SLOTS:
void onLastWindowClosed();
private: private:
QTranslator* m_Translator; QTranslator* m_Translator;

View File

@ -52,6 +52,10 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
m_pCheckBoxMinimizeToTray->setChecked(appConfig().getMinimizeToTray()); m_pCheckBoxMinimizeToTray->setChecked(appConfig().getMinimizeToTray());
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.getCryptoEnabled()); 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) #if defined(Q_OS_WIN)
m_pComboElevate->setCurrentIndex(static_cast<int>(appConfig().elevateMode())); m_pComboElevate->setCurrentIndex(static_cast<int>(appConfig().elevateMode()));
#else #else

View File

@ -16,9 +16,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define TRAY_RETRY_COUNT 5
#define TRAY_RETRY_WAIT 2000
#include "QBarrierApplication.h" #include "QBarrierApplication.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "AppConfig.h" #include "AppConfig.h"
@ -47,8 +44,6 @@ public:
} }
}; };
int waitForTray();
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
bool checkMacAssistiveDevices(); bool checkMacAssistiveDevices();
#endif #endif
@ -93,20 +88,9 @@ int main(int argc, char* argv[])
} }
#endif #endif
int trayAvailable = waitForTray();
QApplication::setQuitOnLastWindowClosed(false);
QSettings settings; QSettings settings;
AppConfig appConfig (&settings); AppConfig appConfig (&settings);
if (appConfig.getAutoHide() && !trayAvailable)
{
// 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()); app.switchTranslator(appConfig.language());
MainWindow mainWindow(settings, appConfig); MainWindow mainWindow(settings, appConfig);
@ -124,29 +108,6 @@ int main(int argc, char* argv[])
return app.exec(); 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) #if defined(Q_OS_MAC)
bool checkMacAssistiveDevices() bool checkMacAssistiveDevices()
{ {