Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/desktop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominique Fuchs <32204802+DominiqueFuchs@users.noreply.github.com>2020-04-24 19:34:11 +0300
committerKevin Ottens (Rebase PR Action) <er-vin@users.noreply.github.com>2020-06-15 15:32:25 +0300
commitf44df7f61a80c3bc86164ef1e2c3e9732cdc724e (patch)
treedcfac2a828907642b8cd2eaf12bf8724b7d6a3c1 /src/gui/systray.cpp
parent121e23e322ac373dbff48db08c19cbb64b651d30 (diff)
Major multi monitor improvements and rewrite of tray window positioning
Signed-off-by: Dominique Fuchs <32204802+DominiqueFuchs@users.noreply.github.com>
Diffstat (limited to 'src/gui/systray.cpp')
-rw-r--r--src/gui/systray.cpp176
1 files changed, 66 insertions, 110 deletions
diff --git a/src/gui/systray.cpp b/src/gui/systray.cpp
index 66ac956f2..98d55c1f9 100644
--- a/src/gui/systray.cpp
+++ b/src/gui/systray.cpp
@@ -16,6 +16,7 @@
#include "systray.h"
#include "theme.h"
#include "config.h"
+#include "common/utility.h"
#include "tray/UserModel.h"
#include <QCursor>
@@ -60,6 +61,7 @@ Systray::Systray()
connect(AccountManager::instance(), &AccountManager::accountAdded,
this, &Systray::showWindow);
+
}
void Systray::create()
@@ -69,6 +71,7 @@ void Systray::create()
}
_trayEngine->load(QStringLiteral("qrc:/qml/src/gui/tray/Window.qml"));
hideWindow();
+ emit activated(QSystemTrayIcon::ActivationReason::Unknown);
}
void Systray::slotNewUserSelected()
@@ -85,17 +88,6 @@ bool Systray::isOpen()
return _isOpen;
}
-Q_INVOKABLE int Systray::screenIndex()
-{
- auto qPos = QCursor::pos();
- for (int i = 0; i < QGuiApplication::screens().count(); i++) {
- if (QGuiApplication::screens().at(i)->geometry().contains(qPos)) {
- return i;
- }
- }
- return 0;
-}
-
Q_INVOKABLE void Systray::setOpened()
{
_isOpen = true;
@@ -133,123 +125,87 @@ void Systray::setToolTip(const QString &tip)
QSystemTrayIcon::setToolTip(tr("%1: %2").arg(Theme::instance()->appNameGUI(), tip));
}
-int Systray::calcTrayWindowX()
+bool Systray::syncIsPaused()
{
-#ifdef Q_OS_OSX
- // macOS handles DPI awareness differently
- // and menu bar is always at the top, icons starting from the right
-
- QPoint topLeft = this->geometry().topLeft();
- QPoint topRight = this->geometry().topRight();
- int trayIconTopCenterX = (topRight - ((topRight - topLeft) * 0.5)).x();
- return trayIconTopCenterX - (400 * 0.5);
-#else
- QScreen* trayScreen = nullptr;
- if (QGuiApplication::screens().count() > 1) {
- trayScreen = QGuiApplication::screens().at(screenIndex());
- } else {
- trayScreen = QGuiApplication::primaryScreen();
- }
+ return _syncIsPaused;
+}
- int screenWidth = trayScreen->geometry().width();
- int screenHeight = trayScreen->geometry().height();
- int availableWidth = trayScreen->availableGeometry().width();
- int availableHeight = trayScreen->availableGeometry().height();
-
- QPoint topRightDpiAware = QPoint();
- QPoint topLeftDpiAware = QPoint();
- if (this->geometry().left() == 0 || this->geometry().top() == 0) {
- // tray geometry is invalid - QT bug on some linux desktop environments
- // Use mouse position instead. Cringy, but should work for now
- topRightDpiAware = QCursor::pos() / trayScreen->devicePixelRatio();
- topLeftDpiAware = QCursor::pos() / trayScreen->devicePixelRatio();
+void Systray::pauseResumeSync()
+{
+ if (_syncIsPaused) {
+ _syncIsPaused = false;
+ emit resumeSync();
} else {
- topRightDpiAware = this->geometry().topRight() / trayScreen->devicePixelRatio();
- topLeftDpiAware = this->geometry().topLeft() / trayScreen->devicePixelRatio();
+ _syncIsPaused = true;
+ emit pauseSync();
}
+}
- // get x coordinate from top center point of tray icon
- int trayIconTopCenterX = (topRightDpiAware - ((topRightDpiAware - topLeftDpiAware) * 0.5)).x();
+/********************************************************************************************/
+/* Helper functions for cross-platform tray icon position and taskbar orientation detection */
+/********************************************************************************************/
- if (availableHeight < screenHeight) {
- // taskbar is on top or bottom
- if (trayIconTopCenterX + (400 * 0.5) > availableWidth) {
- return availableWidth - 400 - 12;
- } else {
- return trayIconTopCenterX - (400 * 0.5);
- }
- } else {
- if (trayScreen->availableGeometry().x() > trayScreen->geometry().x()) {
- // on the left
- return (screenWidth - availableWidth) + 6;
- } else {
- // on the right
- return screenWidth - 400 - (screenWidth - availableWidth) - 6;
+/// Return the current screen index based on cursor position
+int Systray::screenIndex()
+{
+ auto qPos = QCursor::pos();
+ for (int i = 0; i < QGuiApplication::screens().count(); i++) {
+ if (QGuiApplication::screens().at(i)->geometry().contains(qPos)) {
+ return i;
}
}
-#endif
+ return 0;
}
-int Systray::calcTrayWindowY()
-{
-#ifdef Q_OS_OSX
- // macOS menu bar is always 22 (effective) pixels
- // don't use availableGeometry() here, because this also excludes the dock
- return 22+6;
-#else
- QScreen* trayScreen = nullptr;
- if (QGuiApplication::screens().count() > 1) {
- trayScreen = QGuiApplication::screens().at(screenIndex());
- } else {
- trayScreen = QGuiApplication::primaryScreen();
- }
-
- int screenHeight = trayScreen->geometry().height();
- int availableHeight = trayScreen->availableGeometry().height();
- QPoint topRightDpiAware = QPoint();
- QPoint topLeftDpiAware = QPoint();
- if (this->geometry().left() == 0 || this->geometry().top() == 0) {
- // tray geometry is invalid - QT bug on some linux desktop environments
- // Use mouse position instead. Cringy, but should work for now
- topRightDpiAware = QCursor::pos() / trayScreen->devicePixelRatio();
- topLeftDpiAware = QCursor::pos() / trayScreen->devicePixelRatio();
- } else {
- topRightDpiAware = this->geometry().topRight() / trayScreen->devicePixelRatio();
- topLeftDpiAware = this->geometry().topLeft() / trayScreen->devicePixelRatio();
- }
- // get y coordinate from top center point of tray icon
- int trayIconTopCenterY = (topRightDpiAware - ((topRightDpiAware - topLeftDpiAware) * 0.5)).y();
-
- if (availableHeight < screenHeight) {
- // taskbar is on top or bottom
- if (trayScreen->availableGeometry().y() > trayScreen->geometry().y()) {
- // on top
- return (screenHeight - availableHeight) + 6;
- } else {
- // on bottom
- return screenHeight - 510 - (screenHeight - availableHeight) - 6;
- }
- } else {
- // on the left or right
- return (trayIconTopCenterY - 510 + 12);
+int Systray::taskbarOrientation()
+{
+// macOS: Always on top
+#if defined(Q_OS_MACOS)
+ return TaskBarPosition::Top;
+// Windows: Check registry for actual taskbar orientation
+#elif defined(Q_OS_WIN)
+ auto taskbarPosition = Utility::registryGetKeyValue(HKEY_CURRENT_USER,
+ "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRects3",
+ "Settings");
+ switch (taskbarPosition.toInt()) {
+ // Mapping windows binary value (0 = left, 1 = top, 2 = right, 3 = bottom) to qml logic (0 = bottom, 1 = left...)
+ case 0:
+ return TaskBarPosition::Left;
+ case 1:
+ return TaskBarPosition::Top;
+ case 2:
+ return TaskBarPosition::Right;
+ case 3:
+ return TaskBarPosition::Bottom;
+ default:
+ return TaskBarPosition::Bottom;
}
+// Else (generally linux DEs): fallback to cursor position nearest edge logic
+#else
+ return 0;
#endif
}
-bool Systray::syncIsPaused()
+QRect Systray::taskbarRect()
{
- return _syncIsPaused;
+#if defined(Q_OS_WIN)
+ return Utility::getTaskbarDimensions();
+#else
+ return QRect(0, 0, 0, 32);
+#endif
}
-void Systray::pauseResumeSync()
+QPoint Systray::calcTrayIconCenter()
{
- if (_syncIsPaused) {
- _syncIsPaused = false;
- emit resumeSync();
- } else {
- _syncIsPaused = true;
- emit pauseSync();
- }
+// QSystemTrayIcon::geometry() is broken for ages on most Linux DEs (invalid geometry returned)
+// thus we can use this only for Windows and macOS
+#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
+ auto trayIconCenter = geometry().center();
+ return trayIconCenter;
+#else
+// On Linux, fall back to mouse position (assuming tray icon is activated by mouse click)
+ return QCursor::pos();
+#endif
}
} // namespace OCC