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

macOS: make activation events synchronous

    XMLWordPrintable

Details

    • Task
    • Resolution: Unresolved
    • P2: Important
    • None
    • None
    • QPA
    • None
    • macOS

    Description

      We would like to make activation events synchronous in order to keep window activation state in sync with the platform and prevent delivering stale activation events that has been queued up. 

      The change itself is implemented in https://codereview.qt-project.org/#/c/216345/

      Synchronous activation events has the side effect of changing event timing; in particular activation and focus change will happen sooner after show() has been called. This exposes latent timing issues in Qt code that need to be addressed.

      tst_qfiledialog: 

      https://codereview.qt-project.org/220894

      https://codereview.qt-project.org/220895

      QCocoaEventDispatcher:

      https://codereview.qt-project.org/220896

      tst_QGraphicsItem::QTBUG_6738_missingUpdateWithSetParent()

      This test
      1) shows a QGraphicsView
      2) calls QApplication::setActiveWindow(view)
      3) calls QTest::qWaitForWindowActive(&view)
      4) waits for the view to be painted: QTRY_VERIFY(view.repaints > 0);
      5) resets view.repaints; frobs the view; waits for the view to be repainted again: QTRY_COMPARE(view.repaints, 1);

      The test fails when the QTRY_COMPARE in step 5) times out on a repaints value of 2. This can be triggered by running the test repeatedly, and most likely also by running other tests before it. 

      Causes:

      a) macOS may decide to make the window key immediately on show() in step 1), which makes qWaitForWindowActive() return immediately without processing events, before the window is exposed.

      b) Showing the window generates two paint events (one from NSView drawRect/Expose, one posted). The QTRY_VERIFY in step 4) allows for this, but does not guarantee that both events have actually been processed. The late paint event is delivered when QTRY_COMPARE in step 5 processes events again.

       Possible fixes (choose as many as you like):

      • Fix the test: Use qWaitForWindowExposed() in the test. This makes it pass by waiting for the expose paint event and processing events while doing so.
      • Fix QTestLib: Make qWaitForWindowActive() call qWaitForWindowExposed(). At least my impression is that qWaitForWindowActive() is used as a stricter that qWaitForWindowExposed() with additional requirements.
      • Fix QtGui: Make the platform plugins send Expose events before Activate events: the Active state is a sub-state of the Exposed state. (I would implement this by suppressing Activate until Expose time) The general consensus seems to be that active and exposed are and should be unordered though.

      Implemented a variant of fixing the test: https://codereview.qt-project.org/#/c/222431/

       

      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:
            2 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes