From 84d0527268fbd1de11908b4292acf95d96d1713d Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 20 May 2026 12:26:15 -0400 Subject: [PATCH 01/10] refactor(gui): replace tray-related magic numbers with named constants Signed-off-by: Josh --- src/gui/main.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/gui/main.cpp b/src/gui/main.cpp index fe1089110940f..2574abb5742b4 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -35,6 +35,11 @@ using namespace OCC; +namespace { +constexpr int InitialTrayWaitSeconds = 1; +constexpr int XfceTrayMaxAttempts = 30; +constexpr int DelayedTrayRetryMs = 10'000; + void warnSystray() { QMessageBox::critical( @@ -48,6 +53,7 @@ void warnSystray() QMessageBox::Ok ); } +} int main(int argc, char **argv) { @@ -176,7 +182,7 @@ int main(int argc, char **argv) // (eg boot time) then we show the settings dialog if there is still no systemtray. // On XFCE however, we show a message box with explainaition how to install a systemtray. qCInfo(lcApplication) << "System tray is not available, waiting..."; - Utility::sleep(1); + Utility::sleep(InitialTrayWaitSeconds); auto desktopSession = qgetenv("XDG_CURRENT_DESKTOP").toLower(); if (desktopSession.isEmpty()) { @@ -186,7 +192,7 @@ int main(int argc, char **argv) int attempts = 0; while (!QSystemTrayIcon::isSystemTrayAvailable()) { attempts++; - if (attempts >= 30) { + if (attempts >= XfceTrayMaxAttempts) { qCWarning(lcApplication) << "System tray unavailable (xfce)"; warnSystray(); break; @@ -201,7 +207,7 @@ int main(int argc, char **argv) if (desktopSession != "ubuntu") { qCInfo(lcApplication) << "System tray still not available, showing window and trying again later"; app.showMainDialog(); - QTimer::singleShot(10000, &app, &Application::tryTrayAgain); + QTimer::singleShot(DelayedTrayRetryMs, &app, &Application::tryTrayAgain); } else { qCInfo(lcApplication) << "System tray still not available, but assuming it's fine on 'ubuntu' desktop"; } From 406c4ca0830e15fa2d5452bd5f7b179699cd799f Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 20 May 2026 12:28:58 -0400 Subject: [PATCH 02/10] refactor(gui): extract desktop session lookup from main Signed-off-by: Josh --- src/gui/main.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 2574abb5742b4..ff4dae2372abe 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -40,6 +40,15 @@ constexpr int InitialTrayWaitSeconds = 1; constexpr int XfceTrayMaxAttempts = 30; constexpr int DelayedTrayRetryMs = 10'000; +QByteArray currentDesktopSession() +{ + auto desktopSession = qgetenv("XDG_CURRENT_DESKTOP").toLower(); + if (desktopSession.isEmpty()) { + desktopSession = qgetenv("DESKTOP_SESSION").toLower(); + } + return desktopSession; +} + void warnSystray() { QMessageBox::critical( @@ -184,10 +193,7 @@ int main(int argc, char **argv) qCInfo(lcApplication) << "System tray is not available, waiting..."; Utility::sleep(InitialTrayWaitSeconds); - auto desktopSession = qgetenv("XDG_CURRENT_DESKTOP").toLower(); - if (desktopSession.isEmpty()) { - desktopSession = qgetenv("DESKTOP_SESSION").toLower(); - } + const auto desktopSession = currentDesktopSession(); if (desktopSession == "xfce") { int attempts = 0; while (!QSystemTrayIcon::isSystemTrayAvailable()) { From f07a0090de8c2082c3d1eaac6dca2ed7853e26c5 Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 20 May 2026 12:34:46 -0400 Subject: [PATCH 03/10] refactor(gui): extract running-instance handling from main Signed-off-by: Josh --- src/gui/main.cpp | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/src/gui/main.cpp b/src/gui/main.cpp index ff4dae2372abe..7e47b17389c4a 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -62,6 +62,32 @@ void warnSystray() QMessageBox::Ok ); } + +int handleRunningInstance(Application &app) +{ + if (!app.isRunning()) { + return 1; + } + + qCInfo(lcApplication) << "Already running, exiting..."; + if (app.isSessionRestored()) { + // This call is mirrored with the one in Application::slotParseMessage + qCInfo(lcApplication) << "Session was restored, don't notify app!"; + return -1; + } + + const QStringList args = app.arguments(); + if (args.size() > 1) { + const QString msg = args.join(QLatin1String("|")); + if (!app.sendMessage(QLatin1String("MSG_PARSEOPTIONS:") + msg)) { + return -1; + } + } else if (!app.backgroundMode() && !app.sendMessage(QLatin1String("MSG_SHOWMAINDIALOG"))) { + return -1; + } + + return 0; +} } int main(int argc, char **argv) @@ -163,23 +189,8 @@ int main(int argc, char **argv) #endif // if the application is already running, notify it. - if (app.isRunning()) { - qCInfo(lcApplication) << "Already running, exiting..."; - if (app.isSessionRestored()) { - // This call is mirrored with the one in Application::slotParseMessage - qCInfo(lcApplication) << "Session was restored, don't notify app!"; - return -1; - } - - QStringList args = app.arguments(); - if (args.size() > 1) { - QString msg = args.join(QLatin1String("|")); - if (!app.sendMessage(QLatin1String("MSG_PARSEOPTIONS:") + msg)) - return -1; - } else if (!app.backgroundMode() && !app.sendMessage(QLatin1String("MSG_SHOWMAINDIALOG"))) { - return -1; - } - return 0; + if (const auto runningInstanceResult = handleRunningInstance(app); runningInstanceResult <= 0) { + return runningInstanceResult; } // We can't call isSystemTrayAvailable with appmenu-qt5 begause it hides the systemtray From ac61f85e078a432bca9656b676fcaac78e9beb3a Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 20 May 2026 12:44:35 -0400 Subject: [PATCH 04/10] refactor(gui): extract system tray recovery logic from main Signed-off-by: Josh --- src/gui/main.cpp | 86 +++++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 7e47b17389c4a..6c0482b42a279 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -88,8 +88,55 @@ int handleRunningInstance(Application &app) return 0; } + +void handleSystemTrayAvailability(Application &app) +{ + // We can't call isSystemTrayAvailable with appmenu-qt5 because it hides the system tray + // (issue #4693) + if (qgetenv("QT_QPA_PLATFORMTHEME") == "appmenu-qt5") { + return; + } + + if (QSystemTrayIcon::isSystemTrayAvailable()) { + return; + } + + // If the system tray is not there, we will wait one second for it to maybe start + // (e.g. boot time) then we show the settings dialog if there is still no system tray. + // On XFCE however, we show a message box with explanation how to install a system tray. + qCInfo(lcApplication) << "System tray is not available, waiting..."; + Utility::sleep(InitialTrayWaitSeconds); + + const auto desktopSession = currentDesktopSession(); + if (desktopSession == "xfce") { + int attempts = 0; + while (!QSystemTrayIcon::isSystemTrayAvailable()) { + attempts++; + if (attempts >= XfceTrayMaxAttempts) { + qCWarning(lcApplication) << "System tray unavailable (xfce)"; + warnSystray(); + break; + } + Utility::sleep(InitialTrayWaitSeconds); + } + } + + if (QSystemTrayIcon::isSystemTrayAvailable()) { + app.tryTrayAgain(); + } else if (!app.backgroundMode() && !AccountManager::instance()->accounts().isEmpty()) { + if (desktopSession != "ubuntu") { + qCInfo(lcApplication) << "System tray still not available, showing window and trying again later"; + app.showMainDialog(); + QTimer::singleShot(DelayedTrayRetryMs, &app, &Application::tryTrayAgain); + } else { + qCInfo(lcApplication) << "System tray still not available, but assuming it's fine on 'ubuntu' desktop"; + } + } +} } +// ---------------------------------------------------------------------------------- + int main(int argc, char **argv) { #ifdef Q_OS_LINUX @@ -193,44 +240,7 @@ int main(int argc, char **argv) return runningInstanceResult; } - // We can't call isSystemTrayAvailable with appmenu-qt5 begause it hides the systemtray - // (issue #4693) - if (qgetenv("QT_QPA_PLATFORMTHEME") != "appmenu-qt5") - { - if (!QSystemTrayIcon::isSystemTrayAvailable()) { - // If the systemtray is not there, we will wait one second for it to maybe start - // (eg boot time) then we show the settings dialog if there is still no systemtray. - // On XFCE however, we show a message box with explainaition how to install a systemtray. - qCInfo(lcApplication) << "System tray is not available, waiting..."; - Utility::sleep(InitialTrayWaitSeconds); - - const auto desktopSession = currentDesktopSession(); - if (desktopSession == "xfce") { - int attempts = 0; - while (!QSystemTrayIcon::isSystemTrayAvailable()) { - attempts++; - if (attempts >= XfceTrayMaxAttempts) { - qCWarning(lcApplication) << "System tray unavailable (xfce)"; - warnSystray(); - break; - } - Utility::sleep(1); - } - } - - if (QSystemTrayIcon::isSystemTrayAvailable()) { - app.tryTrayAgain(); - } else if (!app.backgroundMode() && !AccountManager::instance()->accounts().isEmpty()) { - if (desktopSession != "ubuntu") { - qCInfo(lcApplication) << "System tray still not available, showing window and trying again later"; - app.showMainDialog(); - QTimer::singleShot(DelayedTrayRetryMs, &app, &Application::tryTrayAgain); - } else { - qCInfo(lcApplication) << "System tray still not available, but assuming it's fine on 'ubuntu' desktop"; - } - } - } - } + handleSystemTrayAvailability(app); return app.exec(); } From a50e862a840d0d9891bc8054e83150c4bdd5e501 Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 20 May 2026 12:54:05 -0400 Subject: [PATCH 05/10] docs(gui): document platform-specific startup special cases Signed-off-by: Josh --- src/gui/main.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 6c0482b42a279..2258cc7ca8e40 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -91,8 +91,7 @@ int handleRunningInstance(Application &app) void handleSystemTrayAvailability(Application &app) { - // We can't call isSystemTrayAvailable with appmenu-qt5 because it hides the system tray - // (issue #4693) + // Skip this check with appmenu-qt5 because that platform theme hides the system tray (#4693) if (qgetenv("QT_QPA_PLATFORMTHEME") == "appmenu-qt5") { return; } @@ -129,6 +128,7 @@ void handleSystemTrayAvailability(Application &app) app.showMainDialog(); QTimer::singleShot(DelayedTrayRetryMs, &app, &Application::tryTrayAgain); } else { + // Ubuntu desktops may operate acceptably without reporting a traditional tray here. qCInfo(lcApplication) << "System tray still not available, but assuming it's fine on 'ubuntu' desktop"; } } @@ -142,13 +142,17 @@ int main(int argc, char **argv) #ifdef Q_OS_LINUX const auto appImagePath = qEnvironmentVariable("APPIMAGE"); const auto runningInsideAppImage = !appImagePath.isNull() && QFile::exists(appImagePath); + if (runningInsideAppImage) { + // Work around rendering issues seen when the client runs from an AppImage. qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-gpu-compositing"); } #endif #ifdef Q_OS_WIN + // Avoid loading DLLs from the current working directory. SetDllDirectory(L""); + // Ensure bundled QML modules are found when launching from the install directory. qputenv("QML_IMPORT_PATH", (QDir::currentPath() + QStringLiteral("/qml")).toLatin1()); #endif @@ -173,18 +177,20 @@ int main(int argc, char **argv) qmlStyle = QStringLiteral("macOS"); #elif defined Q_OS_WIN if (const auto osVersion = QOperatingSystemVersion::current().version(); osVersion < QOperatingSystemVersion::Windows11.version()) { + // Use the older Qt Quick Controls style on pre-Windows 11 systems. qmlStyle = QStringLiteral("Universal"); widgetsStyle = QStringLiteral("Fusion"); if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_UNIVERSAL_THEME")) { - // initialise theme with the light/dark mode setting from the OS + // Initialise theme with the light/dark mode setting from the OS. qputenv("QT_QUICK_CONTROLS_UNIVERSAL_THEME", "System"); } if (osVersion < QOperatingSystemVersion::Windows10_1809.version() && qEnvironmentVariableIsEmpty("QT_QPA_PLATFORM")) { - // for Windows Server 2016 to display text as expected, see #8064 + // Work around DirectWrite-related text rendering issues on older Windows versions like Server 2016 (#8064). qputenv("QT_QPA_PLATFORM", "windows:nodirectwrite"); } } else { + // Match newer Windows styling more closely on Windows 11 and later. qmlStyle = QStringLiteral("FluentWinUI3"); widgetsStyle = QStringLiteral("windows11"); } From ecc87057ec9b3835d61cc8fc39843f3d1813adb0 Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 20 May 2026 13:42:16 -0400 Subject: [PATCH 06/10] docs(gui): clarify styling initialization in main Signed-off-by: Josh --- src/gui/main.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 2258cc7ca8e40..80bcdc0c8c4bd 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -159,24 +159,30 @@ int main(int argc, char **argv) Q_INIT_RESOURCE(resources); Q_INIT_RESOURCE(theme); - // OpenSSL 1.1.0: No explicit initialisation or de-initialisation is necessary. #ifdef Q_OS_MACOS Mac::CocoaInitializer cocoaInit; // RIIA #endif + // Prevent context losses / corrruptions with some OpenGL drivers (#4340) auto surfaceFormat = QSurfaceFormat::defaultFormat(); surfaceFormat.setOption(QSurfaceFormat::ResetNotification); QSurfaceFormat::setDefaultFormat(surfaceFormat); + // Native text rendering is believed to be less blurry (#2409); + // may cause pixelation with advanced features (e.g. text transformation). + // https://doc.qt.io/qt-6/qquickwindow.html#TextRenderType-enum QQuickWindow::setTextRenderType(QQuickWindow::NativeTextRendering); + // Default styling (i.e. for Linux + UNIX) auto qmlStyle = QStringLiteral("Fusion"); auto widgetsStyle = QStringLiteral(""); #if defined Q_OS_MACOS qmlStyle = QStringLiteral("macOS"); + widgetsStyle = QStringLiteral(""); #elif defined Q_OS_WIN - if (const auto osVersion = QOperatingSystemVersion::current().version(); osVersion < QOperatingSystemVersion::Windows11.version()) { + const auto osVersion = QOperatingSystemVersion::current().version(); + if (osVersion < QOperatingSystemVersion::Windows11.version()) { // Use the older Qt Quick Controls style on pre-Windows 11 systems. qmlStyle = QStringLiteral("Universal"); widgetsStyle = QStringLiteral("Fusion"); From 4002c032dfc944bf812da87f9b58c92aece6f310 Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 20 May 2026 13:50:14 -0400 Subject: [PATCH 07/10] docs(gui): add windows QML_IMPORT_PATH comment Signed-off-by: Josh --- src/gui/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 80bcdc0c8c4bd..05181e69f778d 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -153,6 +153,8 @@ int main(int argc, char **argv) // Avoid loading DLLs from the current working directory. SetDllDirectory(L""); // Ensure bundled QML modules are found when launching from the install directory. + // FIXME: confirm the use of currentPath() is intentional here; seems like it + // should be based on the executable path instead (to get install directory)? qputenv("QML_IMPORT_PATH", (QDir::currentPath() + QStringLiteral("/qml")).toLatin1()); #endif From 8cb6b0a4713bde7f2d928773eed4e99d95aa6de4 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 21 May 2026 08:22:43 -0400 Subject: [PATCH 08/10] chore(gui): comment correction in main.cpp Signed-off-by: Josh --- src/gui/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 05181e69f778d..ef09346070499 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -89,6 +89,7 @@ int handleRunningInstance(Application &app) return 0; } +// May block - depending on tray availability void handleSystemTrayAvailability(Application &app) { // Skip this check with appmenu-qt5 because that platform theme hides the system tray (#4693) @@ -165,7 +166,7 @@ int main(int argc, char **argv) Mac::CocoaInitializer cocoaInit; // RIIA #endif - // Prevent context losses / corrruptions with some OpenGL drivers (#4340) + // Prevent context losses / corruptions with some OpenGL drivers (#4340) auto surfaceFormat = QSurfaceFormat::defaultFormat(); surfaceFormat.setOption(QSurfaceFormat::ResetNotification); QSurfaceFormat::setDefaultFormat(surfaceFormat); From 70fd0d1a7d595f10d2695b3c02d395613de2e349 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 21 May 2026 09:44:47 -0400 Subject: [PATCH 09/10] refactor(gui): clarify handleRunningInstance control flow Same overall logic; just additional logging and easier to skim. Signed-off-by: Josh --- src/gui/main.cpp | 49 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/src/gui/main.cpp b/src/gui/main.cpp index ef09346070499..42dfaef6ba45e 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -63,30 +63,52 @@ void warnSystray() ); } -int handleRunningInstance(Application &app) +enum class RunningInstanceResult { + ContinueStartup = 1, // No running instance detected + ExitHandled = 0, // Existing instance handled or intentionally ignored startup + ExitError = -1, // Existing instance detected, but handoff failed +}; + +RunningInstanceResult handleRunningInstance(Application &app) { if (!app.isRunning()) { - return 1; + qCDebug(lcApplication) << "No running instance detected; continuing startup."; + return RunningInstanceResult::ContinueStartup; } - qCInfo(lcApplication) << "Already running, exiting..."; + qCInfo(lcApplication) << "Another instance is already running."; + if (app.isSessionRestored()) { - // This call is mirrored with the one in Application::slotParseMessage - qCInfo(lcApplication) << "Session was restored, don't notify app!"; - return -1; + qCInfo(lcApplication) << "Session restore detected; not notifying the running instance."; + return RunningInstanceResult::ExitHandled; } const QStringList args = app.arguments(); if (args.size() > 1) { + qCInfo(lcApplication) << "Forwarding startup arguments to the running instance."; const QString msg = args.join(QLatin1String("|")); - if (!app.sendMessage(QLatin1String("MSG_PARSEOPTIONS:") + msg)) { - return -1; + if (app.sendMessage(QLatin1String("MSG_PARSEOPTIONS:") + msg)) { + return RunningInstanceResult::ExitHandled; } - } else if (!app.backgroundMode() && !app.sendMessage(QLatin1String("MSG_SHOWMAINDIALOG"))) { - return -1; + + qCWarning(lcApplication) << "Failed to forward startup arguments to the running instance."; + return RunningInstanceResult::ExitError; + } + + if (app.backgroundMode()) { + // FIXME: background mode itself is requested via a startup argument... this is unreachable code (!) + qCInfo(lcApplication) << "Background mode requested with no startup arguments; not requesting the running instance to show the main dialog."; + return RunningInstanceResult::ExitHandled; + } + + qCInfo(lcApplication) << "Requesting the running instance to show the main dialog."; + // This call is mirrored with the one in Application::slotParseMessage + if (app.sendMessage(QLatin1String("MSG_SHOWMAINDIALOG"))) { + return RunningInstanceResult::ExitHandled; } - return 0; + qCWarning(lcApplication) << "Failed to request the main dialog from the running instance."; + return RunningInstanceResult::ExitError; } // May block - depending on tray availability @@ -251,8 +273,9 @@ int main(int argc, char **argv) #endif // if the application is already running, notify it. - if (const auto runningInstanceResult = handleRunningInstance(app); runningInstanceResult <= 0) { - return runningInstanceResult; + const auto runningInstanceResult = handleRunningInstance(app); + if (runningInstanceResult != RunningInstanceResult::ContinueStartup) { + return static_cast(runningInstanceResult); } handleSystemTrayAvailability(app); From c09614c806c6a5b0a6d25e2a82364616e1d288d6 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 21 May 2026 10:35:50 -0400 Subject: [PATCH 10/10] refactor(gui): clearer tray availability logic and logging Signed-off-by: Josh --- src/gui/main.cpp | 63 +++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 42dfaef6ba45e..10fd9a839c8d5 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -42,11 +42,20 @@ constexpr int DelayedTrayRetryMs = 10'000; QByteArray currentDesktopSession() { - auto desktopSession = qgetenv("XDG_CURRENT_DESKTOP").toLower(); - if (desktopSession.isEmpty()) { - desktopSession = qgetenv("DESKTOP_SESSION").toLower(); + const auto xdgCurrentDesktopEnv = qgetenv("XDG_CURRENT_DESKTOP"); + const auto desktopSessionEnv = qgetenv("DESKTOP_SESSION"); + + effective = xdgCurrentDesktopEnv.toLower(); + if (effective.isEmpty()) { + effective = desktopSessionEnv.toLower(); } - return desktopSession; + + qCInfo(lcApplication) << "Tray availability check:" + << "XDG_CURRENT_DESKTOP=" << xdgCurrentDesktopEnv + << "DESKTOP_SESSION=" << desktopSessionEnv + << "effective=" << effective; + + return effective; } void warnSystray() @@ -123,38 +132,48 @@ void handleSystemTrayAvailability(Application &app) return; } + const auto desktopSession = currentDesktopSession(); + // If the system tray is not there, we will wait one second for it to maybe start // (e.g. boot time) then we show the settings dialog if there is still no system tray. // On XFCE however, we show a message box with explanation how to install a system tray. + qCInfo(lcApplication) << "System tray is not available, waiting..."; Utility::sleep(InitialTrayWaitSeconds); - const auto desktopSession = currentDesktopSession(); - if (desktopSession == "xfce") { + if (desktopSession == "xfce") { // FIXME: This seems too strict; XDG_CURRENT_DESKTOP can be a composite int attempts = 0; - while (!QSystemTrayIcon::isSystemTrayAvailable()) { - attempts++; - if (attempts >= XfceTrayMaxAttempts) { - qCWarning(lcApplication) << "System tray unavailable (xfce)"; - warnSystray(); - break; - } + // NOTE: This loop can block for up to 30 more seconds after the initial sleep (!) + while (!QSystemTrayIcon::isSystemTrayAvailable() && attempts < XfceTrayMaxAttempts) { + ++attempts; Utility::sleep(InitialTrayWaitSeconds); } + + if (!QSystemTrayIcon::isSystemTrayAvailable()) { + qCWarning(lcApplication) << "System tray unavailable even after waiting 30s (xfce detected)"; + warnSystray(); + break; + } } if (QSystemTrayIcon::isSystemTrayAvailable()) { app.tryTrayAgain(); - } else if (!app.backgroundMode() && !AccountManager::instance()->accounts().isEmpty()) { - if (desktopSession != "ubuntu") { - qCInfo(lcApplication) << "System tray still not available, showing window and trying again later"; - app.showMainDialog(); - QTimer::singleShot(DelayedTrayRetryMs, &app, &Application::tryTrayAgain); - } else { - // Ubuntu desktops may operate acceptably without reporting a traditional tray here. - qCInfo(lcApplication) << "System tray still not available, but assuming it's fine on 'ubuntu' desktop"; - } + return; + } + + if (app.backgroundMode() || AccountManager::instance()->accounts().isEmpty()) { + return; } + + if (desktopSession == "ubuntu")) { // FIXME: This seems too strict; XDG_CURRENT_DESKTOP can be a composite (e.g. "ubuntu:gnome") + // Ubuntu desktops may operate acceptably without reporting a traditional tray here. + qCInfo(lcApplication) << "System tray still not available, but assuming it's fine on Ubuntu-like desktop"; + return; + } + + qCInfo(lcApplication) << "System tray still not available, showing window and trying again later"; + app.showMainDialog(); + QTimer::singleShot(DelayedTrayRetryMs, &app, &Application::tryTrayAgain); } }