diff --git a/src/gui/kernel/qplatformwindow_p.h b/src/gui/kernel/qplatformwindow_p.h index e240da5838c..5ee14c90e8a 100644 --- a/src/gui/kernel/qplatformwindow_p.h +++ b/src/gui/kernel/qplatformwindow_p.h @@ -30,6 +30,10 @@ struct wl_surface; #if defined(Q_OS_MACOS) Q_FORWARD_DECLARE_OBJC_CLASS(CALayer); +typedef long NSInteger; +enum NSVisualEffectMaterial : NSInteger; +enum NSVisualEffectBlendingMode : NSInteger; +enum NSVisualEffectState: NSInteger; #endif QT_BEGIN_NAMESPACE @@ -63,6 +67,9 @@ struct Q_GUI_EXPORT QCocoaWindow virtual void setContentBorderEnabled(bool enable) = 0; virtual QPoint bottomLeftClippedByNSWindowOffset() const = 0; virtual CALayer *contentLayer() const = 0; + virtual void manageVisualEffectArea(quintptr identifier, const QRect &rect, + NSVisualEffectMaterial material, NSVisualEffectBlendingMode blendMode, + NSVisualEffectState activationState) = 0; }; #endif diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index a3ce192e6e3..c7a5d55344a 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -19,11 +19,12 @@ #include #endif -#include +#include Q_FORWARD_DECLARE_OBJC_CLASS(NSWindow); Q_FORWARD_DECLARE_OBJC_CLASS(NSView); Q_FORWARD_DECLARE_OBJC_CLASS(NSCursor); +Q_FORWARD_DECLARE_OBJC_CLASS(NSVisualEffectView); #if !defined(__OBJC__) using NSInteger = long; @@ -227,6 +228,11 @@ public: // for QNSView CALayer *contentLayer() const override; + void manageVisualEffectArea(quintptr identifier, const QRect &rect, + NSVisualEffectMaterial material, NSVisualEffectBlendingMode blendMode, + NSVisualEffectState activationState) override; + QFlatMap m_effectViews; + NSView *m_view = nil; QCocoaNSWindow *m_nsWindow = nil; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 9a8e5246b80..d0abb8e38c4 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -2224,6 +2224,47 @@ CALayer *QCocoaWindow::contentLayer() const return layer; } +void QCocoaWindow::manageVisualEffectArea(quintptr identifier, const QRect &rect, + NSVisualEffectMaterial material, NSVisualEffectBlendingMode blendMode, + NSVisualEffectState activationState) +{ + if (!qt_objc_cast(m_view.layer)) { + qCWarning(lcQpaWindow) << "Can not manage visual effect areas" + << "in views without a container layer"; + return; + } + + qCDebug(lcQpaWindow) << "Updating visual effect area" << identifier + << "to" << rect << "with material" << material << "blend mode" + << blendMode << "and activation state" << activationState; + + NSVisualEffectView *effectView = nullptr; + if (m_effectViews.contains(identifier)) { + effectView = m_effectViews.value(identifier); + if (rect.isEmpty()) { + [effectView removeFromSuperview]; + m_effectViews.remove(identifier); + return; + } + } else if (!rect.isEmpty()) { + effectView = [NSVisualEffectView new]; + // Ensure that the visual effect layer is stacked well + // below our content layer (which defaults to a z of 0). + effectView.wantsLayer = YES; + effectView.layer.zPosition = -FLT_MAX; + [m_view addSubview:effectView]; + m_effectViews.insert(identifier, effectView); + } + + if (!effectView) + return; + + effectView.frame = rect.toCGRect(); + effectView.material = material; + effectView.blendingMode = blendMode; + effectView.state = activationState; +} + #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug debug, const QCocoaWindow *window) {