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

DPI configuration on X11

    XMLWordPrintable

Details

    • Task
    • Resolution: Unresolved
    • P2: Important
    • 6.0
    • 5.15, 6.x
    • QPA, QPA: X11/XCB
    • None

    Description

      DPI configuration on X11 has recently seen several changes (and reverts) in Qt 5. There are competing proposals for how it should work.

      For Qt 6 (and maybe Qt 5.15.x) we'd like to find a way to make DPI configuration work for as many X11 users as possible, and then document what the Qt approach is.

      Goals

      • The XCB platform plugin should provide a DPI value for each screen
      • Qt applications should behave like other applications on X11, and not require special settings.
      • Configuration on single-screen systems using the screen settings dialogs on KDE and GNOME must (continue to) work
      • Using logical DPI is preferred (over physical DPI), since this allows user adjustments for UI size preferences and viewing distance.

      X11 provides several APIs/properties for getting screen DPI and physical size:

      • Xft.dpi:
        • Global logical DPI value.
        • API: xcb_xrm_resource_get_string(…,”Xft.dpi" … )
        • Changing the screen scale settings in GNOME will adjust this value.
      • xcb_screen_t
        • Global pixel size and physical size (for the virtual desktop)
        • API: xcb_screen_t
      • Xinerama?
        • Does not provide dpi or physical size information

      The reported physical sizes are sometimes inaccurate (examples):
      0 mm * 0 mm, (no value)
      16 mm * 9 mm, (the aspect ratio)
      X mm * Y mm (back-calculated values which gives a DPI of 96)

      Qt platform plugins implement the following functions to provide the per-screen logical DPI to QtGui

      • QScreen::logicalDpi()
      • QScreen::logicalBaseDpi() [96 for X11]

      (For Qt <5.14, the platform plugin could report a scale factor as well. QtGui now computes the scale factor from the DPI values when AA_HighDpiScaling is enabled).

      The platform plugin can compute a DPI value based on pixel size and pysical size, in cases where (per-screen) logical DPI is not available. The result is physical DPI, which might not be exactly what the user wants.

      Current Qt behavior (5.15) - priority

      1. Use global Xft.dpi value, if available
      2. Calculate global DPI using the reported physical size given by the xcb_screen_t struct.

      Suggested Changes (updated)

      1 Make QXcbScreen::logicalDpi() return logical DPI only (by reading Xft.dpi); fall back to 96 if no logical DPI value is available. Don’t calculate logical DPI based on physical size.

      This is effectively already happening in many cases, since X servers fake the virtual desktop physical size such that the calculated DPI ends up at 96.

      We should restrict this further to avoid surprises for the cases where the X server returns the actual physical size. As a first step, restrict the DPI to 96+: https://codereview.qt-project.org/c/qt/qtbase/+/303600

      2 Document an option for making high-dpi scaling use physical DPI. We have the QT_USE_PHYSICAL_DPI environment variable already (needs a bugfix: https://codereview.qt-project.org/c/qt/qtbase/+/302865)

      QXcbScreen::physicalSize() already returns per-screen values from randr; no changes are needed here.

      Appendix

      links

      X11 DPI information retrieval tool: https://github.com/Oblomov/xdpi/
      Arch-linux HiDPI Wiki: https://wiki.archlinux.org/index.php/HiDPI

      The xrandr scaling option for configuring mixed-dpi displays

      This uses xrandr to scale the low-dpi outputs, which it possible to set a global DPI. This makes all applications happy.

      See https://wiki.archlinux.org/index.php/HiDPI

      1. Run ./xrandr , make a note of the output names and pixel sizes:
        Virtual1 connected primary 2880x1800+0+0
        Virtual2 connected 1920x1200+2880+450
      2. Scale each low-dpi output; using a factor corresponding to the difference in display DPI
        xrandr --output Virtual2 --scale 2x2
      3. Set a global Xft.dpi value using e.g. KDE or GNOME screen settings
         

       

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-84082
          # Subject Branch Project Status CR V

          Activity

            People

              sorvig Morten Sørvig
              sorvig Morten Sørvig
              Veli-Pekka Heinonen Veli-Pekka Heinonen
              Votes:
              4 Vote for this issue
              Watchers:
              17 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes