Client: Fix initialization of QWaylandWindow::mScale

QWaylandWindow initializes mScale to the scale factor of the currently
assigned screen when it's constructed. However, it doesn't keep track of
subsequent screen changes that may occur afterwards before
QWindow::setVisible(true). For example

    window.setScreen(foo);
    window.create();
    window.setScreen(bar);
    window.show();

In that case, the value of mScale will correspond to the scale factor
of output "foo" when show() is called.

A better place to initialize mScale is when the show() function is
called. Furthermore, since there's wl_surface.preferred_buffer_scale and
fractional_scale_v1.preferred_scale events, QWaylandWindow could stop
guessing the scale factor and rely on the compositor telling us that
information. However, it's important that the compositor sends the
preferred buffer scale before the first configure event arrives.

Fixes: QTBUG-124839
Pick-to: 6.7
Change-Id: I842aaa352d9cb1e53158f64f2ec0cd3734f7ecf3
Reviewed-by: Liang Qi <liang.qi@qt.io>
Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
Vlad Zahorodnii 2024-05-22 12:13:49 +03:00
parent 76f8559ca6
commit 2c9580bf63
2 changed files with 5 additions and 6 deletions

View File

@ -60,8 +60,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
mFrameCallbackTimeout = frameCallbackTimeout;
}
mScale = waylandScreen() ? waylandScreen()->scale() : 1; // fallback to 1 if we don't have a real screen
static WId id = 1;
mWindowId = id++;
initializeWlSurface();
@ -327,6 +325,7 @@ void QWaylandWindow::reset()
mWaitingToApplyConfigure = false;
mCanResize = true;
mResizeDirty = false;
mScale = std::nullopt;
mOpaqueArea = QRegion();
mMask = QRegion();
@ -1481,7 +1480,7 @@ void QWaylandWindow::updateScale()
void QWaylandWindow::setScale(qreal newScale)
{
if (qFuzzyCompare(mScale, newScale))
if (mScale.has_value() && qFuzzyCompare(mScale.value(), newScale))
return;
mScale = newScale;
@ -1490,7 +1489,7 @@ void QWaylandWindow::setScale(qreal newScale)
if (mViewport)
updateViewport();
else if (mSurface->version() >= 3)
mSurface->set_buffer_scale(std::ceil(mScale));
mSurface->set_buffer_scale(std::ceil(newScale));
}
ensureSize();
@ -1552,7 +1551,7 @@ qreal QWaylandWindow::scale() const
qreal QWaylandWindow::devicePixelRatio() const
{
return qreal(mScale);
return mScale.value_or(waylandScreen() ? waylandScreen()->scale() : 1);
}
bool QWaylandWindow::setMouseGrabEnabled(bool grab)

View File

@ -310,7 +310,7 @@ protected:
bool mSentInitialResize = false;
QPoint mOffset;
qreal mScale = 1;
std::optional<qreal> mScale = 1;
QPlatformScreen *mLastReportedScreen = nullptr;
QString mWindowTitle;