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

High-DPI Change Events for Qt 6

    XMLWordPrintable

Details

    • Task
    • Resolution: Unresolved
    • P2: Important
    • 6.0
    • None
    • GUI: High-DPI
    • None

    Description

      Event kinds and semantics

      There are several event kinds. The events are processed by and propagated through the platform plugin / QPA / QGuiApplication / application. At the QWindow level, the (suggested) event handling is:

      • Screen Change:
        • Update QWindow::screen() and other cached QScreen pointers
        • Don’t do anything else, specific change events will follow
      • DPR (DevicePixelRatio) Change:
        • Don’t run resize or layout code
        • Update any cached DPR values
        • Don’t repaint. Expose/repaint will follow.
      • DPI change:
        • Update any cached DPI values
        • Run all code which scales by DPI
        • Don’t repaint. Expose/repaint will follow.
      • (Expose/Repaint):
        • Paint using the current DPR
        • As described in QTBUG-82676
      • (resize)
        • Run size changed logic/layout code

      There are two ways to trigger change events:

      • the screen configuration is changed
      • the window is moved to a different screen

      There is in general no need to have separate handling of these at the application level. Instead, applications should handle the  QWindow property changes.

      Event Processing

      Platform/QPA/QGuiApplicaton event processing is written to ensure that the application sees a consistent event stream, across all platforms.

      • For example, a DPR change event will always be followed by an Expose/Repaint (if the window needs to be repainted due to the DPR change). This Expose/Repaint will either be generated by the platform or by the Qt QPA/platform layer.

       Event ordering:

      • Use platform ordering ( ? )
      • No guarantee that screen/DPI/DPR change will have a specific ordering
      • The QWindow will get resize/repaint if those actions are required

      Screen Changes:

      Dragging a window to a different screen will at some point cause a screen change - the window->screen() pointer is updated, the DPI or DPR may change, and windows may have to be resized and repainted. Some platforms allow parking a window such that it's visible on more than one screen.

      Observed platform behavior:

      • macOS:
        • The screen change happens when the cursor moves to the other screen.
        • The DPR changes on screen change
        • Window size is not changed
        • The window can be visible on at most one screen - the other screen shows a transparent “shadow” window during window drag, which will disappear on mouse release.
      • Windows (tested with “settings” and “notepad”)
        • The screen change happens when 50% of the window moves to the other screen
        • The DPI changes on screen change
        • The window is resized to match the new DPI, and is also moved to make sure it stays with the new screen as the primary screen and does not snap back.
        • The window can be visible on more than one screen.
        • TODO: it is a bit unclear if this observed behavior is win32 behavior, or is implemented higher in the stack. It could also depend on the DPI awareness level.
      • X11 (Note: test setup only supports setting a global DPI/scale factor, which limits ability to test)
        • The screen change happens when 50% of the window moves to the other screen
        • The DPI changes on screen change
        • The window is not resized.

      High-DPI scaling considerations:

      High-DPI scaling will typically transform DPI change event to DPR change events. For example, consider moving a QWindow from a 100% to a 200% screen on Windows:

      • Qt gets a system DPI change event
      • QHighDpiScaling translates the DPI change to a DPR change
      • The QWindow gets a DPR change event
      • QWindow DPI remains unchanged
      • The QWindow or QPlatformWindow is resized (see below)
      • Finally, thew QWindow gets an expose/repaint and draws at the new DPR.

      Window resize on DPI change

      The effective DPI for a window can change in two ways:

      • The screen’s logical DPI is changed
      • Thew window is moved to a screen with a different logical DPI.

      Qt converts the DPI to a scale factor (e.g. 192 DPI -> 2x). The relationship between the device independent and native coordinate systems is

      device independent x scale factor = native

      The window will need resizing when the scale factor changes and there are two options: either resize the QWindow (device independent) or resize the QPlatformWindow (native).

      1) Resize the QPlatformWindow:

      • The window displays the same amount of content, drawn at a different resolution - intuitively the right behavior for a DPI change
      • Fixed-size windows work as expected
      • Can be tricky to implement on screen changes:
      • make sure the resize does not change the primary screen again (can cause screen change loops)
      • the window manager may refuse to resize the window while it’s being dragged (X11)

      2) Resize the QWindow

      • The window displays a different amount of content
      • Breaks fixed-size windows
      • Easier to implement since we don’t have to resize the native window
      • The current Qt implementation.

      Implementation strategy: Make sure 2) works while investigating if 1) is possible.

      Attachments

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

        Activity

          People

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

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes