Our events today are a bit of a mess and have overloaded meanings:
- QWindow expose events are used both for the original meaning of expose/obscure, and for "you should paint now"
- We have no paint event on a QPA/QtGui level
- We have no hide/unhide event on a QPA level
- QWindow synthesizes show/hide on setVisible, but there's no support for sponaneous show/hide coming from the window system
- QWidget also synthesizes show/hide on setVisible, and documents that spontaneous events will come in after a widget is shown/hidden
- These sponaneous events are sent from QWidgetWindow on expose
- The same expose event sets WA_Mapped
- And asks the widget to paint by syncing the backingstore
- When a view is unhidden on macOS we ask the OS that we need to paint, which will trigger an expose event down the line. But widgets likes to paint on its own, and doing so will trigger the OS to decide that we no longer need the paint event we asked for. As a result, we never send any expose event, and never send show/hide to widgets or set WA_Mapped.
- When a NSView is unhidden, and layer-backed, we don't really need to paint, but since we have to send expose events though QPA to signal the unhide we end up painting
- QWidgets and QWindow should be able to ask for a paint via update(), that gets delivered as a paint event. Right now that means having to bake the paint request into an expose event.
- The OS might send a request to paint before the window is shown/exposed, as a preparation for doing so. Right now Qt assumes a certain order here, which means we can't e.g. use NSWindow.occlusionState to inform the exposed state, as doing so would lead Qt to thinking it can't paint, when the OS actually wanted us to.
These are just some of the problems in this area.
The rough plan for Qt would be to separate all of these events into QPA events for:
- Painting (the os requested us to paint, regardless of what the other states are)
- Expose (the window has been uncovered by another window e.g.)
- Show/hide (the window changed its own show/hide state)
We can mask/translate this behavior change between QtGui and QtWidgets so that they still receive the events they always did (hopefully). Luckily there's no QWidget::exposeEvent().