Skip to content

Commit

Permalink
Merge pull request #1744 from nextcloud/qt-traygeometry-workaround
Browse files Browse the repository at this point in the history
Fix wrong window position on some linux DEs - worked around invalid g…
  • Loading branch information
misch7 authored Mar 1, 2020
2 parents deb90a6 + 0697c81 commit eb7ed33
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 15 deletions.
62 changes: 51 additions & 11 deletions src/gui/systray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "config.h"
#include "tray/UserModel.h"

#include <QCursor>
#include <QDesktopServices>
#include <QGuiApplication>
#include <QQmlComponent>
Expand Down Expand Up @@ -95,6 +96,17 @@ 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;
Expand Down Expand Up @@ -142,17 +154,32 @@ int Systray::calcTrayWindowX()
int trayIconTopCenterX = (topRight - ((topRight - topLeft) * 0.5)).x();
return trayIconTopCenterX - (400 * 0.5);
#else
QScreen *trayScreen = QGuiApplication::primaryScreen();
QScreen* trayScreen = nullptr;
if (QGuiApplication::screens().count() > 1) {
trayScreen = QGuiApplication::screens().at(screenIndex());
} else {
trayScreen = QGuiApplication::primaryScreen();
}

int screenWidth = trayScreen->geometry().width();
int screenHeight = trayScreen->geometry().height();
int availableWidth = trayScreen->availableGeometry().width();
int availableHeight = trayScreen->availableGeometry().height();
QPoint topRightDpiAware = this->geometry().topRight() / trayScreen->devicePixelRatio();
QPoint topLeftDpiAware = this->geometry().topLeft() / trayScreen->devicePixelRatio();

// get coordinates from top center point of tray icon
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 x coordinate from top center point of tray icon
int trayIconTopCenterX = (topRightDpiAware - ((topRightDpiAware - topLeftDpiAware) * 0.5)).x();
int trayIconTopCenterY = (topRightDpiAware - ((topRightDpiAware - topLeftDpiAware) * 0.5)).y();

if (availableHeight < screenHeight) {
// taskbar is on top or bottom
Expand All @@ -179,15 +206,28 @@ int Systray::calcTrayWindowY()
// don't use availableGeometry() here, because this also excludes the dock
return 22+6;
#else
QScreen *trayScreen = QGuiApplication::primaryScreen();
int screenWidth = trayScreen->geometry().width();
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 = this->geometry().topRight() / trayScreen->devicePixelRatio();
QPoint topLeftDpiAware = this->geometry().topLeft() / trayScreen->devicePixelRatio();

// get coordinates from top center point of tray icon
int trayIconTopCenterX = (topRightDpiAware - ((topRightDpiAware - topLeftDpiAware) * 0.5)).x();
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) {
Expand Down
1 change: 1 addition & 0 deletions src/gui/systray.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class Systray
Q_INVOKABLE bool syncIsPaused();
Q_INVOKABLE void setOpened();
Q_INVOKABLE void setClosed();
Q_INVOKABLE int screenIndex();

signals:
void currentUserChanged();
Expand Down
2 changes: 1 addition & 1 deletion src/gui/tray/UserLine.qml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Window 2.3
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.2

Expand Down
6 changes: 3 additions & 3 deletions src/gui/tray/Window.qml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import QtQml 2.1
import QtQml.Models 2.1
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Window 2.3
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.2
import QtGraphicalEffects 1.0
Expand Down Expand Up @@ -63,8 +63,8 @@ Window {
trayWindow.show();
trayWindow.raise();
trayWindow.requestActivate();
trayWindow.setX( systrayBackend.calcTrayWindowX());
trayWindow.setY( systrayBackend.calcTrayWindowY());
trayWindow.setX( Qt.application.screens[systrayBackend.screenIndex()].virtualX + systrayBackend.calcTrayWindowX());
trayWindow.setY( Qt.application.screens[systrayBackend.screenIndex()].virtualY + systrayBackend.calcTrayWindowY());
systrayBackend.setOpened();
userModelBackend.fetchCurrentActivityModel();
}
Expand Down

0 comments on commit eb7ed33

Please sign in to comment.