From 22464f5005bedc351e6efdd516855c99bf59983a Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 29 Jun 2022 19:57:52 +0200 Subject: [PATCH] Work around issues with window positioning on Linux DEs, hardcode tray window to screen center when new account added Signed-off-by: Claudio Cambra --- src/gui/systray.cpp | 28 +++++++++++++++++++++++----- src/gui/systray.h | 10 ++++++++-- src/gui/tray/Window.qml | 15 +++++++++++++-- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/gui/systray.cpp b/src/gui/systray.cpp index d3e4251bb..04400ee21 100644 --- a/src/gui/systray.cpp +++ b/src/gui/systray.cpp @@ -118,8 +118,18 @@ Systray::Systray() connect(UserModel::instance(), &UserModel::addAccount, this, &Systray::openAccountWizard); +#if defined(Q_OS_MACOS) || defined(Q_OS_WIN) connect(AccountManager::instance(), &AccountManager::accountAdded, - this, &Systray::showWindow); + this, [this]{ emit showWindow(); }); +#else + // Since the positioning of the QSystemTrayIcon is borked on non-Windows and non-macOS desktop environments, + // we hardcode the position of the tray to be in the center when we add a new account from somewhere like + // the wizard. Otherwise with the conventional method we end up with the tray appearing wherever the cursor + // is placed + + connect(AccountManager::instance(), &AccountManager::accountAdded, + this, [this]{ emit showWindow(WindowPosition::Center); }); +#endif } void Systray::create() @@ -357,7 +367,7 @@ void Systray::pauseResumeSync() /* Helper functions for cross-platform tray icon position and taskbar orientation detection */ /********************************************************************************************/ -void Systray::positionWindow(QQuickWindow *window) const +void Systray::positionWindowAtTray(QQuickWindow *window) const { if (!useNormalWindow()) { window->setScreen(currentScreen()); @@ -366,6 +376,16 @@ void Systray::positionWindow(QQuickWindow *window) const } } +void Systray::positionWindowAtScreenCenter(QQuickWindow *window) const +{ + if(!useNormalWindow()) { + window->setScreen(currentScreen()); + const QPoint windowAdjustment(window->geometry().width() / 2, window->geometry().height() / 2); + const auto position = currentScreen()->virtualGeometry().center() - windowAdjustment; + window->setPosition(position); + } +} + void Systray::forceWindowInit(QQuickWindow *window) const { // HACK: At least on Windows, if the systray window is not shown at least once @@ -399,9 +419,7 @@ void Systray::positionNotificationWindow(QQuickWindow *window) const window->setPosition(position); } else { // For other DEs we play it safe and place the notification in the centre of the screen - const QPoint windowAdjustment(window->geometry().width() / 2, window->geometry().height() / 2); - const auto position = currentScreen()->geometry().center();// - windowAdjustment; - window->setPosition(position); + positionWindowAtScreenCenter(window); } // TODO: Get actual notification positions for the DEs } diff --git a/src/gui/systray.h b/src/gui/systray.h index a1ecdc4a1..40dfa36f9 100644 --- a/src/gui/systray.h +++ b/src/gui/systray.h @@ -77,6 +77,9 @@ public: enum class NotificationPosition { Default, TopLeft, TopRight, BottomLeft, BottomRight }; Q_ENUM(NotificationPosition); + enum class WindowPosition { Default, Center }; + Q_ENUM(WindowPosition); + void setTrayEngine(QQmlApplicationEngine *trayEngine); void create(); void showMessage(const QString &title, const QString &message, MessageIcon icon = Information); @@ -91,7 +94,6 @@ public: Q_INVOKABLE bool syncIsPaused(); Q_INVOKABLE void setOpened(); Q_INVOKABLE void setClosed(); - Q_INVOKABLE void positionWindow(QQuickWindow *window) const; Q_INVOKABLE void forceWindowInit(QQuickWindow *window) const; Q_INVOKABLE void positionNotificationWindow(QQuickWindow *window) const; @@ -103,8 +105,10 @@ signals: void openHelp(); void shutdown(); + // These window signals are listened to in Window.qml void hideWindow(); - void showWindow(); + void showWindow(WindowPosition position = WindowPosition::Default); + void openShareDialog(const QString &sharePath, const QString &localPath); void showFileActivityDialog(const QString &objectName, const int objectId); void sendChatMessage(const QString &token, const QString &message, const QString &replyTo); @@ -112,6 +116,8 @@ signals: public slots: void slotNewUserSelected(); + void positionWindowAtTray(QQuickWindow *window) const; + void positionWindowAtScreenCenter(QQuickWindow *window) const; private slots: void slotUnpauseAllFolders(); diff --git a/src/gui/tray/Window.qml b/src/gui/tray/Window.qml index 3b5d80ff3..81629711f 100644 --- a/src/gui/tray/Window.qml +++ b/src/gui/tray/Window.qml @@ -78,10 +78,20 @@ Window { Connections { target: Systray - function onShowWindow() { + + function onShowWindow(position) { + if(trayWindow.visible) { + return; + } + accountMenu.close(); appsMenu.close(); - Systray.positionWindow(trayWindow); + + if(position === Systray.WindowPosition.Center) { + Systray.positionWindowAtScreenCenter(trayWindow); + } else { + Systray.positionWindowAtTray(trayWindow); + } trayWindow.show(); trayWindow.raise(); @@ -90,6 +100,7 @@ Window { Systray.setOpened(); UserModel.fetchCurrentActivityModel(); } + function onHideWindow() { trayWindow.hide(); Systray.setClosed();