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

Crash when detaching primary monitor/leaving virtual desktop if there are native widgets in hierarchy

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • 5.3.2
    • 5.1.1, 5.2.1, 5.3.1, 5.4.0
    • GUI: Window management
    • Windows 7
    • 9c3a58a913a7e59359146264ee59d40d703d4db2 (5.3 branch, 29.8.2014, 5.3.2/3?)

    Description

      On Windows 7, if a user disconnects a monitor, my program crashes.
      I've done a lot of testing to track down the problem. I am attaching a sample application that crashes every time. After changing screens, click on the tab that is not showing, and the program will crash.

      There are a few issues in the code that I found.
      First, QWidgetWindow::repaintWindow() calls QBackingStore::markDirty() without checking if the rect is empty, which leads to a failed assertion in QWidgetBackingStore::markDirty. If you fix that issue you will see other issues.

      The main issue is that when a QScreen is destroyed, the QWindow::destroy() method is called. This method recursively destroys child windows. After that the QWindow::create() method is called to recreate the window, but this is not recursive. So you have a bunch of child QWindows that have deleted their QPlatformWindows.

      You can see this right away as the log fills up with messages like this:

      QBackingStore::flush() called for QWidgetWindow(0xd200d8, name = "centralWidgetWindow") which does not have a handle.

      You can fix this by recursively creating child windows when handling the screenDestroyed signal.

      Then you are still left with the bug reported in QTBUG-38650, which is that the window doesn't appear on the screen when you unplug the monitor. Although it will come back if make these changes and then plug the monitor back in.

      There are some changes in the 5.4 branch regarding screen changes. I was hopeful that they might address these issues, but as of today (2014-08-15), they do not.

      Analysis of the crashes (see qtbug40187_stack.txt): The mainwindow as such re-creates fine, crashes occur later when fex switching tabs. This invokes setVisible(true) on the label window. QWindow::setVisible() calls create on the label window, which fails in the QPA plugin since it cannot create child windows with the missing parent (tab page widget). platformWindow->setVisible() then crashes. On XCB, this does not crash, but the child windows are created as top levels.

      Attachments

        1. MonitorSwitch.zip
          7 kB
        2. qtbug40187_stack.txt
          15 kB
        3. qtbug40817.zip
          3 kB

        Issue Links

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

          Activity

            People

              dzedsystems Dyami Caliri
              dzedsystems Dyami Caliri
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes