Преглед изворни кода

Work around issues with window positioning on Linux DEs, hardcode tray window to screen center when new account added

Signed-off-by: Claudio Cambra <claudio.cambra@gmail.com>
Claudio Cambra пре 3 година
родитељ
комит
22464f5005
3 измењених фајлова са 44 додато и 9 уклоњено
  1. 23 5
      src/gui/systray.cpp
  2. 8 2
      src/gui/systray.h
  3. 13 2
      src/gui/tray/Window.qml

+ 23 - 5
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
     }

+ 8 - 2
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();

+ 13 - 2
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();