diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2020-08-06 16:57:44 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2020-08-07 12:01:22 +0200 |
commit | b4f6fdf57574cfb0c8ab7e7b80f8e4b01f13c0dd (patch) | |
tree | 489ce6a297d7a51f5c6c2fb3a3560be7cf8266ae /src/plugins/platforms/cocoa | |
parent | abb985a4032a337581aa885e1ac547287244b695 (diff) |
macOS: Handle platform window destroy and create in backingstore
We observe changes to the NSWindow to pick up color space changes,
so we need to track when the platform window is destroyed and created
to match our observer with the recreated NSWindow.
This does not handle the fact that we're internally recreating the
NSWindow if certain window flag changes requires so, without letting
clients know via surface events.
Task-number: QTBUG-85915
Pick-to: 5.15
Change-Id: I7a7d728c742def79adebaadc985cedd86ea0d581
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.mm | 49 |
2 files changed, 36 insertions, 16 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index c29ab2d8f8..4a5b3886f2 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -96,6 +96,9 @@ public: QPlatformGraphicsBuffer *graphicsBuffer() const override; private: + void observeBackingPropertiesChanges(); + bool eventFilter(QObject *watched, QEvent *event) override; + QSize m_requestedSize; QRegion m_paintedRegion; diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index aedce10c1f..9ee6ab5b4f 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -340,29 +340,37 @@ QCALayerBackingStore::QCALayerBackingStore(QWindow *window) qCDebug(lcQpaBackingStore) << "Creating QCALayerBackingStore for" << window; m_buffers.resize(1); - // Ideally this would be plumbed from the platform layer to QtGui, and - // the QBackingStore would be recreated, but we don't have that code yet, - // so at least make sure we update our backingstore when the backing - // properties (color space e.g.) are changed. - NSView *view = static_cast<QCocoaWindow *>(window->handle())->view(); + observeBackingPropertiesChanges(); + window->installEventFilter(this); +} + +QCALayerBackingStore::~QCALayerBackingStore() +{ +} + +void QCALayerBackingStore::observeBackingPropertiesChanges() +{ + Q_ASSERT(window()->handle()); + NSView *view = static_cast<QCocoaWindow *>(window()->handle())->view(); m_backingPropertiesObserver = QMacNotificationObserver(view.window, NSWindowDidChangeBackingPropertiesNotification, [this]() { - if (!this->window()->handle()) { - // The platform window has been destroyed, but the backingstore - // is still alive, as that's tied to a QWindow. The original - // NSWindow we were observing is also likely gone. FIXME: - // We should listen for surface events from the QWindow and - // remove and re-attach our observer based on those. - return; - } - qCDebug(lcQpaBackingStore) << "Backing properties for" - << this->window() << "did change"; backingPropertiesChanged(); }); } -QCALayerBackingStore::~QCALayerBackingStore() +bool QCALayerBackingStore::eventFilter(QObject *watched, QEvent *event) { + Q_ASSERT(watched == window()); + + if (event->type() == QEvent::PlatformSurface) { + auto *surfaceEvent = static_cast<QPlatformSurfaceEvent*>(event); + if (surfaceEvent->surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated) + observeBackingPropertiesChanges(); + else + m_backingPropertiesObserver = QMacNotificationObserver(); + } + + return false; } void QCALayerBackingStore::resize(const QSize &size, const QRegion &staticContents) @@ -662,6 +670,15 @@ QImage QCALayerBackingStore::toImage() const void QCALayerBackingStore::backingPropertiesChanged() { + // Ideally this would be plumbed from the platform layer to QtGui, and + // the QBackingStore would be recreated, but we don't have that code yet, + // so at least make sure we update our backingstore when the backing + // properties (color space e.g.) are changed. + + Q_ASSERT(window()->handle()); + + qCDebug(lcQpaBackingStore) << "Backing properties for" << window() << "did change"; + qCDebug(lcQpaBackingStore) << "Updating color space of existing buffers"; for (auto &buffer : m_buffers) { if (buffer) |