[vlc-commits] [Git][videolan/vlc][master] qt: consider csd shadows when requesting blur behind effect

Steve Lhomme (@robUx4) gitlab at videolan.org
Fri Jan 17 15:33:17 UTC 2025



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
366474b5 by Fatih Uzunoglu at 2025-01-17T15:10:07+00:00
qt: consider csd shadows when requesting blur behind effect

KWindowSystem's documentation states the following:

> Note that you will usually want to set the region to the
> shape of the window, excluding any shadow or halo.

I interpret this as, the requested blur region should not
encapsulate the area where the window shadows are drawn by
the client (application) because client shadows are part of
the window.

Historically this has not been a problem because the client
shadows are placed in the frame extents, and KWin did not
apply blur effect in the frame extents/margins. This does
not seem to be a documented behavior, and with KWin 6.2.0
it appears that the blur is applied in frame extents on X11.

- - - - -


5 changed files:

- modules/gui/qt/maininterface/compositor.cpp
- modules/gui/qt/maininterface/compositor.hpp
- modules/gui/qt/maininterface/kwindowsystem_module.cpp
- modules/gui/qt/maininterface/win32windoweffects_module.cpp
- modules/gui/qt/maininterface/windoweffects_module.hpp


Changes:

=====================================
modules/gui/qt/maininterface/compositor.cpp
=====================================
@@ -271,6 +271,7 @@ bool CompositorVideo::commonGUICreateImpl(QWindow* window, CompositorVideo::Flag
     {
         m_mainCtx->setCanShowVideoPIP(true);
     }
+    m_mainCtx->setWindowSuportExtendedFrame(flags & CompositorVideo::HAS_EXTENDED_FRAME);
     if (!backendIsOpenVg && (flags & CompositorVideo::HAS_ACRYLIC))
     {
         if (Q_LIKELY(!window->isActive()))
@@ -292,7 +293,6 @@ bool CompositorVideo::commonGUICreateImpl(QWindow* window, CompositorVideo::Flag
 #else
     m_interfaceWindowHandler = std::make_unique<InterfaceWindowHandler>(m_intf, m_mainCtx, window);
 #endif
-    m_mainCtx->setWindowSuportExtendedFrame(flags & CompositorVideo::HAS_EXTENDED_FRAME);
 
 #ifdef _WIN32
     m_taskbarWidget = std::make_unique<WinTaskbarWidget>(m_intf, window);
@@ -302,6 +302,40 @@ bool CompositorVideo::commonGUICreateImpl(QWindow* window, CompositorVideo::Flag
     return true;
 }
 
+void CompositorVideo::adjustBlurBehind()
+{
+    if (m_mainCtx && m_windowEffectsModule)
+    {
+        if (QWindow *const window = interfaceMainWindow())
+        {
+            assert(m_windowEffectsModule->isEffectAvailable(window, WindowEffectsModule::BlurBehind));
+            const bool blurBehind = m_mainCtx->hasAcrylicSurface();
+            if (blurBehind && m_mainCtx->windowSuportExtendedFrame() && m_mainCtx->useClientSideDecoration())
+            {
+                QRegion blurRegion;
+                const QRegion maskRegion = window->mask();
+                if (maskRegion.isEmpty())
+                {
+                    // If there is window mask, we assume that the content area is smaller than the
+                    // window geometry. We also assume that in that case window has custom margins
+                    // set (Wayland case). KWin 6.2 Wayland already considers window custom margins
+                    // when applying the blur effect, but KWin X11 does not consider `_GTK_FRAME_EXTENTS`.
+                    // Since the mask region represents the actual content area, and the outside region
+                    // is included in the frame margins, we can set the blur region only if the mask is
+                    // empty. This fixes blur backdrop applied to client shadows on X11:
+                    const auto margin = m_mainCtx->windowExtendedMargin();
+                    blurRegion = QRegion(margin, margin, window->width() - 2 * margin, window->height() - 2 * margin);
+                }
+                m_windowEffectsModule->setBlurBehind(window, true, blurRegion);
+            }
+            else
+            {
+                m_windowEffectsModule->setBlurBehind(window, blurBehind, {});
+            }
+        }
+    }
+}
+
 bool CompositorVideo::commonGUICreate(QWindow* window, QmlUISurface* qmlSurface, CompositorVideo::Flags flags)
 {
     bool ret = commonGUICreateImpl(window, flags);
@@ -385,7 +419,33 @@ bool CompositorVideo::setBlurBehind(QWindow *window, const bool enable)
     if (!m_windowEffectsModule->isEffectAvailable(window, WindowEffectsModule::BlurBehind))
         return false;
 
-    m_windowEffectsModule->setBlurBehind(window, enable);
     m_mainCtx->setHasAcrylicSurface(enable);
+
+    if (m_mainCtx->windowSuportExtendedFrame())
+    {
+        assert(m_mainCtx);
+
+        if (enable)
+        {
+            connect(window, &QWindow::widthChanged, this, &CompositorVideo::adjustBlurBehind, Qt::UniqueConnection);
+            connect(window, &QWindow::heightChanged, this, &CompositorVideo::adjustBlurBehind, Qt::UniqueConnection);
+            connect(m_mainCtx, &MainCtx::windowExtendedMarginChanged, this, &CompositorVideo::adjustBlurBehind, Qt::UniqueConnection);
+            connect(m_mainCtx, &MainCtx::useClientSideDecorationChanged, this, &CompositorVideo::adjustBlurBehind, Qt::UniqueConnection);
+        }
+        else
+        {
+            disconnect(window, &QWindow::widthChanged, this, &CompositorVideo::adjustBlurBehind);
+            disconnect(window, &QWindow::heightChanged, this, &CompositorVideo::adjustBlurBehind);
+            disconnect(m_mainCtx, &MainCtx::windowExtendedMarginChanged, this, &CompositorVideo::adjustBlurBehind);
+            disconnect(m_mainCtx, &MainCtx::useClientSideDecorationChanged, this, &CompositorVideo::adjustBlurBehind);
+        }
+
+        adjustBlurBehind();
+    }
+    else
+    {
+        m_windowEffectsModule->setBlurBehind(window, enable, {});
+    }
+
     return true;
 }


=====================================
modules/gui/qt/maininterface/compositor.hpp
=====================================
@@ -167,6 +167,9 @@ protected:
 private:
     bool commonGUICreateImpl(QWindow* window, CompositorVideo::Flags flags);
 
+private slots:
+    void adjustBlurBehind();
+
 protected slots:
     virtual void onSurfacePositionChanged(const QPointF&) {}
     virtual void onSurfaceSizeChanged(const QSizeF&) {}


=====================================
modules/gui/qt/maininterface/kwindowsystem_module.cpp
=====================================
@@ -39,9 +39,9 @@ static bool isEffectAvailable(const QWindow*, const WindowEffectsModule::Effect
     return KWindowEffects::isEffectAvailable(kWindowEffect);
 }
 
-static void setBlurBehind(QWindow* const window, const bool enable = true)
+static void setBlurBehind(QWindow* const window, const bool enable = true, const QRegion& region = {})
 {
-    KWindowEffects::enableBlurBehind(window, enable, QRegion());
+    KWindowEffects::enableBlurBehind(window, enable, region);
 }
 
 static int Open(vlc_object_t* const p_this)


=====================================
modules/gui/qt/maininterface/win32windoweffects_module.cpp
=====================================
@@ -20,6 +20,7 @@
 
 #include <QOperatingSystemVersion>
 #include <QWindow>
+#include <QRegion>
 
 #include <cassert>
 
@@ -65,8 +66,10 @@ static bool isEffectAvailable(const QWindow* window, const WindowEffectsModule::
     };
 }
 
-static void setBlurBehind(QWindow* const window, const bool enable = true)
+static void setBlurBehind(QWindow* const window, const bool enable = true, const QRegion& region = {})
 {
+    Q_UNUSED(region);
+
     assert(window);
     assert(window->winId()); // use QWindow::create() before calling this function
 


=====================================
modules/gui/qt/maininterface/windoweffects_module.hpp
=====================================
@@ -20,6 +20,8 @@
 
 #include <vlc_common.h>
 
+#include <QRegion>
+
 class QWindow;
 
 struct WindowEffectsModule
@@ -34,7 +36,12 @@ struct WindowEffectsModule
     void *p_sys = nullptr;
 
     bool (*isEffectAvailable)(const QWindow* window, Effect effect);
-    void (*setBlurBehind)(QWindow* window, bool enable);
+
+    // NOTE: Region is not guaranteed to be respected.
+    // WARNING: Care must be taken for Qt library ABI compatibility.
+    //          For example, KWindowSystem may be built with Qt that are not
+    //          binary compatible with the version the application uses.
+    void (*setBlurBehind)(QWindow* window, bool enable, const QRegion& region);
 };
 
 #endif // WINDOWEFFECTSMODULE_HPP



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/366474b5675b8864df1b3bf4e9b064ce6a2b2686

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/366474b5675b8864df1b3bf4e9b064ce6a2b2686
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list