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

QScreen::availableGeometry().topLeft() is wrong for high-DPI displays

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.7
    • GUI: High-DPI
    • None
    • Linux/X11, Windows
    • a0f53ec97 (dev)

    Description

      QScreen::geometry() has this thing where there size of the QRect is in device-independent coordinates and the topLeft is in device coordinates. In some cases QScreen::availableGeometry().topLeft() will be computed by mixing device-independent and device-dependent coordinates leading to a nonsense value. The case where this happens is when availableGeometry.topLeft() == geometry.topLeft().

      The relevant code in src\gui\kernel\qscreen.cpp looks like this:

      void QScreenPrivate::updateGeometry()
      {
          qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
          QRect nativeGeometry = platformScreen->geometry();
          geometry = QRect(nativeGeometry.topLeft(), QHighDpi::fromNative(nativeGeometry.size(), scaleFactor));
          availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), scaleFactor, geometry.topLeft());
      

      The line for geometry explicitly preserves topLeft and only scales the size, whereas availableGeometry is handled differently. Here the topleft will be computed via these functions from src\gui\kernel\qhighdpiscaling_p.h:

      inline QPoint scale(const QPoint &pos, qreal scaleFactor, QPoint origin = QPoint(0, 0))
      {
           return (pos - origin) * scaleFactor + origin;
      }
      
      inline QRect scale(const QRect &rect, qreal scaleFactor, QPoint origin = QPoint(0, 0))
      {
          return QRect(scale(rect.topLeft(), scaleFactor, origin), scale(rect.size(), scaleFactor));
      }
      
      template <typename T>
      inline T fromNative(const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
      {
          return scale(value, qreal(1) / scaleFactor, origin);
      }
      

      I believe the fix is compute availableGeometry in exactly the same way as geometry.

      Background info

      The behaviour for screen size and screen position is documented in https://doc.qt.io/qt-6/highdpi.html where it says:

      Specifically, Qt will scale the screen size (resulting in a "smaller" screen for positive scale factors), but will not change the screen position. This will produce an islands-of-screens type virtual desktop geometry.

      Attachments

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

        Activity

          People

            sorvig Morten Sørvig
            ts Thomas Sondergaard
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes