[vlc-commits] qt: reparent video window to root whence UI closes

Rémi Denis-Courmont git at videolan.org
Sat Feb 6 18:43:15 UTC 2021


vlc/vlc-3.0 | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Fri Feb  5 19:46:15 2021 +0200| [4d147a3d3804fce2451938ee5145e94794f12dbf] | committer: Rémi Denis-Courmont

qt: reparent video window to root whence UI closes

The video window has to exist until it is closed by its owner, i.e.
WindowClose() is called. If it stayed as a child of the main UI window,
it would be destroyed with the main UI window.

This reparents it (back) to the root window before the main UI window
gets destroyed. This works around #21875.

> http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=4d147a3d3804fce2451938ee5145e94794f12dbf
---

 modules/gui/qt/components/interface_widgets.cpp |  2 ++
 modules/gui/qt/main_interface.cpp               |  2 ++
 modules/gui/qt/qt.cpp                           | 24 +++++++++++++++++++++++-
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/modules/gui/qt/components/interface_widgets.cpp b/modules/gui/qt/components/interface_widgets.cpp
index 74e82eab58..ff44bf2e44 100644
--- a/modules/gui/qt/components/interface_widgets.cpp
+++ b/modules/gui/qt/components/interface_widgets.cpp
@@ -229,6 +229,7 @@ QSize VideoWidget::physicalSize() const
 }
 
 void WindowResized(vout_window_t *, const QSize&);
+void WindowReleased(vout_window_t *);
 
 void VideoWidget::reportSize()
 {
@@ -378,6 +379,7 @@ void VideoWidget::release( void )
 
     if( stable )
     {
+        WindowReleased(p_window);
         layout->removeWidget( stable );
         stable->deleteLater();
         stable = NULL;
diff --git a/modules/gui/qt/main_interface.cpp b/modules/gui/qt/main_interface.cpp
index 259dcf7109..a57506533d 100644
--- a/modules/gui/qt/main_interface.cpp
+++ b/modules/gui/qt/main_interface.cpp
@@ -1664,6 +1664,8 @@ void MainInterface::closeEvent( QCloseEvent *e )
 //  hide();
     if ( b_minimalView )
         setMinimalView( false );
+    if( videoWidget )
+        releaseVideoSlot();
     emit askToQuit(); /* ask THEDP to quit, so we have a unique method */
     /* Accept session quit. Otherwise we break the desktop mamager. */
     e->accept();
diff --git a/modules/gui/qt/qt.cpp b/modules/gui/qt/qt.cpp
index ded2a908de..8acf42808a 100644
--- a/modules/gui/qt/qt.cpp
+++ b/modules/gui/qt/qt.cpp
@@ -28,6 +28,7 @@
 
 #define VLC_MODULE_LICENSE VLC_LICENSE_GPL_2_PLUS
 
+#include <atomic>
 #include <QApplication>
 #include <QDate>
 #include <QMutex>
@@ -714,6 +715,7 @@ typedef struct {
 #ifdef QT5_HAS_X11
     Display *dpy;
 #endif
+    std::atomic<bool> orphaned;
 } vout_window_qt_t;
 
 static int WindowOpen( vout_window_t *p_wnd, const vout_window_cfg_t *cfg )
@@ -748,6 +750,7 @@ static int WindowOpen( vout_window_t *p_wnd, const vout_window_cfg_t *cfg )
     vout_window_qt_t *sys = new vout_window_qt_t;
 
     sys->mi = p_intf->p_sys->p_mi;
+    sys->orphaned = false;
     p_wnd->sys = (vout_window_sys_t *)sys;
     msg_Dbg( p_wnd, "requesting video window..." );
 
@@ -783,7 +786,7 @@ static int WindowOpen( vout_window_t *p_wnd, const vout_window_cfg_t *cfg )
     }
 
 #ifdef QT5_HAS_X11
-    if (QX11Info::isPlatformX11())
+    if (QX11Info::isPlatformX11() && likely(!sys->orphaned))
     {
         XReparentWindow(sys->dpy, xid, p_wnd->handle.xid, 0, 0);
         XMapWindow(sys->dpy, xid);
@@ -824,6 +827,25 @@ static int WindowControl( vout_window_t *p_wnd, int i_query, va_list args )
     return sys->mi->controlVideo(i_query, args);
 }
 
+void WindowReleased(vout_window_t *wnd)
+{
+    vout_window_qt_t *sys = (vout_window_qt_t *)wnd->sys;
+
+    msg_Warn(wnd, "orphaned video window");
+    sys->orphaned = true;
+#if defined (QT5_HAS_X11)
+    if (QX11Info::isPlatformX11())
+    {   /* In the unlikely event that WindowOpen() has not yet reparented the
+         * window, WindowOpen() will skip reparenting. Then this call will be
+         * a no-op.
+         */
+        XReparentWindow(sys->dpy, wnd->handle.xid,
+                        RootWindow(sys->dpy, DefaultScreen(sys->dpy)), 0, 0);
+        XSync(sys->dpy, True);
+    }
+#endif
+}
+
 static void WindowClose( vout_window_t *p_wnd )
 {
     vout_window_qt_t *sys = (vout_window_qt_t *)p_wnd->sys;



More information about the vlc-commits mailing list