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

Issues with screen attach/detach/sleep/property changes

    XMLWordPrintable

    Details

    • Type: Epic
    • Status: Open
    • Priority: P1: Critical
    • Resolution: Unresolved
    • Affects Version/s: 5.13.1, 5.13.2, 5.14
    • Fix Version/s: 5.14.0 RC1
    • Component/s: QPA
    • Labels:
      None
    • Epic Name:
      macOS: Screen issues
    • Platform/s:
      macOS

      Description

      Events

      NSScreen reconfiguration

      • Is done in response to _NSCGSDisplayCGSNotificationHandler, which calls _NSApplicationReactToDisplayChanged.
        • This in turn calls [_NSScreenConfiguration invalidateConfigurationForReason:0x1], which refreshes NScreen.screens based on the new display info.
        • It then calls [NSApplication _reactToScreenInvalidation], which schedules a block to run on the next runloop pass.
          • This block calls [NSApplication _reactToScreenInvalidationImmediately:] when run, which among other things:
            • Updated depth for window, triggering NSWindowDidChangeBackingPropertiesNotification
            • Send screen change event to window, triggering NSWindowDidChangeScreenNotification
            • Moves windows if needed, triggering NSWindowDidMoveNotification
          • After all this, the block sends a NSApplicationDidChangeScreenParametersNotification

      The problem with this flow from Qt's point of view is that the screen parameter notification comes in after the notifications for the window. We'd like to know about the screen update before all this happens, so we can process those events with an updated view of the screens.

      CGDisplayReconfigurationCallBack

      This is part of Quartz Display Services. It has two callbacks when a display change happens.

      1. First the callback is called with the kCGDisplayBeginConfigurationFlag, via displayWillConfigNotifyProc
      2. Then the callback is called with the changed flags after the change has happened, eg. kCGDisplayAddFlag, via displayConfigFinalizedProc

      Both of these are delivered as events from the window server. The problem with this API is that the second callback is not guaranteed to happen after _NSCGSDisplayCGSNotificationHandler, at least not in practice, so we can't rely on the NSScreen array to be up to date at that point.

      Debugging

      Running this in a standalone terminal will show relevant debug output (assuming rasterwindow example used for testing):

      sudo log stream --color always --level debug --process rasterwindow --style compact --type log --predicate 'subsystem == "com.apple.AppKit" || senderImagePath CONTAINS "QtCore"' | c++filt -n
      

      Pass -NSScreenLoggingEnabled YES as arguments to the application to trigger screen configuration logging from AppKit.

      Test cases

      Switching GPUs

      Changing resolution

      Mirroring on/off

      Display sleep

      Changing main/primary display

      Connecting/disconnecting external display

        Attachments

          Issue Links

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

            Activity

              People

              Assignee:
              vestbo Tor Arne Vestbø
              Reporter:
              vestbo Tor Arne Vestbø
              RnD Owner:
              Tor Arne Vestbø
              Votes:
              2 Vote for this issue
              Watchers:
              6 Start watching this issue

                Dates

                Created:
                Updated:

                  Gerrit Reviews

                  There are no open Gerrit changes