Work around issues with window positioning on Linux DEs, hardcode tray window to...
authorClaudio Cambra <claudio.cambra@gmail.com>
Wed, 29 Jun 2022 17:57:52 +0000 (19:57 +0200)
committerClaudio Cambra <claudio.cambra@gmail.com>
Mon, 4 Jul 2022 12:11:19 +0000 (14:11 +0200)
Signed-off-by: Claudio Cambra <claudio.cambra@gmail.com>
src/gui/systray.cpp
src/gui/systray.h
src/gui/tray/Window.qml

index d3e4251bb466d36630681d847574abb2eac99f95..04400ee2130895df08904ee9f9d1852e0b47ae0d 100644 (file)
@@ -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
     }
index a1ecdc4a17b817ef0472b75cef8ea8971436d88e..40dfa36f989f80d545765ecb0cb92223c0da2e04 100644 (file)
@@ -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();
index 3b5d80ff38aeb021c3e175a4f058684a48b9efd9..81629711f98ad0ccb2df25448c760a9bce82f320 100644 (file)
@@ -78,10 +78,20 @@ Window {
 \r
     Connections {\r
         target: Systray\r
-        function onShowWindow() {\r
+\r
+        function onShowWindow(position) {\r
+            if(trayWindow.visible) {\r
+                return;\r
+            }\r
+\r
             accountMenu.close();\r
             appsMenu.close();\r
-            Systray.positionWindow(trayWindow);\r
+\r
+            if(position === Systray.WindowPosition.Center) {\r
+                Systray.positionWindowAtScreenCenter(trayWindow);\r
+            } else {\r
+                Systray.positionWindowAtTray(trayWindow);\r
+            }\r
 \r
             trayWindow.show();\r
             trayWindow.raise();\r
@@ -90,6 +100,7 @@ Window {
             Systray.setOpened();\r
             UserModel.fetchCurrentActivityModel();\r
         }\r
+\r
         function onHideWindow() {\r
             trayWindow.hide();\r
             Systray.setClosed();\r