QWindowPrivate: Guard against not having any QScreens when updating DPR

On some platforms (Windows and macOS) it has been observed that the
platform layer removes all screens, without providing a dummy screen.
This results in QGuiApplication::screens() being empty. As updating
the cached DPR for a window is part of the window moving to a new
screen, we have to guard for the case where the window moves to
a nullptr screen (because QGuiApplication::primaryScreen() is now
null).

We use the QGuiApplication::devicePixelRatio() fallback path, which
returns 1.0 if there are no screens.

Fixes: QTBUG-128390
Pick-to: 6.7
Change-Id: I3ba20590047f1ef49c8d3ac5b7556b814a105ce4
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit fbf957de5feded9cbbd60feacaa08c9902815c38)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Wang Yu 2024-08-28 11:45:06 +08:00 committed by Qt Cherry-pick Bot
parent e5d96ae7d4
commit 29b141d88f

View File

@ -1413,11 +1413,19 @@ bool QWindowPrivate::updateDevicePixelRatio()
{
Q_Q(QWindow);
// If there is no platform window use the associated screen's devicePixelRatio,
// which typically is the primary screen and will be correct for single-display
// systems (a very common case).
const qreal newDevicePixelRatio = platformWindow ?
platformWindow->devicePixelRatio() * QHighDpiScaling::factor(q) : q->screen()->devicePixelRatio();
const qreal newDevicePixelRatio = [this, q]{
if (platformWindow)
return platformWindow->devicePixelRatio() * QHighDpiScaling::factor(q);
// If there is no platform window use the associated screen's devicePixelRatio,
// which typically is the primary screen and will be correct for single-display
// systems (a very common case).
if (auto *screen = q->screen())
return screen->devicePixelRatio();
// In some cases we are running without any QScreens, so fall back to QGuiApp
return qGuiApp->devicePixelRatio();
}();
if (newDevicePixelRatio == devicePixelRatio)
return false;