Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-108386

Windows: QScreen::devicePixelRatio sometimes inaccurate results

    XMLWordPrintable

Details

    • Bug
    • Resolution: Incomplete
    • P2: Important
    • None
    • 5.15.1
    • QPA: Windows
    • None
    • Windows

    Description

      Repro Steps:

      1. Set primary display to 100% DPI scaling
      2. Build and launch the app below
      3. Close the app's main window
      4. Set primary display to 125% DPI scaling
      5. Restore the app from the system tray icon (via double click)
      6. Observe

      Expected Result:

      • The pixel ratio is "1.25"

      Actual Result:

      • The pixel ratio remains at "1"

      Additional Info:

      • Qt seems to be relying on the WM_SETTINGCHANGE event to update the pixel ratio (see QGuiApplicationPrivate::processScreenLogicalDotsPerInchChange).  WM_SETTINGCHANGE is sent to top level windows so the ratio is not updated properly if no Qt windows are open when the DPI is changed.
      • If you skip step 3 (closing the window), the pixel ratio updates as expected

      Code sample:

      #include <QApplication>
      #include <QLabel>
      #include <QScreen>
      #include <QStyle>
      #include <QSystemTrayIcon>
      
      int main(int argc, char *argv[])
      {
      	QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
      	QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
      
      	QApplication app(argc, argv);
      	app.setApplicationName("Qt cached pixel ratio bug");
      	app.setQuitOnLastWindowClosed(false);
      
      	QLabel window;
      	window.resize({ 300, 100 });
      	window.show();
      
      	auto updateText = [&window]()
      	{
      		const qreal ratio = QGuiApplication::primaryScreen()->devicePixelRatio();
      		window.setText(QString("Primary screen pixel ratio: %1").arg(ratio));
      	};
      	updateText();
      
      	QScreen* screen = QGuiApplication::primaryScreen();
      	QObject::connect(screen, &QScreen::logicalDotsPerInchChanged, updateText);
      	QObject::connect(screen, &QScreen::physicalDotsPerInchChanged, updateText);
      
      	QSystemTrayIcon icon;
      	icon.setIcon(QApplication::style()->standardIcon(QStyle::SP_ComputerIcon));
      	icon.show();
      
      	// Not using a context menu here because opening the context menu creates
      	// a long-lived HWND that will handle the WM_SETTINGCHANGED event. This
      	// would cause the repro steps to work only once per session.
      	QObject::connect(&icon, &QSystemTrayIcon::activated, [&](auto reason)
      	{
      		switch (reason)
      		{
      		case QSystemTrayIcon::DoubleClick:
      			updateText();
      			window.show();
      			break;
      
      		case QSystemTrayIcon::MiddleClick:
      		case QSystemTrayIcon::Context:
      			app.exit();
      			break;
      
      		default:
      			break;
      		}
      	});
      
      	return app.exec();
      }
      
      

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              sorvig Morten Sørvig
              mloftus Mitchell Loftus
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes