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:
authorKevin Ottens <kevin.ottens@nextcloud.com>2020-05-20 20:36:57 +0300
committerKevin Ottens (Rebase PR Action) <er-vin@users.noreply.github.com>2020-06-15 15:32:25 +0300
commit6c6dfb15a7d2193b430f55b0deac160e3c4460eb (patch)
tree11f425964414e207be70cdc86ce5e24b66e92a40 /src/gui/systray.cpp
parent83b36b4ab0a5f70b5f32fe001dd57b580afdba9e (diff)
Move all the position computation on the C++ side
The API is just more convenient there, the rect and point types on the QML side are just pale shadow of their C++ counterparts. Also improved a bit the constness of the Systray class. Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Diffstat (limited to 'src/gui/systray.cpp')
-rw-r--r--src/gui/systray.cpp105
1 files changed, 96 insertions, 9 deletions
diff --git a/src/gui/systray.cpp b/src/gui/systray.cpp
index 3370a85f7..5db933983 100644
--- a/src/gui/systray.cpp
+++ b/src/gui/systray.cpp
@@ -61,8 +61,6 @@ Systray::Systray()
connect(AccountManager::instance(), &AccountManager::accountAdded,
this, &Systray::showWindow);
-
- qmlRegisterUncreatableType<Systray>("com.nextcloud.gui", 1, 0, "Systray", "This type is uncreatable, it is exported for its enums");
}
void Systray::create()
@@ -146,8 +144,22 @@ void Systray::pauseResumeSync()
/* Helper functions for cross-platform tray icon position and taskbar orientation detection */
/********************************************************************************************/
+QScreen *Systray::currentScreen() const
+{
+ const auto screens = QGuiApplication::screens();
+ const auto cursorPos = QCursor::pos();
+
+ for (const auto screen : screens) {
+ if (screen->geometry().contains(cursorPos)) {
+ return screen;
+ }
+ }
+
+ return nullptr;
+}
+
/// Return the current screen index based on cursor position
-int Systray::screenIndex()
+int Systray::screenIndex() const
{
auto qPos = QCursor::pos();
for (int i = 0; i < QGuiApplication::screens().count(); i++) {
@@ -158,7 +170,7 @@ int Systray::screenIndex()
return 0;
}
-Systray::TaskBarPosition Systray::taskbarOrientation()
+Systray::TaskBarPosition Systray::taskbarOrientation() const
{
// macOS: Always on top
#if defined(Q_OS_MACOS)
@@ -208,7 +220,7 @@ Systray::TaskBarPosition Systray::taskbarOrientation()
}
// TODO: Get real taskbar dimensions Linux as well
-QRect Systray::taskbarRect()
+QRect Systray::taskbarGeometry() const
{
#if defined(Q_OS_WIN)
QRect tbRect = Utility::getTaskbarDimensions();
@@ -234,15 +246,90 @@ QRect Systray::taskbarRect()
#endif
}
-QPoint Systray::calcTrayIconCenter()
+QRect Systray::currentScreenRect() const
+{
+ const auto screen = currentScreen();
+ const auto rect = screen->geometry();
+ return rect.translated(screen->virtualGeometry().topLeft());
+}
+
+QPoint Systray::computeWindowReferencePoint(int width, int height) const
+{
+ const auto trayIconCenter = calcTrayIconCenter();
+ const auto taskbarRect = taskbarGeometry();
+ const auto taskbarScreenEdge = taskbarOrientation();
+ const auto screenRect = currentScreenRect();
+
+ switch(taskbarScreenEdge) {
+ case TaskBarPosition::Bottom:
+ return {
+ trayIconCenter.x() - width / 2,
+ screenRect.bottom() - taskbarRect.height() - height - 4
+ };
+ case TaskBarPosition::Left:
+ return {
+ screenRect.left() + taskbarRect.width() + 4,
+ trayIconCenter.y()
+ };
+ case TaskBarPosition::Top:
+ return {
+ trayIconCenter.x() - width / 2,
+ screenRect.top() + taskbarRect.height() + 4
+ };
+ case TaskBarPosition::Right:
+ return {
+ screenRect.right() - taskbarRect.width() - width - 4,
+ trayIconCenter.y()
+ };
+ }
+ Q_UNREACHABLE();
+}
+
+QPoint Systray::computeWindowPosition(int width, int height) const
+{
+ auto referencePoint = computeWindowReferencePoint(width, height);
+
+ const auto taskbarScreenEdge = taskbarOrientation();
+ const auto taskbarRect = taskbarGeometry();
+ const auto screenRect = currentScreenRect();
+
+ if (screenRect.right() <= referencePoint.x() + width) {
+ referencePoint.rx() = screenRect.right() - width - 4;
+#if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
+ referencePoint.rx() -= taskbarScreenEdge == TaskBarPosition::Right ? taskbarRect.width() : 0;
+#endif
+ }
+
+ if (referencePoint.x() <= screenRect.left()) {
+ referencePoint.rx() = screenRect.left() + 4;
+#if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
+ referencePoint.rx() += taskbarScreenEdge == TaskBarPosition::Left ? taskbarRect.width() : 0;
+#endif
+ }
+
+ if (referencePoint.y() <= screenRect.top()) {
+ referencePoint.ry() = screenRect.top() + 4;
+
+#if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
+ referencePoint.ry() += taskbarScreenEdge == TaskBarPosition::Top ? taskbarRect.height() : 0;
+#endif
+ }
+ if (screenRect.bottom() <= referencePoint.y() + height) {
+ referencePoint.ry() = screenRect.bottom() - height - 4;
+ }
+
+ return referencePoint;
+}
+
+QPoint Systray::calcTrayIconCenter() const
{
-// QSystemTrayIcon::geometry() is broken for ages on most Linux DEs (invalid geometry returned)
-// thus we can use this only for Windows and macOS
+ // 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)
+ // On Linux, fall back to mouse position (assuming tray icon is activated by mouse click)
return QCursor::pos();
#endif
}