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

Broken insitialization of High DPI Scaling

    XMLWordPrintable

Details

    • Bug
    • Resolution: Duplicate
    • P2: Important
    • None
    • 6.3.0
    • GUI: High-DPI
    • None
    • Windows

    Description

      I have desktop setup consisting of 2 screens and a layout like on image below

      Screen scales:

      #1 - 175%

      #2 - 100%

      and there is no any environment varialbe set that affects scaling.

       

      Application creates QScreen object for each screen in order : #2, #1

      Let's see what is happening on application start.

      First, QHighDpiScaling::initHighDpiScaling() is called and it initializes static member QHighDpiScaling::m_active

      // Set initial active state
      m_active = m_globalScalingActive || m_usePlatformPluginDpi;
      

      _*where _m_usePlatformPluginDpi* is true by default.

      Then QScreen for display #2 is created in QWindowSystemInterface::handleScreenAdded(). Functions inside QScreen construction initilizes geometry of the screen object which are in independent device units. It's important to note that at this moment QHighDpiScaling::m_active is true and returned scale factor is correct (which is 1.0 in fact). After that QHighDpiScaling::updateHighDpiScaling() is called.

      QHighDpiScaling::updateHighDpiScaling() updates value of QHighDpiScaling::m_active with code:

      // Check if any screens (now) has a scale factor != 1 and set
      // m_platformPluginDpiScalingActive if so.
      if (m_usePlatformPluginDpi && !m_platformPluginDpiScalingActive ) {
          const auto screens = QGuiApplication::screens();
          for (QScreen *screen : screens) {
              if (!qFuzzyCompare(screenSubfactor(screen->handle()), qreal(1))) {
                  m_platformPluginDpiScalingActive  = true;
                  break;
              }
          }
      }
      
      m_active = m_globalScalingActive || m_screenFactorSet || m_platformPluginDpiScalingActive;
      

      At this moment QGuiApplication::screens() contains only one screen with scale factor == 1.0. So, here is important that _m_platformPluginDpiScalingActive_ is false (2 others bool variables also false) and as result m_active becomes false too.

      Next we go to creation of next QScreen object for display #1. And here initialization of screen geometry goes wrong. Geometry is calculated by function QPlatformScreen::

      deviceIndependentGeometry().

      QRect QPlatformScreen::deviceIndependentGeometry() const
      {
          qreal scaleFactor = QHighDpiScaling::factor(this);
          QRect nativeGeometry = geometry();
          return QRect(nativeGeometry.topLeft(),   QHighDpi::fromNative(nativeGeometry.size(), scaleFactor));
      }
      

      And here qreal scaleFactor = QHighDpiScaling::factor(this); instead of scale equal to 1.75 returns 1.0. And the reason is that QHighDpiScaling::m_active is false and 1.0 is a fallback value.

       

      Possible solution

      Call QHighDpiScaling::updateHighDpiScaling() after creation of all QScreen objects and not after each one.

      Temporary fix

      Call QHighDpiScaling::setGlobalFactor() to set some custom scale factor and then call second one with scale == 1.0. Call of this function leads to recalculation of screens geometry.

      Test project

      Attachments contains test project to reproduce the bug.

      main.cpp contains defs that can be enabled/disabled. Without temporary fix application outputs:

      "\\\\.\\DISPLAY2" QRect(0,0 3440x1440)
      "\\\\.\\DISPLAY1" QRect(-1920,0 1920x1080)
      

      With temporary fix:

      "\\\\.\\DISPLAY2" QRect(0,0 3440x1440)
      "\\\\.\\DISPLAY1" QRect(-1920,0 1097x617)
      

       

      Attachments

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

        Activity

          People

            sorvig Morten Sørvig
            medyakovvit Vitaly
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes