Priority: P3: Somewhat important
Affects Version/s: 5.15.1, 5.15.2
Component/s: GUI: High-DPI
Commits:dafe9e23638c4fe272044fae91380a225e19193a (qt/qtbase/dev) 0cc492022cd90789f4d452880079f1bec7d70298 (qt/tqtc-qtbase/tqtc/lts-5.15)
The issue is that the method primaryScreen on QGuiApplication assumes that the screen at index zero in QGuiApplicationPrivate::screen_list is always the primary screen.
This is not the case if the user changes their primary screen while the Qt app is running.
Qt app that opens a QWidget popup with the attribute Qt::WA_TranslucentBackground & window flag Qt::FramelessWindowHint set.
User has a high dip multiple monitor setup, in my case (3840 x 2160 DPI 150%) x2.
While the Qt app is running change the main display by using display settings.
In the Qt app click the button to display the popup.
End result is that the popup is transparent and the user can't see it.
In the method QWindowsBackingStore::flush Qt needs to call the Win32 API UpdateLayeredWindowIndirect so the popup can be transparent.
That API takes a dirty rect that is calculated with a frameOffset, the primary screen used to calculate that off set was incorrect, so the frameOffset is incorrect.
And the result of this is that the popup is transparent.
Whenever the main display changes update QGuiApplicationPrivate::screen_list so the new primary screen is always at index zero.
But going by the comment in the monitorEnumCallback method in qwindowsscreen.cpp, it's sounds like this is expected?
// QWindowSystemInterface::handleScreenAdded() documentation specifies that first
// added screen will be the primary screen, so order accordingly.
// Note that the side effect of this policy is that there is no way to change primaryhighlightsv
// screen reported by Qt, unless we want to delete all existing screens and add them
// again whenever primary screen changes.
A another approach would be to update the method QGuiApplication::primaryScreen() to return the correct primary screen.