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

OS X: Move expose event handling to [QNSView drawRect]

    XMLWordPrintable

    Details

    • Type: Task
    • Status: Closed
    • Priority: P2: Important
    • Resolution: Done
    • Affects Version/s: None
    • Fix Version/s: 5.10.0 Alpha
    • Component/s: QPA
    • Labels:
      None
    • Platform/s:
      macOS

      Description

      The expected behavior of Expose events has changed during the lifetime of Qt 5. We now want to be strict about when Expose events are sent, since they indicate that an immediate repaint is needed. Obscure events should also be sent at correct times to stop animations.

      The Cocoa platform plugin has evolved to follow these changes, but has reached a state where there are potentially many sources for sending expose events, making it hard to reason about when they are sent. In addition the Cocoa platform plugin has special code paths for running under under QTestLib. It is desirable to simplify and unify the implementation.

      We can use [NSView drawRect] as the canonical source of "you are on screen and should draw now". This is similar to what the iOS platform plugin already does.

      Pending Patches:

      https://codereview.qt-project.org/#/c/143798/ (Rework expose handling)
      https://codereview.qt-project.org/#/c/146850/ (Document Expose event)
      https://codereview.qt-project.org/#/c/146851/ (tst_qgl fix)
      https://codereview.qt-project.org/#/c/146564/ (QCocoaCursor:setPos())

      Related Bug Reports
      QTBUG-50684

      Specific issues encountered:

      Stricter Expose/Obscure handling breaks some tests:

      • Some tests accidentally obscure a window (e.g. with another window), and still expect paint events. [Solution: fix the test]
      • The GLWidget-as-viewport widget case:
            QGraphicsView view;
            view.setViewport(new QGLWidget);
            waitForWindowExposed(&view); // won't happen
        

        The issue here is that the (top-level) QWindow for the QGraphicsView is completely obscured by the viewport window and won't receive the expose event. Possible solutions:

        • QTest::waitForWindowExposed should use some other (self-contained) means to determine if a window is on screen.
        • The native viewport widget is a QtWidgets internal matter: that module should make sure the top-level QWindow gets expose events (somehow).
        • Fix the test: you can't wait for exposed on that window.
        • Send expose immediately followed by Obscure

      QCursor::setPos instability in tst_qabstractitemview.cpp

      tst_QBackingStore - crash

      • -can be reproduced locally on OS X 10.10 (and probably below), does not happen on 10.11. Quite annoying chicken-egg problem: while we're inside platformWindow = createPlatformWindow(...), at some point here we also call
        syncWindowState, which can end up in performZoom/performMiniaturize: etc.; this can trigger drawRect. Our QNSView will try to updateExposedState on a half-created window and at some point somewhere in
        QCocoaBackingStore window()->handle() will be nullptr, since it's a 'platformWindow' from the assignment expression above - it's not assigned yet.
        Update: this can be fixed if we add a guard in drawRect: if (!m_platformWindow->m_inConstructor) .... proceed with expose - I think there's nothing we can do about the fact that some object is, indeed, half-constructed and some
        pointers are not valid yet.

      qtdeclarative:

      • FAIL! : qmltest::ClickWindow::test_clickBothWindows() 'verify()' returned FALSE. () - cannot be reproduced if running as a standalone test
      • tst_qquickwindow::hideThenDelete(persistent:SG=false,GL=false) '(!window.isExposed())' returned FALSE. () (and three more versions of the same test) -something weird: when running hideThenDelete the second time,
        a window first receives expose event with null region (expected), but the there is the second expose event with non-null region (making QTRY_VERIFY(!exposed) to fail). Looks like a result of not running event loop properly
        and delaying drawRect (actually, self.window is not even visible at this point).

      https://bugreports.qt.io/browse/QTBUG-45975 - this one shows another (probably unrelated) problem that still can (again, probably) be addressed by the upcoming re-work in Cocoa plugin.

        Attachments

          Issue Links

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

            Activity

              People

              Assignee:
              sorvig Morten Sørvig
              Reporter:
              sorvig Morten Sørvig
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Gerrit Reviews

                  There are no open Gerrit changes