Details
-
Task
-
Resolution: Done
-
P2: Important
-
None
-
None
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
It's hard to see how is relevant.- The QCursor::setPos() implementation on Cocoa should perhaps be made synchronous (the current one is async). Discussion is here: https://codereview.qt-project.org/#/c/145298/
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
- duplicates
-
QTBUG-45975 MacOS: QOpenGLWindow contained in QMainWindow flickers when being resized programmatically
- Closed
- is duplicated by
-
QTBUG-52711 Window flickers when resized on OS X
- Closed
- is required for
-
QTBUG-49859 OS X: Unified Expose and Update events via CVDisplayLink/drawRect
- Closed
- resulted in
-
QTBUG-61964 QCocoaEventDispatcher::processEvents() return true if there is a modal session running (even if no events were processed), causing QCoreApplication::processEvents() to loop until timeout.
- Reported
-
QTBUG-62042 tst_MacNativeEvents::testKeyPressOnToplevel fails when synchronous expose events are enabled
- Reported
-
QTBUG-61965 QCocoaWindow::requestActivateWindow() ignores window modality
- Open
-
QTBUG-61953 Allow QWindows to have 0x0 size, like widgets
- Open
-
QTBUG-61967 Order of QWindow expose and activation not specified
- Open
-
QTBUG-65502 [macOS] [Reg: 5.9.3 -> 5.10.0] The window is not always correctly updated when it should be
- Closed
-
QTBUG-61977 QPA sends events durning platform window construction
- Closed
For Gerrit Dashboard: QTBUG-50414 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
146564,4 | qcocoacursor - change cursor position synchronously | dev | qt/qtbase | Status: ABANDONED | -1 | 0 |
146850,5 | Document expose event behavior | dev | qt/qtbase | Status: MERGED | +2 | 0 |
146851,4 | Wait for window expose on the viewport widget | dev | qt/qtbase | Status: MERGED | +2 | 0 |
199818,20 | macOS: Send expose event at drawRect and trigger updates via setNeedsDisplay | dev | qt/qtbase | Status: MERGED | +2 | 0 |