[vlc-commits] [Git][videolan/vlc][master] 6 commits: qt: register the specific `MainCtx` qml type

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Wed Jul 29 14:26:08 UTC 2026



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


Commits:
ae4254ca by Fatih Uzunoglu at 2026-07-29T15:18:23+02:00
qt: register the specific `MainCtx` qml type

- - - - -
25ad0423 by Fatih Uzunoglu at 2026-07-29T15:18:23+02:00
qt: introduce `MainCtxWin32::createWindowWithoutRedirectionSurface()`

- - - - -
9dbd6898 by Fatih Uzunoglu at 2026-07-29T15:18:23+02:00
qt: use `MainCtxWin32::createWindowWithoutRedirectionSurfaceImpl()` in `CompositorDirectComposition`

- - - - -
c7eede6d by Fatih Uzunoglu at 2026-07-29T15:18:23+02:00
qt: dcomp: disable redirection surface in independent tool tip windows

- - - - -
1ffbafc8 by Fatih Uzunoglu at 2026-07-29T15:18:23+02:00
qt: dcomp: disable redirection surface in `WindowDialog`

- - - - -
84486e2f by Fatih Uzunoglu at 2026-07-29T15:18:23+02:00
qt: dcomp: disable redirection surface in `PlaylistDetachedWindow`

- - - - -


7 changed files:

- modules/gui/qt/dialogs/dialogs/qml/WindowDialog.qml
- modules/gui/qt/maininterface/compositor_dcomp.cpp
- modules/gui/qt/maininterface/mainctx_win32.cpp
- modules/gui/qt/maininterface/mainctx_win32.hpp
- modules/gui/qt/maininterface/mainui.cpp
- modules/gui/qt/playlist/qml/PlaylistDetachedWindow.qml
- modules/gui/qt/widgets/qml/ToolTipExt.qml


Changes:

=====================================
modules/gui/qt/dialogs/dialogs/qml/WindowDialog.qml
=====================================
@@ -67,6 +67,14 @@ Window {
         show()
     }
 
+    Component.onCompleted: {
+        if (MainCtx.createWindowWithoutRedirectionSurface) { // Win32
+            const ret = MainCtx.createWindowWithoutRedirectionSurface(this)
+            if (!ret)
+                console.debug("MainCtx::createWindowWithoutRedirectionSurface(): returned false for window", this)
+        }
+    }
+
     ColumnLayout {
         id: layout
         anchors.fill: parent


=====================================
modules/gui/qt/maininterface/compositor_dcomp.cpp
=====================================
@@ -325,30 +325,9 @@ bool CompositorDirectComposition::makeMainInterface(MainCtx* mainCtx, std::funct
             },
             Qt::SingleShotConnection);
 
-    {
-        // Express the desire to use WS_EX_NOREDIRECTIONBITMAP, it has the following advantages:
-        // - Increased performance due to not having to copy buffers (within GPU, or inter GPU-CPU unlike WS_EX_LAYERED).
-        // - Win32 window background brush is invalidated, so window does not flash white when opened.
-        // - No more resize artifact until the opaque scene covers the new area when the window is resized.
-        // - Make it possible to use the Windows 11 22H2 native acrylic backdrop effect, because the white background does not remain as an artifact.
-        //   When the window has a frame (currently it is the case for both SSD and CSD), clear color does not clear that background, which means
-        //   that the window should not be exposed (transparent UI). Currently there is either the acrylic simulation visual in the background which is
-        //   completely opaque or the video visual or the UI visual does not get transparent, so we don't suffer from this issue. With `WS_EX_NOREDIRECTIONBITMAP`,
-        //   the background does not paint a rectangle with `WNDCLASSEX::hbrBackground`, even if `WS_EX_LAYERED` is not used, so we are fine. The scene graph
-        //   does not have anything in the window to clear, so clear color can be transparent which means that the UI can be transparent and expose the window
-        //   for the window to provide the (native) backdrop acrylic effect.
-
-        const char* const envDisableRedirectionSurface = "QT_QPA_DISABLE_REDIRECTION_SURFACE";
-        const bool redirectionSurfaceIsExplicitlyWanted = !qEnvironmentVariableIsEmpty(envDisableRedirectionSurface) && !qEnvironmentVariableIntValue(envDisableRedirectionSurface);
-
-        if (!redirectionSurfaceIsExplicitlyWanted)
-            qputenv(envDisableRedirectionSurface, "1"); // TODO: Other QQuickWindow (toolbar editor, independent popups)
-
-        m_quickView->create();
-
-        if (!redirectionSurfaceIsExplicitlyWanted)
-            qunsetenv(envDisableRedirectionSurface); // NOTE: We need to disable it, otherwise regular QWidget windows would have issues
-    }
+    const bool noRedirectionSurface = MainCtxWin32::createWindowWithoutRedirectionSurfaceImpl(m_quickView.get());
+    if (!noRedirectionSurface)
+        qDebug() << "MainCtxWin32::createWindowWithoutRedirectionSurfaceImpl() returned false for window" << m_quickView.get();
 
     const bool ret = commonGUICreate(quickViewPtr, quickViewPtr, CompositorVideo::CAN_SHOW_PIP | CompositorVideo::HAS_ACRYLIC);
 


=====================================
modules/gui/qt/maininterface/mainctx_win32.cpp
=====================================
@@ -40,6 +40,8 @@
 
 #include <QWindow>
 
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
 #include <dwmapi.h>
 
 #define WM_APPCOMMAND 0x0319
@@ -840,6 +842,52 @@ bool MainCtxWin32::getDisableVolumeKeys() const
     return m_disableVolumeKeys;
 }
 
+bool MainCtxWin32::createWindowWithoutRedirectionSurfaceImpl(QWindow *window)
+{
+    assert(window);
+
+    if (window->handle()) // Unlike `::winId()`, `::handle()` does not implicitly call `::create()`
+    {
+        const auto extendedStyle = GetWindowLong(reinterpret_cast<HWND>(window->winId()), GWL_EXSTYLE);
+        const bool alreadyHasNoRedirectionBitmap = (extendedStyle & 0x00200000L /* WS_EX_NOREDIRECTIONBITMAP */);
+
+        assert(alreadyHasNoRedirectionBitmap); // You can not call this function on an already created window.
+        return alreadyHasNoRedirectionBitmap;
+    }
+
+    // Express the desire to use WS_EX_NOREDIRECTIONBITMAP, it has the following advantages:
+    // - Increased performance due to not having to copy buffers (within GPU, or inter GPU-CPU unlike WS_EX_LAYERED).
+    // - Win32 window background brush is invalidated, so window does not flash white when opened.
+    // - No more resize artifact until the opaque scene covers the new area when the window is resized.
+    // - Make it possible to use the Windows 11 22H2 native acrylic backdrop effect, because the white background does not remain as an artifact.
+    //   When the window has a frame (currently it is the case for both SSD and CSD), clear color does not clear that background, which means
+    //   that the window should not be exposed (transparent UI). Currently there is either the acrylic simulation visual in the background which is
+    //   completely opaque or the video visual or the UI visual does not get transparent, so we don't suffer from this issue. With `WS_EX_NOREDIRECTIONBITMAP`,
+    //   the background does not paint a rectangle with `WNDCLASSEX::hbrBackground`, even if `WS_EX_LAYERED` is not used, so we are fine. The scene graph
+    //   does not have anything in the window to clear, so clear color can be transparent which means that the UI can be transparent and expose the window
+    //   for the window to provide the (native) backdrop acrylic effect.
+
+    const char* const envDisableRedirectionSurface = "QT_QPA_DISABLE_REDIRECTION_SURFACE";
+    const bool redirectionSurfaceIsExplicitlyWanted = !qEnvironmentVariableIsEmpty(envDisableRedirectionSurface) && !qEnvironmentVariableIntValue(envDisableRedirectionSurface);
+
+    if (!redirectionSurfaceIsExplicitlyWanted)
+    {
+        qputenv(envDisableRedirectionSurface, "1");
+    }
+    else
+    {
+        qDebug() << "MainCtxWin32::createWindowWithoutRedirectionSurfaceImpl():"
+                 << "redirection surface is explicitly wanted through" << envDisableRedirectionSurface;
+        return false;
+    }
+
+    window->create();
+
+    qunsetenv(envDisableRedirectionSurface); // NOTE: We need to disable it, otherwise regular QWidget windows would have issues
+
+    return true;
+}
+
 // InterfaceWindowHandlerWin32
 
 InterfaceWindowHandlerWin32::InterfaceWindowHandlerWin32(qt_intf_t *_p_intf, MainCtx* mainCtx, QWindow* window, QObject *parent)


=====================================
modules/gui/qt/maininterface/mainctx_win32.hpp
=====================================
@@ -25,6 +25,7 @@
 #define MAIN_INTERFACE_WIN32_HPP
 
 #include "maininterface/mainctx.hpp"
+#include "maininterface/compositor.hpp"
 #include "player/player_controller.hpp"
 #include "interface_window_handler.hpp"
 #include <QAbstractNativeEventFilter>
@@ -91,6 +92,19 @@ public:
     Q_INVOKABLE bool platformHandlesShadowsWithCSD() const override { return (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8); };
     Q_INVOKABLE bool platformHandlesResizeWithCSD() const override { return (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8); };
 
+    static bool createWindowWithoutRedirectionSurfaceImpl(QWindow* window);
+
+    Q_INVOKABLE bool createWindowWithoutRedirectionSurface(QWindow* window)
+    {
+        // Only applicable with Direct Composition:
+        assert(p_intf);
+        assert(p_intf->p_compositor);
+        if (p_intf->p_compositor->type() != vlc::Compositor::DirectCompositionCompositor)
+            return false;
+
+        return createWindowWithoutRedirectionSurfaceImpl(window);
+    }
+
 public slots:
     void reloadPrefs() override;
 


=====================================
modules/gui/qt/maininterface/mainui.cpp
=====================================
@@ -87,6 +87,9 @@
 
 #include "videosurface.hpp"
 #include "mainctx.hpp"
+#ifdef _WIN32
+#include "mainctx_win32.hpp"
+#endif
 #include "mainctx_submodels.hpp"
 
 #include <QScreen>
@@ -227,6 +230,10 @@ void MainUI::registerQMLTypes()
 
         // @uri VLC.MainInterface
         qmlRegisterSingletonInstance<MainCtx>(uri, versionMajor, versionMinor, "MainCtx", m_mainCtx);
+#ifdef _WIN32
+        assert(dynamic_cast<MainCtxWin32*>(m_mainCtx));
+        qmlRegisterAnonymousType<MainCtxWin32>(uri, versionMajor);
+#endif
         qmlRegisterTypesAndRevisions<SearchCtx>(uri, versionMajor);
         qmlRegisterTypesAndRevisions<SortCtx>(uri, versionMajor);
         qmlRegisterUncreatableType<UINotifier>(uri, versionMajor, versionMinor, "UINotifier", "");


=====================================
modules/gui/qt/playlist/qml/PlaylistDetachedWindow.qml
=====================================
@@ -51,6 +51,14 @@ Window {
         MainCtx.playqueuePanel.visible = false
     }
 
+    Component.onCompleted: {
+        if (MainCtx.createWindowWithoutRedirectionSurface) { // Win32
+            const ret = MainCtx.createWindowWithoutRedirectionSurface(this)
+            if (!ret)
+                console.debug("MainCtx::createWindowWithoutRedirectionSurface(): returned false for window", this)
+        }
+    }
+
     PlaylistPane {
         id: playlistView
 


=====================================
modules/gui/qt/widgets/qml/ToolTipExt.qml
=====================================
@@ -78,6 +78,18 @@ T.ToolTip {
         wrapMode: Text.WordWrap
 
         color: theme.fg.primary
+
+        Component.onCompleted: {
+            if (MainCtx.createWindowWithoutRedirectionSurface) { // Win32
+                Window.windowChanged.connect(this, () => {
+                    if (Window.window && (Window.window !== MainCtx.intfMainWindow)) { // Only relevant when `popupType` is `Popup.Window`
+                        const ret = MainCtx.createWindowWithoutRedirectionSurface(Window.window)
+                        if (!ret)
+                            console.debug("MainCtx::createWindowWithoutRedirectionSurface(): returned false for window", this)
+                    }
+                })
+            }
+        }
     }
 
     background: Rectangle {



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/dedb8cf3465a015a9d8219aeaf108a6d79f23e47...84486e2fb2eb0b2e866e879c3501505430df8045

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/dedb8cf3465a015a9d8219aeaf108a6d79f23e47...84486e2fb2eb0b2e866e879c3501505430df8045
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list