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,31 +340,39 @@ 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(); - 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(); - }); + 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]() { + backingPropertiesChanged(); + }); +} + +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) { qCDebug(lcQpaBackingStore) << "Resize requested to" << size; @@ -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)