From 0d46bfd4755a223182e64cf112ab7d8abf9f2175 Mon Sep 17 00:00:00 2001 From: David Redondo Date: Wed, 8 Jun 2022 11:25:59 +0200 Subject: [PATCH] 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 Reviewed-by: David Edmundson Reviewed-by: Aleix Pol Gonzalez --- .../platforms/wayland/qwaylandintegration.cpp | 3 +++ src/plugins/platforms/wayland/qwaylandwindow.cpp | 14 +++++++++++++- src/plugins/platforms/wayland/qwaylandwindow_p.h | 3 +++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index 33d47e4ca6c..a874c55a3ca 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -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 diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 888c4639970..85266422d42 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -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(newScreen)->scale(); if (scale != mScale) { diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h index e3f59a1d256..66d5bdade88 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow_p.h +++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h @@ -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;