Keep toplevel windows in the top left corner of the screen

We can't know the actual position of a window on the screen. This causes
an issue when Widgets try to position a popup/menu absolutely and keep
it on the screen when the screen geometry doesn't include (0,0).
Instead report their positions always as the top left corner of
the screen that they are on.
This new behavior can be disabled for qt-shell or via an environment
variable by users that rely on the old behavior.

Fixes: QTBUG-85297
Change-Id: Iacb91cb03a0df87af950115760d2f41124ac06a3
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: David Edmundson <davidedmundson@kde.org>
Reviewed-by: Aleix Pol Gonzalez <aleixpol@kde.org>
This commit is contained in:
David Redondo 2022-06-08 11:25:59 +02:00
parent 64be7816a8
commit 0d46bfd475
3 changed files with 19 additions and 1 deletions

View File

@ -86,6 +86,9 @@ QWaylandIntegration::QWaylandIntegration()
return;
}
QWaylandWindow::fixedToplevelPositions =
!qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_FIXED_POSITIONS");
// ### Not ideal...
// We don't want to use QPlatformWindow::requestActivate here, since that gives a warning
// for most shells. Also, we don't want to put this into the specific shells that can use

View File

@ -328,8 +328,13 @@ void QWaylandWindow::setGeometry_helper(const QRect &rect)
}
}
void QWaylandWindow::setGeometry(const QRect &rect)
void QWaylandWindow::setGeometry(const QRect &r)
{
auto rect = r;
if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup
&& window()->type() != Qt::ToolTip) {
rect.moveTo(screen()->geometry().topLeft());
}
setGeometry_helper(rect);
if (window()->isVisible() && rect.isValid()) {
@ -1210,6 +1215,13 @@ void QWaylandWindow::handleScreensChanged()
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
mLastReportedScreen = newScreen;
if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup
&& window()->type() != Qt::ToolTip
&& geometry().topLeft() != newScreen->geometry().topLeft()) {
auto geometry = this->geometry();
geometry.moveTo(newScreen->geometry().topLeft());
setGeometry(geometry);
}
int scale = newScreen->isPlaceholder() ? 1 : static_cast<QWaylandScreen *>(newScreen)->scale();
if (scale != mScale) {

View File

@ -76,6 +76,9 @@ public:
QWaylandWindow(QWindow *window, QWaylandDisplay *display);
~QWaylandWindow() override;
// Keep Toplevels position on the top left corner of their screen
static inline bool fixedToplevelPositions = true;
virtual WindowType windowType() const = 0;
virtual void ensureSize();
WId winId() const override;