Details
-
Bug
-
Resolution: Unresolved
-
P3: Somewhat important
-
None
-
5.15.2
-
None
-
windows11,显示器分辨率2560x1440
Description
My code uses the following interface
The high resolution support interface was invoked before QApplication construction(High-DPI):
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
Hardware environment
Operating System:windows11
Monitor resolution:2560x1440
Bug triggering procedure
1. Windows system scaling for 100% of the time to run the program, the initial call QHighDpiScaling: : updateHighDpiScaling () method, m_active will be set to false
2. Change the Windows scaling to 150%, the first to enter the QtWindows: : DisplayChangedEvent event handling, QWindowSystemInterface: : handleScreenGeometryChange method can construct the corresponding event.
void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const QRect &geometry, const QRect &availableGeometry) { QWindowSystemInterfacePrivate::ScreenGeometryEvent *e = new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, QHighDpi::fromNativeScreenGeometry(geometry, screen), QHighDpi::fromNative(availableGeometry, screen, geometry.topLeft())); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); }
The geometry passed in when constructing a ScreenGeometryEvent here, without scaling, is 2560x1440.
3. Tracking QHighDpi::fromNativeScreenGeometry -> QHighDpiScaling::factor -> QHighDpiScaling::scaleAndOrigin
QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QScreen *screen, QPoint *nativePosition) { if (!m_active) return { qreal(1), QPoint() }; if (!screen) return { m_factor, QPoint() }; // the global factor return scaleAndOrigin(screen->handle(), nativePosition); }
The value of m_active here is false, so the returned scaling factor is 1, so the geometry passed in when constructing ScreenGeometryEvent does not compute the scaling factor.
4. Followed by a trigger QGuiApplicationPrivate: : processScreenLogicalDotsPerInchChange event handling, This method also can call QHighDpiScaling: : updateHighDpiScaling (), m_active values will change to true at this time.
5. Then will trigger QGuiApplicationPrivate: : processScreenGeometryChange event handling, In this method, the geometry and availableGeometry are obtained from the ScreenGeometryEvent constructed in Step 2 and assigned to QScreen, both of which are unscaled error values. The subsequent retrieval of geometry and availableGeometry from QScreen will be incorrect.
Note
The geometry error only results when changing from 100% to another scale for the first time, because m_active is true after Step 4 and false when the first ScreenGeometryEvent is constructed.