[vlc-commits] [Git][videolan/vlc][master] 2 commits: qt: make CompositorX11RenderWindow a QMainWindow

Rémi Denis-Courmont (@Courmisch) gitlab at videolan.org
Wed Mar 2 21:02:07 UTC 2022



Rémi Denis-Courmont pushed to branch master at VideoLAN / VLC


Commits:
7613d360 by Pierre Lamot at 2022-03-02T20:17:01+00:00
qt: make CompositorX11RenderWindow a QMainWindow

CompositorX11RenderWindow acts as the main window, there is no points in
encapsulating the actual object.

- - - - -
94bc262f by Pierre Lamot at 2022-03-02T20:17:01+00:00
qt: fix video window visible twice with X11 compositor

removing BypassWindowManagerHint was causing the window to be displayed twice on
some desktop environments

fix: #26590

- - - - -


4 changed files:

- modules/gui/qt/maininterface/compositor_x11.cpp
- modules/gui/qt/maininterface/compositor_x11_renderwindow.cpp
- modules/gui/qt/maininterface/compositor_x11_renderwindow.hpp
- modules/gui/qt/maininterface/compositor_x11_utils.cpp


Changes:

=====================================
modules/gui/qt/maininterface/compositor_x11.cpp
=====================================
@@ -152,26 +152,33 @@ bool CompositorX11::makeMainInterface(MainCtx* mainCtx)
 {
     m_mainCtx = mainCtx;
 
-    m_videoWidget = std::make_unique<DummyNativeWidget>();
+
+    bool useCSD = m_mainCtx->useClientSideDecoration();
+    m_renderWindow = std::make_unique<vlc::CompositorX11RenderWindow>(m_intf, m_conn, useCSD);
+    if (!m_renderWindow->init())
+        return false;
+
+    m_videoWidget = std::make_unique<DummyNativeWidget>(m_renderWindow.get());
     // widget would normally require WindowTransparentForInput, without this
     // we end up with an invisible area within our window that grabs our mouse events.
     // But using this this causes rendering issues with some VoutDisplay
-    // (xcb_render for instance) instead, we manually, set a null intput region afterwards
+    // (xcb_render for instance) instead, we manually, set a null input region afterwards
     // see setTransparentForMouseEvent
     m_videoWidget->winId();
-    m_videoWidget->setWindowFlag(Qt::WindowStaysOnBottomHint);
-    m_videoWidget->show();
 
-    bool useCSD = m_mainCtx->useClientSideDecoration();
-    m_renderWindow = std::make_unique<vlc::CompositorX11RenderWindow>(m_intf, m_conn, useCSD);
-    if (!m_renderWindow->init())
-        return false;
+    //update manually EventMask as we don't use WindowTransparentForInput
+    const uint32_t mask = XCB_CW_EVENT_MASK;
+    const uint32_t values = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY
+        | XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_FOCUS_CHANGE;
+    xcb_change_window_attributes(QX11Info::connection(), m_videoWidget->winId(), mask, &values);
+    setTransparentForMouseEvent(QX11Info::connection(), m_videoWidget->winId());
+    m_videoWidget->show();
 
     m_interfaceWindow = m_renderWindow->getWindow();
 
     m_qmlView = std::make_unique<CompositorX11UISurface>(m_interfaceWindow);
-    m_qmlView->setFlag(Qt::WindowType::BypassWindowManagerHint);
     m_qmlView->setFlag(Qt::WindowType::WindowTransparentForInput);
+    m_qmlView->setParent(m_interfaceWindow);
     m_qmlView->winId();
     m_qmlView->show();
 


=====================================
modules/gui/qt/maininterface/compositor_x11_renderwindow.cpp
=====================================
@@ -318,45 +318,38 @@ void X11DamageObserver::onEvent()
 
 //// CompositorX11RenderWindow
 
-CompositorX11RenderWindow::CompositorX11RenderWindow(qt_intf_t* p_intf, xcb_connection_t* conn, bool useCDS, QObject* parent)
-    : QObject(parent)
+CompositorX11RenderWindow::CompositorX11RenderWindow(qt_intf_t* p_intf, xcb_connection_t* conn, bool useCDS, QWidget* parent)
+    : QMainWindow(parent)
     , m_intf(p_intf)
     , m_conn(conn)
 {
-    m_rootWidget = new QMainWindow();
-    m_rootWidget->setAttribute(Qt::WA_NativeWindow);
-    m_rootWidget->setAttribute(Qt::WA_OpaquePaintEvent);
-    m_rootWidget->setAttribute(Qt::WA_NoSystemBackground);
-    m_rootWidget->setAttribute(Qt::WA_TranslucentBackground);
-    m_rootWidget->setAttribute(Qt::WA_MouseTracking);
+    setAttribute(Qt::WA_NativeWindow);
+    setAttribute(Qt::WA_OpaquePaintEvent);
+    setAttribute(Qt::WA_NoSystemBackground);
+    setAttribute(Qt::WA_TranslucentBackground);
+    setAttribute(Qt::WA_MouseTracking);
 
     if (useCDS)
-        m_rootWidget->setWindowFlag(Qt::FramelessWindowHint);
+        setWindowFlag(Qt::FramelessWindowHint);
 
-    m_stable = new DummyNativeWidget(m_rootWidget);
+    m_stable = new DummyNativeWidget(this);
     m_stable->winId();
 
-    m_rootWidget->setCentralWidget(m_stable);
+    setCentralWidget(m_stable);
 
-    m_rootWidget->winId();
-    m_rootWidget->show();
+    winId();
+    show();
 
-    m_window = m_rootWidget->window()->windowHandle();
-    m_wid = m_window->winId();
+    m_window = window()->windowHandle();
+    m_wid = winId();
 }
 
 CompositorX11RenderWindow::~CompositorX11RenderWindow()
 {
     stopRendering();
 
-    if (m_rootWidget)
-    {
-        m_rootWidget->removeEventFilter(this);
-        m_window->removeEventFilter(this);
-
-        if (m_rootWidget)
-            delete m_rootWidget;
-    }
+    removeEventFilter(this);
+    m_window->removeEventFilter(this);
 }
 
 bool CompositorX11RenderWindow::init()
@@ -384,7 +377,7 @@ bool CompositorX11RenderWindow::init()
     }
 
     //install event filters
-    m_rootWidget->installEventFilter(this);
+    installEventFilter(this);
     m_window->installEventFilter(this);
 
     return true;
@@ -414,7 +407,7 @@ bool CompositorX11RenderWindow::startRendering()
     //pass initial values
     m_renderTask->onInterfaceSurfaceChanged(m_interfaceClient.get());
     m_renderTask->onVideoSurfaceChanged(m_videoClient.get());
-    m_renderTask->onWindowSizeChanged(m_rootWidget->size() * m_rootWidget->devicePixelRatioF());
+    m_renderTask->onWindowSizeChanged(size() * devicePixelRatioF());
     m_renderTask->onAcrylicChanged(m_hasAcrylic);
 
     //use the same thread as the rendering thread, neither tasks are blocking.
@@ -477,13 +470,13 @@ bool CompositorX11RenderWindow::eventFilter(QObject* obj, QEvent* event)
             if (m_interfaceWindow)
                 m_interfaceWindow->handleWindowEvent(event);
             resetClientPixmaps();
-            emit windowSizeChanged(resizeEvent->size() * m_rootWidget->devicePixelRatioF());
+            emit windowSizeChanged(resizeEvent->size() * devicePixelRatioF());
             needRefresh = true;
         }
     }
     else
     {
-        assert(obj == m_rootWidget);
+        assert(obj == this);
         if (event->type() == QEvent::Resize)
             return false;
 
@@ -540,19 +533,17 @@ void CompositorX11RenderWindow::setVideoSize(const QSize& size)
             m_videoClient->resetPixmap();
             m_videoClient->getPicture();
         }
-        m_videoPosition.setSize(size * m_rootWidget->devicePixelRatioF());
+        m_videoPosition.setSize(size * devicePixelRatioF());
         emit videoPositionChanged(m_videoPosition);
     }
 }
 
 void CompositorX11RenderWindow::setVideoWindow( QWindow* window)
 {
-    window->setParent(m_window);
     //ensure Qt x11 pending operation have been forwarded to the server
     xcb_flush(QX11Info::connection());
     m_videoClient = std::make_unique<CompositorX11RenderClient>(m_intf, m_conn, window);
     m_videoPosition = QRect(0,0,0,0);
-    setTransparentForMouseEvent(QX11Info::connection(), window->winId());
     m_videoWindow = window;
     emit videoSurfaceChanged(m_videoClient.get());
 }
@@ -569,8 +560,6 @@ void CompositorX11RenderWindow::disableVideoWindow()
 
 void CompositorX11RenderWindow::setInterfaceWindow(CompositorX11UISurface* window)
 {
-    assert(m_window);
-    window->setParent(m_window);
     //ensure Qt x11 pending operation have been forwarded to the server
     xcb_flush(QX11Info::connection());
     m_interfaceClient = std::make_unique<CompositorX11RenderClient>(m_intf, m_conn, window);


=====================================
modules/gui/qt/maininterface/compositor_x11_renderwindow.hpp
=====================================
@@ -26,6 +26,7 @@
 
 #include <QObject>
 #include <QMutex>
+#include <QMainWindow>
 
 #include <xcb/xcb.h>
 #include <xcb/render.h>
@@ -39,7 +40,6 @@
 #include "compositor_x11_utils.hpp"
 
 class QWidget;
-class QMainWindow;
 class QSocketNotifier;
 
 namespace vlc {
@@ -144,11 +144,11 @@ public:
     QSocketNotifier* m_socketNotifier = nullptr;
 };
 
-class CompositorX11RenderWindow : public QObject
+class CompositorX11RenderWindow : public QMainWindow
 {
     Q_OBJECT
 public:
-    explicit CompositorX11RenderWindow(qt_intf_t* p_intf, xcb_connection_t* conn, bool useCDS, QObject* parent = nullptr);
+    explicit CompositorX11RenderWindow(qt_intf_t* p_intf, xcb_connection_t* conn, bool useCDS, QWidget* parent = nullptr);
     ~CompositorX11RenderWindow();
 
     bool init();
@@ -185,7 +185,6 @@ private:
     qt_intf_t* m_intf = nullptr;
     xcb_connection_t* m_conn = nullptr;
 
-    QMainWindow* m_rootWidget = nullptr;
     QWidget* m_stable = nullptr;
 
     QThread* m_renderThread = nullptr;


=====================================
modules/gui/qt/maininterface/compositor_x11_utils.cpp
=====================================
@@ -19,8 +19,9 @@
 #include <vlc_cxx_helpers.hpp>
 #include "compositor_x11_utils.hpp"
 
-namespace vlc {
+#include <QWindow>
 
+namespace vlc {
 
 DummyNativeWidget::DummyNativeWidget(QWidget* parent, Qt::WindowFlags f)
     : QWidget(parent, f)
@@ -29,6 +30,18 @@ DummyNativeWidget::DummyNativeWidget(QWidget* parent, Qt::WindowFlags f)
     setAttribute(Qt::WA_OpaquePaintEvent, true);
     setAttribute(Qt::WA_PaintOnScreen, true);
     setAttribute(Qt::WA_MouseTracking, true);
+    setAttribute(Qt::WA_TranslucentBackground, false);
+    QWindow* w =  window()->windowHandle();
+    assert(w);
+    /*
+     * force the window not to have an alpha channel, the  parent window
+     * may have an alpha channel and child widget would inhertit the format
+     * even if we set Qt::WA_TranslucentBackground to false. having an alpha
+     * in this surface would lead to the video begin semi-tranparent.
+     */
+    QSurfaceFormat format = w->format();
+    format.setAlphaBufferSize(0);
+    w->setFormat(format);
 }
 
 DummyNativeWidget::~DummyNativeWidget()



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/8ba757d42d2e45f5feba14d93554a3d9ac29e257...94bc262fbe361dd4da5a4263b52e7ecdafe7d44e

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/8ba757d42d2e45f5feba14d93554a3d9ac29e257...94bc262fbe361dd4da5a4263b52e7ecdafe7d44e
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