[vlc-commits] [Git][videolan/vlc][master] 9 commits: qt/MainInterface: implement acrylic surface notifiers

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sun Sep 12 15:28:35 UTC 2021



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
87cb513e by Prince Gupta at 2021-09-12T12:46:25+00:00
qt/MainInterface: implement acrylic surface notifiers

- - - - -
034edad6 by Steve Lhomme at 2021-09-12T12:46:25+00:00
contrib: pthreads: patch dcomp.h from mingw64 to add gaussian effect

- - - - -
b74b0758 by Prince Gupta at 2021-09-12T12:46:25+00:00
qt/compositor_dcomp: force Win 8.1 compilation

To allow use of IDCompositionGaussianBlurEffect and others

- - - - -
606d8cfa by Prince Gupta at 2021-09-12T12:46:25+00:00
qt/compositor_dcomp: allow adding visual from outside

- - - - -
c6afb90a by Prince Gupta at 2021-09-12T12:46:25+00:00
qt/compositor_dcomp: implement acrylicsurface

- - - - -
dcd3d543 by Prince Gupta at 2021-09-12T12:46:25+00:00
qml: implement AcrylicBackground

- - - - -
ca242d7b by Prince Gupta at 2021-09-12T12:46:25+00:00
qml/BannerSource: use AcrylicBackground

- - - - -
2d6c4156 by Prince Gupta at 2021-09-12T12:46:25+00:00
qml/MusicArtistsAlbums: use AcrylicBackground for list

- - - - -
b605fd25 by Prince Gupta at 2021-09-12T12:46:25+00:00
qml/PlaylistListView: use AcrylicBackground

- - - - -


16 changed files:

- + contrib/src/pthreads/0001-dcomp.h-add-some-missing-interfaces.patch
- contrib/src/pthreads/rules.mak
- modules/gui/qt/Makefile.am
- modules/gui/qt/maininterface/compositor_dcomp.cpp
- modules/gui/qt/maininterface/compositor_dcomp.hpp
- + modules/gui/qt/maininterface/compositor_dcomp_acrylicsurface.cpp
- + modules/gui/qt/maininterface/compositor_dcomp_acrylicsurface.hpp
- modules/gui/qt/maininterface/compositor_dcomp_uisurface.hpp
- modules/gui/qt/maininterface/main_interface.cpp
- modules/gui/qt/maininterface/main_interface.hpp
- modules/gui/qt/maininterface/qml/BannerSources.qml
- modules/gui/qt/medialibrary/qml/MusicArtistsAlbums.qml
- modules/gui/qt/player/qml/Player.qml
- modules/gui/qt/playlist/qml/PlaylistListView.qml
- modules/gui/qt/vlc.qrc
- + modules/gui/qt/widgets/qml/AcrylicBackground.qml


Changes:

=====================================
contrib/src/pthreads/0001-dcomp.h-add-some-missing-interfaces.patch
=====================================
@@ -0,0 +1,111 @@
+From 9de58105bbe6fb870c746d3f5c4ed97d91ba1b7c Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Tue, 7 Sep 2021 14:36:16 +0200
+Subject: [PATCH] dcomp.h: add some missing interfaces
+
+* IDCompositionFilterEffect: https://docs.microsoft.com/en-us/windows/win32/api/dcomp/nn-dcomp-idcompositionfiltereffect
+* IDCompositionSaturationEffect: https://docs.microsoft.com/en-us/windows/win32/api/dcomp/nn-dcomp-idcompositionsaturationeffect
+* IDCompositionGaussianBlurEffect: https://docs.microsoft.com/en-us/windows/win32/api/dcomp/nn-dcomp-idcompositiongaussianblureffect
+* IDCompositionDevice3: https://docs.microsoft.com/en-us/windows/win32/api/dcomp/nn-dcomp-idcompositiondevice3
+
+The order of methods can be found from
+https://github.com/terrafx/terrafx.interop.windows/tree/main/sources/Interop/Windows/um/dcomp
+
+As for other IDCompositionEffect interfaces, some methods are inverted for MSVC
+compilation in C++ (which is odd).
+
+Co-authored-by: Prince Gupta <guptaprince8832 at gmail.com>
+---
+ mingw-w64-headers/include/dcomp.h | 74 +++++++++++++++++++++++++++++++
+ 1 file changed, 74 insertions(+)
+
+diff --git a/mingw-w64-headers/include/dcomp.h b/mingw-w64-headers/include/dcomp.h
+index 58f4b8466..7f124ca99 100644
+--- a/mingw-w64-headers/include/dcomp.h
++++ b/mingw-w64-headers/include/dcomp.h
+@@ -524,8 +524,82 @@ __CRT_UUID_DECL(IDCompositionVisualDebug,0xfed2b808,0x5eb4,0x43a0,0xae,0xa3,0x35
+ #endif
+
+
++#undef INTERFACE
++#define INTERFACE IDCompositionFilterEffect
++DECLARE_INTERFACE_IID_(IDCompositionFilterEffect, IDCompositionEffect, "30C421D5-8CB2-4E9F-B133-37BE270D4AC2")
++{
++    STDMETHOD(SetInput)(THIS_ UINT index, IUnknown *input, UINT flags) PURE;
++};
++
++#ifdef __CRT_UUID_DECL
++__CRT_UUID_DECL(IDCompositionFilterEffect,0x30c421d5,0x8cb2,0x4e9f,0xb1,0x33,0x37,0xbe,0x27,0x0d,0x4a,0xc2);
+ #endif
+
++
++#undef INTERFACE
++#define INTERFACE IDCompositionSaturationEffect
++DECLARE_INTERFACE_IID_(IDCompositionSaturationEffect, IDCompositionFilterEffect, "A08DEBDA-3258-4FA4-9F16-9174D3FE93B1")
++{
++#if defined(_MSC_VER) && defined(__cplusplus)
++    STDMETHOD(SetSaturation)(THIS_ float ratio) PURE;
++    STDMETHOD(SetSaturation)(THIS_ IDCompositionAnimation* animation) PURE;
++#else
++    STDMETHOD(SetSaturation)(THIS_ IDCompositionAnimation* animation) PURE;
++    STDMETHOD(SetSaturation)(THIS_ float ratio ) PURE;
++#endif
++};
++
++#ifdef __CRT_UUID_DECL
++__CRT_UUID_DECL(IDCompositionSaturationEffect,0xa08debda,0x3258,0x4fa4,0x9f,0x16,0x91,0x74,0xd3,0xfe,0x93,0xb1);
++#endif
++
++
++#undef INTERFACE
++#define INTERFACE IDCompositionGaussianBlurEffect
++DECLARE_INTERFACE_IID_(IDCompositionGaussianBlurEffect, IDCompositionFilterEffect, "45D4D0B7-1BD4-454E-8894-2BFA68443033")
++{
++
++#if defined(_MSC_VER) && defined(__cplusplus)
++    STDMETHOD(SetStandardDeviation)(THIS_ float amount) PURE;
++    STDMETHOD(SetStandardDeviation)(THIS_ IDCompositionAnimation* animation) PURE;
++#else
++    STDMETHOD(SetStandardDeviation)(THIS_ IDCompositionAnimation* animation) PURE;
++    STDMETHOD(SetStandardDeviation)(THIS_ float amount) PURE;
++#endif
++    STDMETHOD(SetBorderMode)(THIS_ D2D1_BORDER_MODE mode) PURE;
++};
++
++#ifdef __CRT_UUID_DECL
++__CRT_UUID_DECL(IDCompositionGaussianBlurEffect,0x45d4d0b7,0x1bd4,0x454e,0x88,0x94,0x2b,0xfa,0x68,0x44,0x30,0x33);
++#endif
++
++
++// WARNING: some of the arguments are replaced with void*, only what's used has been kept
++#undef INTERFACE
++#define INTERFACE IDCompositionDevice3
++DECLARE_INTERFACE_IID_(IDCompositionDevice3, IDCompositionDevice2, "0987CB06-F916-48BF-8D35-CE7641781BD9")
++{
++    STDMETHOD(CreateGaussianBlurEffect)(THIS_ IDCompositionGaussianBlurEffect **gaussianBlurEffect) PURE;
++    STDMETHOD(CreateBrightnessEffect)(THIS_ void **brightnessEffect) PURE;
++    STDMETHOD(CreateColorMatrixEffect)(THIS_ void **colorMatrixEffect) PURE;
++    STDMETHOD(CreateShadowEffect)(THIS_ void **shadowEffect) PURE;
++    STDMETHOD(CreateHueRotationEffect)(THIS_ void **hueRotationEffect) PURE;
++    STDMETHOD(CreateSaturationEffect)(THIS_ IDCompositionSaturationEffect **saturationEffect) PURE;
++    STDMETHOD(CreateTurbulenceEffect)(THIS_ void **turbulenceEffect) PURE;
++    STDMETHOD(CreateLinearTransferEffect)(THIS_ void **linearTransferEffect) PURE;
++    STDMETHOD(CreateTableTransferEffect)(THIS_ void **tableTransferEffect) PURE;
++    STDMETHOD(CreateCompositeEffect)(THIS_ void **compositeEffect) PURE;
++    STDMETHOD(CreateBlendEffect)(THIS_ void **blendEffect) PURE;
++    STDMETHOD(CreateArithmeticCompositeEffect)(THIS_ void **arithmeticCompositeEffect) PURE;
++    STDMETHOD(CreateAffineTransform2DEffect)(THIS_ void **affineTransform2dEffect) PURE;
++};
++
++#ifdef __CRT_UUID_DECL
++__CRT_UUID_DECL(IDCompositionDevice3,0x0987cb06,0xf916,0x48bf,0x8d,0x35,0xce,0x76,0x41,0x78,0x1b,0xd9);
++#endif
++
++#endif // WINAPI_PARTITION_DESKTOP
++
+ #if (_WIN32_WINNT >= 0x0A00)
+
+ STDAPI DCompositionCreateDevice3(IUnknown *renderingDevice, REFIID iid, void **dcompositionDevice);
+--
+2.27.0.windows.1
+


=====================================
contrib/src/pthreads/rules.mak
=====================================
@@ -13,8 +13,8 @@ ifdef HAVE_WINSTORE
 PKGS += winrt_headers
 PKGS_ALL += winrt_headers
 endif
-PKGS += dxvahd
-PKGS_ALL += dxvahd
+PKGS += dxvahd dcomp
+PKGS_ALL += dxvahd dcomp
 ifeq ($(HAVE_MINGW64_V8),true)
 PKGS_FOUND += winrt_headers dxvahd
 endif
@@ -33,6 +33,7 @@ $(TARBALLS)/mingw-w64-v$(WINPTHREADS_VERSION).tar.bz2:
 pthreads: mingw-w64-v$(WINPTHREADS_VERSION).tar.bz2 .sum-pthreads
 #pthreads: mingw-w64-$(WINPTHREADS_HASH).tar.xz .sum-pthreads
 	$(UNPACK)
+	$(APPLY) $(SRC)/pthreads/0001-dcomp.h-add-some-missing-interfaces.patch
 	$(MOVE)
 
 .pthreads: pthreads
@@ -55,3 +56,11 @@ pthreads: mingw-w64-v$(WINPTHREADS_VERSION).tar.bz2 .sum-pthreads
 	mkdir -p -- "$(PREFIX)/include"
 	cd $< && cp mingw-w64-headers/include/dxvahd.h "$(PREFIX)/include"
 	touch $@
+
+.sum-dcomp: .sum-pthreads
+	touch $@
+
+.dcomp: pthreads
+	mkdir -p -- "$(PREFIX)/include"
+	cd $< && cp mingw-w64-headers/include/dcomp.h "$(PREFIX)/include"
+	touch $@


=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -278,6 +278,8 @@ libqt_plugin_la_SOURCES += \
 	gui/qt/maininterface/compositor_dcomp.cpp \
 	gui/qt/maininterface/compositor_dcomp.hpp \
 	gui/qt/maininterface/compositor_dcomp_error.hpp \
+	gui/qt/maininterface/compositor_dcomp_acrylicsurface.hpp \
+	gui/qt/maininterface/compositor_dcomp_acrylicsurface.cpp \
 	gui/qt/maininterface/compositor_dcomp_uisurface.cpp \
 	gui/qt/maininterface/compositor_dcomp_uisurface.hpp
 endif
@@ -413,6 +415,7 @@ nodist_libqt_plugin_la_SOURCES += gui/qt/maininterface/main_interface_win32.moc.
 
 if HAVE_DCOMP
 nodist_libqt_plugin_la_SOURCES += \
+	gui/qt/maininterface/compositor_dcomp_acrylicsurface.moc.cpp \
 	gui/qt/maininterface/compositor_dcomp.moc.cpp \
 	gui/qt/maininterface/compositor_dcomp_uisurface.moc.cpp
 endif
@@ -770,6 +773,7 @@ libqt_plugin_la_QML = \
 	gui/qt/widgets/qml/CheckedDelegate.qml \
 	gui/qt/widgets/qml/ComboBoxExt.qml \
 	gui/qt/widgets/qml/ContextButton.qml \
+	gui/qt/widgets/qml/AcrylicBackground.qml \
 	gui/qt/widgets/qml/AnimatedBackground.qml \
 	gui/qt/widgets/qml/CoverShadow.qml \
 	gui/qt/widgets/qml/CSDWindowButton.qml \


=====================================
modules/gui/qt/maininterface/compositor_dcomp.cpp
=====================================
@@ -30,6 +30,7 @@
 #include <QDesktopWidget>
 #include <QQuickWidget>
 #include <QLibrary>
+#include <QScreen>
 
 #include <QOpenGLFunctions>
 #include <QOpenGLFramebufferObject>
@@ -338,6 +339,16 @@ MainInterface* CompositorDirectComposition::makeMainInterface()
         m_uiSurface->setContent(m_ui->getComponent(), m_ui->createRootItem());
         HR(m_rootVisual->AddVisual(m_uiVisual.Get(), FALSE, nullptr), "add ui visual to root");
         HR(m_dcompDevice->Commit(), "commit UI visual");
+
+        auto resetAcrylicSurface = [this](QScreen * = nullptr)
+        {
+            m_acrylicSurface.reset(new CompositorDCompositionAcrylicSurface(m_intf, m_d3d11Device.Get()));
+        };
+
+        resetAcrylicSurface();
+        connect(qGuiApp, &QGuiApplication::screenAdded, this, resetAcrylicSurface);
+        connect(qGuiApp, &QGuiApplication::screenRemoved, this, resetAcrylicSurface);
+
         return m_mainInterface;
     }
     catch (const DXError& err)
@@ -380,6 +391,7 @@ void CompositorDirectComposition::unloadGUI()
         m_rootVisual->RemoveVisual(m_uiVisual.Get());
         m_uiVisual.Reset();
     }
+    m_acrylicSurface.reset();
     m_uiSurface.reset();
     m_ui.reset();
     m_taskbarWidget.reset();
@@ -436,4 +448,24 @@ Compositor::Type CompositorDirectComposition::type() const
     return Compositor::DirectCompositionCompositor;
 }
 
+void CompositorDirectComposition::addVisual(Microsoft::WRL::ComPtr<IDCompositionVisual> visual)
+{
+    vlc_assert(m_rootVisual);
+
+    HRESULT hr = m_rootVisual->AddVisual(visual.Get(), FALSE, m_videoVisual ? m_videoVisual.Get() : m_uiVisual.Get());
+    if (FAILED(hr))
+        msg_Err(m_intf, "failed to add visual, code: 0x%lX", hr);
+
+    m_dcompDevice->Commit();
+}
+
+void CompositorDirectComposition::removeVisual(Microsoft::WRL::ComPtr<IDCompositionVisual> visual)
+{
+    auto hr = m_rootVisual->RemoveVisual(visual.Get());
+    if (FAILED(hr))
+        msg_Err(m_intf, "failed to remove visual, code: 0x%lX", hr);
+
+    m_dcompDevice->Commit();
+}
+
 }


=====================================
modules/gui/qt/maininterface/compositor_dcomp.hpp
=====================================
@@ -21,12 +21,18 @@
 #include "compositor.hpp"
 
 #include <windows.h>
+
+# if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x603)
+#  undef _WIN32_WINNT
+#  define _WIN32_WINNT 0x0603
+# endif
 #include <dcomp.h>
 #include <d3d11.h>
 #include <wrl.h>
 #include <dwmapi.h>
 
 #include "maininterface/mainui.hpp"
+#include "compositor_dcomp_acrylicsurface.hpp"
 #include "compositor_dcomp_uisurface.hpp"
 #include "videosurface.hpp"
 #include "interface_window_handler.hpp"
@@ -58,6 +64,9 @@ public:
 
     Type type() const override;
 
+    void addVisual(Microsoft::WRL::ComPtr<IDCompositionVisual> visual);
+    void removeVisual(Microsoft::WRL::ComPtr<IDCompositionVisual> visual);
+
 private slots:
     void onSurfacePositionChanged(QPointF position);
 
@@ -77,6 +86,7 @@ private:
     std::unique_ptr<WinTaskbarWidget> m_taskbarWidget;
 
     std::unique_ptr<CompositorDCompositionUISurface> m_uiSurface;
+    std::unique_ptr<CompositorDCompositionAcrylicSurface> m_acrylicSurface;
     vout_window_t *m_window = nullptr;
     std::unique_ptr<MainUI> m_ui;
     std::unique_ptr<VideoWindowHandler> m_videoWindowHandler;


=====================================
modules/gui/qt/maininterface/compositor_dcomp_acrylicsurface.cpp
=====================================
@@ -0,0 +1,445 @@
+/*****************************************************************************
+ * Copyright (C) 2021 the VideoLAN team
+ *
+ * Authors: Prince Gupta <guptaprince8832 at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include "compositor_dcomp_acrylicsurface.hpp"
+
+#include <QWindow>
+#include <QScreen>
+#include <QLibrary>
+#include <versionhelpers.h>
+
+#include "compositor_dcomp.hpp"
+
+namespace
+{
+
+template <typename F>
+F loadFunction(QLibrary &library, const char *symbol)
+{
+    vlc_assert(library.isLoaded());
+
+    auto f = library.resolve(symbol);
+    if (!f)
+    {
+        const auto err = GetLastError();
+        throw std::runtime_error(QString("failed to load %1, code %2").arg(QString(symbol), QString::number(err)).toStdString());
+    }
+
+    return reinterpret_cast<F>(f);
+}
+
+bool isWinPreIron()
+{
+    typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
+
+    auto ntdll = GetModuleHandleW(L"ntdll.dll");
+    auto GetVersionInfo = reinterpret_cast<RtlGetVersionPtr>(GetProcAddress(ntdll, "RtlGetVersion"));
+
+    if (GetVersionInfo)
+    {
+        RTL_OSVERSIONINFOW versionInfo = { };
+        versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+        if (!GetVersionInfo(&versionInfo))
+            return versionInfo.dwMajorVersion <= 10
+                    && versionInfo.dwBuildNumber < 20000;
+    }
+
+    return false;
+}
+
+}
+
+namespace vlc
+{
+
+CompositorDCompositionAcrylicSurface::CompositorDCompositionAcrylicSurface(qt_intf_t *intf_t, ID3D11Device *device, QObject *parent)
+    : QObject(parent)
+    , m_intf {intf_t}
+{
+    if (!init(device))
+    {
+        m_intf = nullptr;
+        return;
+    }
+
+    if (auto w = window())
+        setActive(w->isActive());
+
+    qApp->installNativeEventFilter(this);
+}
+
+CompositorDCompositionAcrylicSurface::~CompositorDCompositionAcrylicSurface()
+{
+    setActive(false);
+
+    if (m_dummyWindow)
+        DestroyWindow(m_dummyWindow);
+}
+
+bool CompositorDCompositionAcrylicSurface::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
+{
+    MSG* msg = static_cast<MSG*>( message );
+
+    if (!m_intf || msg->hwnd != hwnd())
+        return false;
+
+    switch (msg->message)
+    {
+    case WM_WINDOWPOSCHANGED:
+    {
+        sync();
+        commitChanges();
+
+        requestReset(); // incase z-order changed
+        break;
+    }
+    case WM_ACTIVATE:
+    {
+        const int activeType = LOWORD(msg->wParam);
+        if ((activeType == WA_ACTIVE) || (activeType == WA_CLICKACTIVE))
+            setActive(true);
+        else if (activeType == WA_INACTIVE)
+            setActive(false);
+
+        break;
+    }
+    }
+
+    return false;
+}
+
+
+bool CompositorDCompositionAcrylicSurface::init(ID3D11Device *device)
+{
+    if (!loadFunctions())
+        return false;
+
+    if (!createDevice(device))
+        return false;
+
+    if (!createDesktopVisual())
+        return false;
+
+    if (!createBackHostVisual())
+        return false;
+
+    m_leftMostScreenX = 0;
+    m_topMostScreenY = 0;
+    for (const auto screen : qGuiApp->screens())
+    {
+        const auto geometry = screen->geometry();
+        m_leftMostScreenX = std::min<int>(geometry.left(), m_leftMostScreenX);
+        m_topMostScreenY = std::min<int>(geometry.top(), m_topMostScreenY);
+    }
+
+    return true;
+}
+
+bool CompositorDCompositionAcrylicSurface::loadFunctions()
+try
+{
+    QLibrary dwmapi("dwmapi.dll");
+    if (!dwmapi.load())
+        throw std::runtime_error("failed to dwmapi.dll, reason: " + dwmapi.errorString().toStdString());
+
+    lDwmpCreateSharedThumbnailVisual = loadFunction<DwmpCreateSharedThumbnailVisual>(dwmapi, MAKEINTRESOURCEA(147));
+    lDwmpCreateSharedMultiWindowVisual = loadFunction<DwmpCreateSharedMultiWindowVisual>(dwmapi, MAKEINTRESOURCEA(163));
+
+    if (isWinPreIron())
+        lDwmpUpdateSharedVirtualDesktopVisual = loadFunction<DwmpUpdateSharedVirtualDesktopVisual>(dwmapi, MAKEINTRESOURCEA(164)); //PRE-IRON
+    else
+        lDwmpUpdateSharedMultiWindowVisual = loadFunction<DwmpUpdateSharedMultiWindowVisual>(dwmapi, MAKEINTRESOURCEA(164)); //20xxx+
+
+
+    QLibrary user32("user32.dll");
+    if (!user32.load())
+        throw std::runtime_error("failed to user32.dll, reason: " + user32.errorString().toStdString());
+
+    lSetWindowCompositionAttribute = loadFunction<SetWindowCompositionAttribute>(user32, "SetWindowCompositionAttribute");
+    lGetWindowCompositionAttribute = loadFunction<GetWindowCompositionAttribute>(user32, "GetWindowCompositionAttribute");
+
+    return true;
+}
+catch (std::exception &err)
+{
+    msg_Err(m_intf, err.what());
+    return false;
+}
+
+bool CompositorDCompositionAcrylicSurface::createDevice(ID3D11Device *device)
+try
+{
+    QLibrary dcompDll("DCOMP.dll");
+    if (!dcompDll.load())
+        throw DXError("failed to load DCOMP.dll",  static_cast<HRESULT>(GetLastError()));
+
+    DCompositionCreateDeviceFun myDCompositionCreateDevice3 =
+            reinterpret_cast<DCompositionCreateDeviceFun>(dcompDll.resolve("DCompositionCreateDevice3"));
+    if (!myDCompositionCreateDevice3)
+        throw DXError("failed to load DCompositionCreateDevice3 function",  static_cast<HRESULT>(GetLastError()));
+
+    using namespace Microsoft::WRL;
+
+    ComPtr<IDXGIDevice> dxgiDevice;
+    HR(device->QueryInterface(dxgiDevice.GetAddressOf()), "query dxgi device");
+
+    ComPtr<IDCompositionDevice> dcompDevice1;
+    HR(myDCompositionCreateDevice3(
+                dxgiDevice.Get(),
+                __uuidof(IDCompositionDevice),
+                (void**)dcompDevice1.GetAddressOf()), "create composition device");
+
+    HR(dcompDevice1->QueryInterface(m_dcompDevice.GetAddressOf()), "dcompdevice not an IDCompositionDevice3");
+
+    HR(m_dcompDevice->CreateVisual(m_rootVisual.GetAddressOf()), "create root visual");
+
+    HR(m_dcompDevice->CreateRectangleClip(m_rootClip.GetAddressOf()), "create root clip");
+
+    HR(m_dcompDevice->CreateTranslateTransform(m_translateTransform.GetAddressOf()), "create translate transform");
+
+    HR(m_dcompDevice->CreateSaturationEffect(m_saturationEffect.GetAddressOf()), "create saturation effect");
+
+    HR(m_dcompDevice->CreateGaussianBlurEffect(m_gaussianBlur.GetAddressOf()), "create gaussian effect");
+
+    m_saturationEffect->SetSaturation(2);
+
+    m_gaussianBlur->SetBorderMode(D2D1_BORDER_MODE_HARD);
+    m_gaussianBlur->SetStandardDeviation(20);
+    m_gaussianBlur->SetInput(0, m_saturationEffect.Get(), 0);
+    m_rootVisual->SetEffect(m_gaussianBlur.Get());
+
+    return true;
+}
+catch (const DXError &err)
+{
+    msg_Err(m_intf, "failed to initialise compositor acrylic surface: '%s' code: 0x%lX", err.what(), err.code());
+    return false;
+}
+
+
+bool CompositorDCompositionAcrylicSurface::createDesktopVisual()
+try
+{
+    vlc_assert(!m_desktopVisual);
+    auto desktopWindow = GetShellWindow();
+    if (!desktopWindow)
+        throw DXError("failed to get desktop window",  static_cast<HRESULT>(GetLastError()));
+
+    const int desktopWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+    const int desktopHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
+
+    DWM_THUMBNAIL_PROPERTIES thumbnail;
+    thumbnail.dwFlags = DWM_TNP_SOURCECLIENTAREAONLY | DWM_TNP_VISIBLE | DWM_TNP_RECTDESTINATION | DWM_TNP_RECTSOURCE | DWM_TNP_OPACITY | DWM_TNP_ENABLE3D;
+    thumbnail.opacity = 255;
+    thumbnail.fVisible = TRUE;
+    thumbnail.fSourceClientAreaOnly = FALSE;
+    thumbnail.rcDestination = RECT{ 0, 0, desktopWidth, desktopHeight };
+    thumbnail.rcSource = RECT{ 0, 0, desktopWidth, desktopHeight };
+
+    HTHUMBNAIL desktopThumbnail;
+    HR(lDwmpCreateSharedThumbnailVisual(hwnd(), desktopWindow, 2, &thumbnail, m_dcompDevice.Get(), (void**)m_desktopVisual.GetAddressOf(), &desktopThumbnail), "create desktop visual");
+    HR(m_rootVisual->AddVisual(m_desktopVisual.Get(), FALSE, nullptr), "Add desktop visual");
+
+    return true;
+}
+catch (const DXError &err)
+{
+    msg_Err(m_intf, "failed to create desktop visual: '%s' code: 0x%lX", err.what(), err.code());
+    return false;
+}
+
+bool CompositorDCompositionAcrylicSurface::createBackHostVisual()
+try
+{
+    vlc_assert(!m_dummyWindow);
+    // lDwmpCreateSharedMultiWindowVisual requires a window with disabled live (thumbnail) preview
+    // use a hidden dummy window to avoid disabling live preview of main window
+    m_dummyWindow = ::CreateWindowExA(WS_EX_TOOLWINDOW, "STATIC", "dummy", WS_VISIBLE, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
+    if (!m_dummyWindow)
+        throw DXError("failed to create dummy window",  static_cast<HRESULT>(GetLastError()));
+
+    int attr = DWM_CLOAKED_APP;
+    DwmSetWindowAttribute(m_dummyWindow, DWMWA_CLOAK, &attr, sizeof attr);
+
+    BOOL enable = TRUE;
+    WINDOWCOMPOSITIONATTRIBDATA CompositionAttribute{};
+    CompositionAttribute.Attrib = WCA_EXCLUDED_FROM_LIVEPREVIEW;
+    CompositionAttribute.pvData = &enable;
+    CompositionAttribute.cbData = sizeof(BOOL);
+    lSetWindowCompositionAttribute(m_dummyWindow, &CompositionAttribute);
+
+    vlc_assert(!m_backHostVisual);
+    HR(lDwmpCreateSharedMultiWindowVisual(m_dummyWindow, m_dcompDevice.Get(), (void**)m_backHostVisual.GetAddressOf(), &m_backHostThumbnail)
+       , "failed to create shared multi visual");
+
+    updateVisual();
+
+    HR(m_rootVisual->AddVisual(m_backHostVisual.Get(), TRUE, m_desktopVisual.Get()), "Add backhost visual");
+
+    return true;
+}
+catch (const DXError &err)
+{
+    msg_Err(m_intf, "failed to create acrylic back host visual: '%s' code: 0x%lX", err.what(), err.code());
+    return false;
+}
+
+void CompositorDCompositionAcrylicSurface::sync()
+{
+    if (!m_intf || !hwnd())
+        return;
+
+    const int dx = std::abs(m_leftMostScreenX);
+    const int dy = std::abs(m_topMostScreenY);
+
+    // window()->geometry()/frameGeometry() returns incorrect rect with CSD
+    RECT rect;
+    GetWindowRect(hwnd(), &rect);
+    m_rootClip->SetLeft((float)rect.left + dx);
+    m_rootClip->SetRight((float)rect.right + dx);
+    m_rootClip->SetTop((float)rect.top);
+    m_rootClip->SetBottom((float)rect.bottom);
+    m_rootVisual->SetClip(m_rootClip.Get());
+
+    int frameX = 0;
+    int frameY = 0;
+
+    if (!m_intf->p_mi->useClientSideDecoration())
+    {
+        frameX = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
+        frameY = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION)
+                    + GetSystemMetrics(SM_CXPADDEDBORDER);
+    }
+    else if (window()->visibility() & QWindow::Maximized)
+    {
+        // in maximized state CSDWin32EventHandler re-adds border
+        frameX = GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
+        frameY = GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
+    }
+
+    m_translateTransform->SetOffsetX(-1 * (float)rect.left - frameX - dx);
+    m_translateTransform->SetOffsetY(-1 * (float)rect.top - frameY - dy);
+    m_rootVisual->SetTransform(m_translateTransform.Get());
+}
+
+void CompositorDCompositionAcrylicSurface::updateVisual()
+{
+    const auto w = window();
+    if (!w || !w->screen())
+        return;
+
+    const auto screenRect = w->screen()->availableVirtualGeometry();
+    RECT sourceRect {screenRect.left(), screenRect.top(), screenRect.right(), screenRect.bottom()};
+    SIZE destinationSize {screenRect.width(), screenRect.height()};
+
+    HWND hwndExclusionList[2];
+    hwndExclusionList[0] = hwnd();
+    hwndExclusionList[1] = m_dummyWindow;
+
+    HRESULT hr = S_FALSE;
+
+    if (lDwmpUpdateSharedVirtualDesktopVisual)
+        hr = lDwmpUpdateSharedVirtualDesktopVisual(m_backHostThumbnail, NULL, 0, hwndExclusionList, 2, &sourceRect, &destinationSize);
+    else if (lDwmpUpdateSharedMultiWindowVisual)
+        hr = lDwmpUpdateSharedMultiWindowVisual(m_backHostThumbnail, NULL, 0, hwndExclusionList, 2, &sourceRect, &destinationSize, 1);
+    else
+        vlc_assert_unreachable();
+
+    if (FAILED(hr))
+        qDebug("failed to update shared multi window visual");
+}
+
+void CompositorDCompositionAcrylicSurface::commitChanges()
+{
+    m_dcompDevice->Commit();
+    DwmFlush();
+}
+
+void CompositorDCompositionAcrylicSurface::requestReset()
+{
+    if (m_resetPending)
+        return;
+
+    m_resetPending = true;
+    m_resetTimer.start(5, Qt::PreciseTimer, this);
+}
+
+void CompositorDCompositionAcrylicSurface::setActive(const bool newActive)
+{
+    if (newActive == m_active)
+        return;
+
+    m_active = newActive;
+    if (m_active)
+    {
+        auto dcompositor = static_cast<vlc::CompositorDirectComposition *>(m_intf->p_compositor);
+        dcompositor->addVisual(m_rootVisual);
+
+        updateVisual();
+        sync();
+        commitChanges();
+
+        // delay propagating changes to avoid flickering
+        QMetaObject::invokeMethod(this, [this]()
+        {
+            m_intf->p_mi->setHasAcrylicSurface(true);
+        }, Qt::QueuedConnection);
+    }
+    else
+    {
+        m_intf->p_mi->setHasAcrylicSurface(false);
+
+        // delay propagating changes to avoid flickering
+        QMetaObject::invokeMethod(this, [this]()
+        {
+            auto dcompositor = static_cast<vlc::CompositorDirectComposition *>(m_intf->p_compositor);
+            dcompositor->removeVisual(m_rootVisual);
+        }, Qt::QueuedConnection);
+    }
+}
+
+QWindow *CompositorDCompositionAcrylicSurface::window()
+{
+    return m_intf ? m_intf->p_compositor->interfaceMainWindow() : nullptr;
+}
+
+HWND CompositorDCompositionAcrylicSurface::hwnd()
+{
+    auto w = window();
+    return w->handle() ? (HWND)w->winId() : nullptr;
+}
+
+void CompositorDCompositionAcrylicSurface::timerEvent(QTimerEvent *event)
+{
+    if (!event)
+        return;
+
+    if (event->timerId() == m_resetTimer.timerId())
+    {
+        m_resetPending = false;
+        m_resetTimer.stop();
+
+        updateVisual();
+        sync();
+        commitChanges();
+    }
+}
+
+}


=====================================
modules/gui/qt/maininterface/compositor_dcomp_acrylicsurface.hpp
=====================================
@@ -0,0 +1,233 @@
+/*****************************************************************************
+ * Copyright (C) 2021 the VideoLAN team
+ *
+ * Authors: Prince Gupta <guptaprince8832 at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef COMPOSITOR_DCOMP_ACRYLICSURFACE_HPP
+#define COMPOSITOR_DCOMP_ACRYLICSURFACE_HPP
+
+#include <QAbstractNativeEventFilter>
+#include <QBasicTimer>
+
+#include <windows.h>
+
+# if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x603)
+#  undef _WIN32_WINNT
+#  define _WIN32_WINNT 0x0603
+# endif
+
+#include <dcomp.h>
+#include <d3d11.h>
+#include <wrl.h>
+#include <dwmapi.h>
+
+#include "compositor_dcomp_error.hpp"
+#include "main_interface.hpp"
+
+// Windows Private APIs, taken from https://blog.adeltax.com/dwm-thumbnails-but-with-idcompositionvisual/
+
+enum THUMBNAIL_TYPE {
+    TT_DEFAULT = 0x0,
+    TT_SNAPSHOT = 0x1,
+    TT_ICONIC = 0x2,
+    TT_BITMAPPENDING = 0x3,
+    TT_BITMAP = 0x4
+};
+
+typedef HRESULT(WINAPI* DwmpCreateSharedThumbnailVisual)(
+    IN HWND hwndDestination,
+    IN HWND hwndSource,
+    IN DWORD dwThumbnailFlags,
+    IN DWM_THUMBNAIL_PROPERTIES* pThumbnailProperties,
+    IN VOID* pDCompDevice,
+    OUT VOID** ppVisual,
+    OUT PHTHUMBNAIL phThumbnailId);
+
+typedef HRESULT(WINAPI* DwmpQueryWindowThumbnailSourceSize)(
+    IN HWND hwndSource,
+    IN BOOL fSourceClientAreaOnly,
+    OUT SIZE* pSize);
+
+typedef HRESULT(WINAPI* DwmpQueryThumbnailType)(
+    IN HTHUMBNAIL hThumbnailId,
+    OUT THUMBNAIL_TYPE* thumbType);
+
+typedef HRESULT(WINAPI* DwmpCreateSharedMultiWindowVisual)(
+    IN HWND hwndDestination,
+    IN VOID* pDCompDevice,
+    OUT VOID** ppVisual,
+    OUT PHTHUMBNAIL phThumbnailId);
+
+//pre-cobalt/pre-iron
+typedef HRESULT(WINAPI* DwmpUpdateSharedVirtualDesktopVisual)(
+    IN HTHUMBNAIL hThumbnailId,
+    IN HWND* phwndsInclude,
+    IN DWORD chwndsInclude,
+    IN HWND* phwndsExclude,
+    IN DWORD chwndsExclude,
+    OUT RECT* prcSource,
+    OUT SIZE* pDestinationSize);
+
+
+//cobalt/iron (20xxx+)
+//Change: function name + new DWORD parameter.
+//Pass "1" in dwFlags. Feel free to explore other flags.
+typedef HRESULT(WINAPI* DwmpUpdateSharedMultiWindowVisual)(
+    IN HTHUMBNAIL hThumbnailId,
+    IN HWND* phwndsInclude,
+    IN DWORD chwndsInclude,
+    IN HWND* phwndsExclude,
+    IN DWORD chwndsExclude,
+    OUT RECT* prcSource,
+    OUT SIZE* pDestinationSize,
+    IN DWORD dwFlags);
+
+#define DWM_TNP_FREEZE 0x100000
+#define DWM_TNP_ENABLE3D 0x4000000
+#define DWM_TNP_DISABLE3D 0x8000000
+#define DWM_TNP_FORCECVI 0x40000000
+#define DWM_TNP_DISABLEFORCECVI 0x80000000
+
+enum WINDOWCOMPOSITIONATTRIB {
+    WCA_UNDEFINED = 0x0,
+    WCA_NCRENDERING_ENABLED = 0x1,
+    WCA_NCRENDERING_POLICY = 0x2,
+    WCA_TRANSITIONS_FORCEDISABLED = 0x3,
+    WCA_ALLOW_NCPAINT = 0x4,
+    WCA_CAPTION_BUTTON_BOUNDS = 0x5,
+    WCA_NONCLIENT_RTL_LAYOUT = 0x6,
+    WCA_FORCE_ICONIC_REPRESENTATION = 0x7,
+    WCA_EXTENDED_FRAME_BOUNDS = 0x8,
+    WCA_HAS_ICONIC_BITMAP = 0x9,
+    WCA_THEME_ATTRIBUTES = 0xA,
+    WCA_NCRENDERING_EXILED = 0xB,
+    WCA_NCADORNMENTINFO = 0xC,
+    WCA_EXCLUDED_FROM_LIVEPREVIEW = 0xD,
+    WCA_VIDEO_OVERLAY_ACTIVE = 0xE,
+    WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 0xF,
+    WCA_DISALLOW_PEEK = 0x10,
+    WCA_CLOAK = 0x11,
+    WCA_CLOAKED = 0x12,
+    WCA_ACCENT_POLICY = 0x13,
+    WCA_FREEZE_REPRESENTATION = 0x14,
+    WCA_EVER_UNCLOAKED = 0x15,
+    WCA_VISUAL_OWNER = 0x16,
+    WCA_HOLOGRAPHIC = 0x17,
+    WCA_EXCLUDED_FROM_DDA = 0x18,
+    WCA_PASSIVEUPDATEMODE = 0x19,
+    WCA_LAST = 0x1A,
+};
+
+struct WINDOWCOMPOSITIONATTRIBDATA {
+    WINDOWCOMPOSITIONATTRIB Attrib;
+    void* pvData;
+    DWORD cbData;
+};
+
+typedef BOOL(WINAPI* SetWindowCompositionAttribute)(
+    IN HWND hwnd,
+    IN WINDOWCOMPOSITIONATTRIBDATA* pwcad);
+
+typedef BOOL(WINAPI* GetWindowCompositionAttribute)(
+    IN HWND hwnd,
+    OUT WINDOWCOMPOSITIONATTRIBDATA* pAttrData
+);
+
+//Signature for DCompositionCreateDevice
+typedef HRESULT (*DCompositionCreateDeviceFun)(IDXGIDevice *dxgiDevice, REFIID iid, void** dcompositionDevice);
+
+namespace vlc
+{
+
+/**
+ * @brief The CompositorDCompositionAcrylicSurface class
+ * Adds acrylic surface to the compositor_dcomp when the main window becomes active
+ * This acrylic surface is only valid for screen configuration at the time of initialization
+ */
+
+class CompositorDCompositionAcrylicSurface
+        : public QObject
+        , public QAbstractNativeEventFilter
+{
+    Q_OBJECT
+
+public:
+    CompositorDCompositionAcrylicSurface(qt_intf_t *intf_t, ID3D11Device *device, QObject *parent = nullptr);
+
+    ~CompositorDCompositionAcrylicSurface();
+
+protected:
+    bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override;
+
+    void timerEvent(QTimerEvent *event) override;
+
+private:
+    bool init(ID3D11Device *device);
+    bool loadFunctions();
+    bool createDevice(ID3D11Device *device);
+    bool createDesktopVisual();
+    bool createBackHostVisual();
+
+    void sync();
+    void updateVisual();
+    void commitChanges();
+    void requestReset();
+
+    void setActive(bool newActive);
+
+    QWindow *window();
+
+    HWND hwnd();
+
+    DwmpCreateSharedThumbnailVisual lDwmpCreateSharedThumbnailVisual {};
+
+    DwmpCreateSharedMultiWindowVisual lDwmpCreateSharedMultiWindowVisual {};
+
+    // use to update visual created with lDwmpCreateSharedMultiWindowVisual
+    //PRE-IRON
+    DwmpUpdateSharedVirtualDesktopVisual lDwmpUpdateSharedVirtualDesktopVisual {};
+
+    //20xxx+
+    DwmpUpdateSharedMultiWindowVisual lDwmpUpdateSharedMultiWindowVisual {};
+
+    SetWindowCompositionAttribute lSetWindowCompositionAttribute {};
+    GetWindowCompositionAttribute lGetWindowCompositionAttribute {};
+
+    HTHUMBNAIL m_backHostThumbnail = NULL;
+    HWND m_dummyWindow {};
+
+    Microsoft::WRL::ComPtr<IDCompositionDevice3> m_dcompDevice;
+    Microsoft::WRL::ComPtr<IDCompositionVisual2> m_rootVisual;
+    Microsoft::WRL::ComPtr<IDCompositionVisual2> m_backHostVisual;
+    Microsoft::WRL::ComPtr<IDCompositionVisual2> m_desktopVisual;
+    Microsoft::WRL::ComPtr<IDCompositionRectangleClip> m_rootClip;
+    Microsoft::WRL::ComPtr<IDCompositionTranslateTransform> m_translateTransform;
+    Microsoft::WRL::ComPtr<IDCompositionSaturationEffect> m_saturationEffect;
+    Microsoft::WRL::ComPtr<IDCompositionGaussianBlurEffect> m_gaussianBlur;
+
+    qt_intf_t *m_intf {};
+    QBasicTimer m_resetTimer;
+    bool m_resetPending = false;
+    bool m_active = false;
+    int m_leftMostScreenX = 0;
+    int m_topMostScreenY = 0;
+};
+
+}
+
+#endif


=====================================
modules/gui/qt/maininterface/compositor_dcomp_uisurface.hpp
=====================================
@@ -28,6 +28,12 @@
 #include <vlc_interface.h> /* intf_thread_t */
 
 #include <windows.h>
+
+# if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x603)
+#  undef _WIN32_WINNT
+#  define _WIN32_WINNT 0x0603
+# endif
+
 #include <d3d11.h>
 #include <dcomp.h>
 #include <wrl.h>


=====================================
modules/gui/qt/maininterface/main_interface.cpp
=====================================
@@ -342,6 +342,24 @@ void MainInterface::onWindowVisibilityChanged(QWindow::Visibility visibility)
     m_windowVisibility = visibility;
 }
 
+void MainInterface::setUseAcrylicBackground(const bool v)
+{
+    if (m_useAcrylicBackground == v)
+        return;
+
+    m_useAcrylicBackground = v;
+    emit useAcrylicBackgroundChanged();
+}
+
+void MainInterface::setHasAcrylicSurface(const bool v)
+{
+    if (m_hasAcrylicSurface == v)
+        return;
+
+    m_hasAcrylicSurface = v;
+    emit hasAcrylicSurfaceChanged();
+}
+
 void MainInterface::incrementIntfUserScaleFactor(bool increment)
 {
     if (increment)


=====================================
modules/gui/qt/maininterface/main_interface.hpp
=====================================
@@ -163,6 +163,8 @@ class MainInterface : public QObject
     Q_PROPERTY(bool canShowVideoPIP READ canShowVideoPIP CONSTANT FINAL)
     Q_PROPERTY(bool pinVideoControls READ pinVideoControls WRITE setPinVideoControls NOTIFY pinVideoControlsChanged FINAL)
     Q_PROPERTY(ControlbarProfileModel* controlbarProfileModel READ controlbarProfileModel CONSTANT FINAL)
+    Q_PROPERTY(bool useAcrylicBackground READ useAcrylicBackground NOTIFY useAcrylicBackgroundChanged FINAL)
+    Q_PROPERTY(bool hasAcrylicSurface READ hasAcrylicSurface NOTIFY hasAcrylicSurfaceChanged FINAL)
 
 public:
     /* tors */
@@ -217,6 +219,8 @@ public:
     inline ControlbarProfileModel* controlbarProfileModel() const { return m_controlbarProfileModel; }
     inline QUrl getDialogFilePath() const { return m_dialogFilepath; }
     inline void setDialogFilePath(const QUrl& filepath ){ m_dialogFilepath = filepath; }
+    inline bool useAcrylicBackground() const { return m_useAcrylicBackground; }
+    inline bool hasAcrylicSurface() const { return m_hasAcrylicSurface; }
 
     bool hasEmbededVideo() const;
     VideoSurfaceProvider* getVideoSurfaceProvider() const;
@@ -290,6 +294,9 @@ protected:
 
     ControlbarProfileModel* m_controlbarProfileModel;
 
+    bool m_useAcrylicBackground = true;
+    bool m_hasAcrylicSurface = false;
+
 public slots:
     void toggleUpdateSystrayMenu();
     void showUpdateSystrayMenu();
@@ -306,6 +313,8 @@ public slots:
     void setPinVideoControls( bool );
     void updateIntfScaleFactor();
     void onWindowVisibilityChanged(QWindow::Visibility);
+    void setUseAcrylicBackground(bool);
+    void setHasAcrylicSurface(bool);
 
     void emitBoss();
     void emitRaise();
@@ -356,6 +365,8 @@ signals:
 
     void intfScaleFactorChanged();
     void pinVideoControlsChanged( bool );
+    void useAcrylicBackgroundChanged();
+    void hasAcrylicSurfaceChanged();
 };
 
 #endif


=====================================
modules/gui/qt/maininterface/qml/BannerSources.qml
=====================================
@@ -60,15 +60,18 @@ FocusScope {
             searchBox.expanded = true
     }
 
-    Rectangle {
+    Widgets.AcrylicBackground {
+        alternativeColor: VLCStyle.colors.topBanner
+        anchors.fill: parent
+    }
+
+     Item {
         id: pLBannerSources
 
         property alias model: globalMenuGroup.model
 
         anchors.fill: parent
 
-        color: VLCStyle.colors.topBanner
-
         Column {
             id: col
             anchors {
@@ -161,6 +164,7 @@ FocusScope {
 
                             delegate: Widgets.BannerTabButton {
                                 iconTxt: model.icon
+                                color: "transparent"
                                 showText: globalToolbar.colapseTabButtons
                                 selected: model.index === selectedIndex
                                 onClicked: root.itemClicked(model.index)


=====================================
modules/gui/qt/medialibrary/qml/MusicArtistsAlbums.qml
=====================================
@@ -101,11 +101,10 @@ FocusScope {
         focus: visible
         anchors.fill: parent
 
-        Rectangle {
+        Widgets.AcrylicBackground {
             width: artistList.width
             height: artistList.height
-            color: VLCStyle.colors.bgAlt
-            opacity: .8
+            alternativeColor: VLCStyle.colors.bgAlt
         }
 
         Row {


=====================================
modules/gui/qt/player/qml/Player.qml
=====================================
@@ -567,6 +567,8 @@ FocusScope {
 
             PL.PlaylistListView {
                 id: playlistView
+
+                useAcrylic: false
                 focus: true
                 anchors.fill: parent
 


=====================================
modules/gui/qt/playlist/qml/PlaylistListView.qml
=====================================
@@ -32,6 +32,8 @@ FocusScope {
 
     property alias model: listView.model
 
+    property alias useAcrylic: acrylicBackground.enabled
+
     readonly property real minimumWidth: noContentInfoColumn.implicitWidth +
                                          leftPadding +
                                          rightPadding +
@@ -102,10 +104,16 @@ FocusScope {
         }
     }
 
-    Rectangle {
+    Widgets.AcrylicBackground {
+        id: acrylicBackground
+
+        anchors.fill: parent
+        alternativeColor: colors.bgAlt
+    }
+
+    Item {
         id: parentRect
         anchors.fill: parent
-        color: colors.topBanner
 
         Widgets.DragItem {
             id: dragItem


=====================================
modules/gui/qt/vlc.qrc
=====================================
@@ -196,6 +196,7 @@
         <file alias="ActionButtonPrimary.qml">widgets/qml/ActionButtonPrimary.qml</file>
         <file alias="BannerTabButton.qml">widgets/qml/BannerTabButton.qml</file>
         <file alias="BusyIndicatorExt.qml">widgets/qml/BusyIndicatorExt.qml</file>
+        <file alias="AcrylicBackground.qml">widgets/qml/AcrylicBackground.qml</file>
         <file alias="AnimatedBackground.qml">widgets/qml/AnimatedBackground.qml</file>
         <file alias="CSDWindowButton.qml">widgets/qml/CSDWindowButton.qml</file>
         <file alias="CSDWindowButtonSet.qml">widgets/qml/CSDWindowButtonSet.qml</file>


=====================================
modules/gui/qt/widgets/qml/AcrylicBackground.qml
=====================================
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Copyright (C) 2021 VLC authors and VideoLAN
+ *
+ * Authors: Prince Gupta <guptaprince8832 at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * ( at your option ) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+import QtQuick 2.11
+
+import "qrc:///style/"
+
+// This Component uses layering, avoid adding children to this widget
+Item {
+    id: root
+
+    readonly property bool usingAcrylic: visible && enabled && mainInterface.useAcrylicBackground && mainInterface.hasAcrylicSurface
+
+    property color tintColor: VLCStyle.colors.setColorAlpha(VLCStyle.colors.bg, 0.7)
+
+    property color alternativeColor: VLCStyle.colors.bgAlt
+
+    layer.enabled: true
+    layer.effect: ShaderEffect {
+        property color overlay: root.usingAcrylic ? root.tintColor : root.alternativeColor
+
+        blending: false
+        fragmentShader: "
+            uniform lowp vec4 overlay;
+            void main() { gl_FragColor = overlay; }
+        "
+    }
+}



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/9ace5912de874bceb95a777f19cd36c2cfc3d437...b605fd25e97c75aa147b9bfd7fb530904eed27c7

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/9ace5912de874bceb95a777f19cd36c2cfc3d437...b605fd25e97c75aa147b9bfd7fb530904eed27c7
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list