[vlc-devel] [PATCH 09/16] qt: separate video window handling code from main interface

Pierre Lamot pierre at videolabs.io
Thu Aug 6 09:43:55 CEST 2020


  This allows to manage the video window then actual window is different from
  the main interface window.
---
 modules/gui/qt/Makefile.am                    |   3 +
 .../qt/maininterface/video_window_handler.cpp | 179 ++++++++++++++++++
 .../qt/maininterface/video_window_handler.hpp |  75 ++++++++
 3 files changed, 257 insertions(+)
 create mode 100644 modules/gui/qt/maininterface/video_window_handler.cpp
 create mode 100644 modules/gui/qt/maininterface/video_window_handler.hpp

diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index b02cb7440d..5ce6527b44 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -124,6 +124,8 @@ libqt_plugin_la_SOURCES = \
 	gui/qt/maininterface/mainui.hpp \
 	gui/qt/maininterface/videosurface.cpp \
 	gui/qt/maininterface/videosurface.hpp \
+	gui/qt/maininterface/video_window_handler.cpp \
+	gui/qt/maininterface/video_window_handler.hpp \
 	gui/qt/medialibrary/medialib.cpp \
 	gui/qt/medialibrary/medialib.hpp \
 	gui/qt/medialibrary/mlalbum.cpp \
@@ -289,6 +291,7 @@ nodist_libqt_plugin_la_SOURCES = \
 	gui/qt/maininterface/main_interface.moc.cpp \
 	gui/qt/maininterface/mainui.moc.cpp \
 	gui/qt/maininterface/videosurface.moc.cpp \
+	gui/qt/maininterface/video_window_handler.moc.cpp \
 	gui/qt/medialibrary/medialib.moc.cpp \
 	gui/qt/medialibrary/mlalbum.moc.cpp \
 	gui/qt/medialibrary/mlalbummodel.moc.cpp \
diff --git a/modules/gui/qt/maininterface/video_window_handler.cpp b/modules/gui/qt/maininterface/video_window_handler.cpp
new file mode 100644
index 0000000000..c54fef03f5
--- /dev/null
+++ b/modules/gui/qt/maininterface/video_window_handler.cpp
@@ -0,0 +1,179 @@
+/*****************************************************************************
+ * Copyright (C) 2020 VLC authors and VideoLAN
+ *
+ * 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 "video_window_handler.hpp"
+#include "main_interface.hpp"
+
+#include <QApplication>
+#include <QScreen>
+
+#include <vlc_vout_window.h>
+
+VideoWindowHandler::VideoWindowHandler(intf_thread_t* intf, MainInterface* mainInterace,QObject *parent)
+    : QObject(parent)
+    , m_intf(intf)
+    , m_interface(mainInterace)
+{
+    /* Does the interface resize to video size or the opposite */
+    m_autoresize = var_InheritBool( m_intf, "qt-video-autoresize" );
+
+    connect( this, &VideoWindowHandler::askVideoToResize,
+             this, &VideoWindowHandler::setVideoSize, Qt::QueuedConnection );
+    connect( this, &VideoWindowHandler::askVideoSetFullScreen,
+             this, &VideoWindowHandler::setVideoFullScreen, Qt::QueuedConnection );
+    connect( this, &VideoWindowHandler::askVideoOnTop,
+             this, &VideoWindowHandler::setVideoOnTop, Qt::QueuedConnection );
+}
+
+void VideoWindowHandler::setWindow(QWindow* window)
+{
+    m_window = window;
+}
+
+void VideoWindowHandler::disable()
+{
+    emit askVideoSetFullScreen( false );
+    emit askVideoOnTop( false );
+}
+
+void VideoWindowHandler::requestResizeVideo( unsigned i_width, unsigned i_height )
+{
+    emit askVideoToResize( i_width, i_height );
+}
+
+void VideoWindowHandler::requestVideoWindowed( )
+{
+   emit askVideoSetFullScreen( false );
+}
+
+void VideoWindowHandler::requestVideoFullScreen(const char * )
+{
+    emit askVideoSetFullScreen( true );
+}
+
+void VideoWindowHandler::requestVideoState(  unsigned i_arg )
+{
+    bool on_top = (i_arg & VOUT_WINDOW_STATE_ABOVE) != 0;
+    emit askVideoOnTop( on_top );
+}
+
+void VideoWindowHandler::setVideoSize(unsigned int w, unsigned int h)
+{
+    Qt::WindowStates states = m_window->windowStates();
+    if ((states & (Qt::WindowFullScreen | Qt::WindowMaximized)) == 0)
+    {
+        /* Resize video widget to video size, or keep it at the same
+         * size. Call setSize() either way so that vout_window_ReportSize
+         * will always get called.
+         * If the video size is too large for the screen, resize it
+         * to the screen size.
+         */
+        if (m_autoresize)
+        {
+            QRect screen = m_window->screen()->availableGeometry();
+            qreal factor = m_window->devicePixelRatio();
+            if( (float)h / factor > screen.height() )
+            {
+                w = screen.width();
+                h = screen.height();
+            }
+            else
+            {
+                // Convert the size in logical pixels
+                w = qRound( (float)w / factor );
+                h = qRound( (float)h / factor );
+                msg_Dbg( m_intf, "Logical video size: %ux%u", w, h );
+            }
+            m_window->resize(w, h);
+        }
+    }
+}
+
+void VideoWindowHandler::setVideoFullScreen( bool fs )
+{
+    m_videoFullScreen = fs;
+
+    Qt::WindowStates states = m_window->windowStates();
+    if( fs )
+    {
+        int numscreen = var_InheritInteger( m_intf, "qt-fullscreen-screennumber" );
+
+        auto screenList = QApplication::screens();
+        if ( numscreen >= 0 && numscreen < screenList.count() )
+        {
+            QRect screenres = screenList[numscreen]->geometry();
+            m_lastWinScreen = m_window->screen();
+#ifdef QT5_HAS_WAYLAND
+            if( !m_hasWayland )
+                m_window->setScreen(screenList[numscreen]);
+#endif
+            m_window->setScreen(screenList[numscreen]);
+
+            /* To be sure window is on proper-screen in xinerama */
+            if( !screenres.contains( m_window->position() ) )
+            {
+                m_lastWinGeometry = m_window->geometry();
+                msg_Dbg( m_intf, "Moving video to correct position");
+                m_window->setPosition(screenres.x(), screenres.y() );
+            }
+        }
+        m_window->setWindowStates(states | Qt::WindowFullScreen);
+    }
+    else
+    {
+        if (m_interface->isInterfaceFullScreen())
+            m_window->setWindowStates(states | Qt::WindowFullScreen);
+        else
+            m_window->setWindowStates(states & ~Qt::WindowFullScreen);
+#ifdef QT5_HAS_WAYLAND
+        if( m_lastWinScreen != NULL && !m_hasWayland )
+            m_window->setScreen(m_lastWinScreen);
+#else
+        if( m_lastWinScreen != NULL )
+            m_window->setScreen(m_lastWinScreen);
+#endif
+        //FIXME m_interface->restorePosition();
+        if( m_lastWinGeometry.isNull() == false )
+        {
+            m_window->setGeometry( m_lastWinGeometry );
+            m_lastWinGeometry = QRect();
+        }
+    }
+}
+
+
+/* Slot to change the video always-on-top flag.
+ * Emit askVideoOnTop() to invoke this from other thread. */
+void VideoWindowHandler::setVideoOnTop( bool on_top )
+{
+    //don't apply changes if user has already sets its interface on top
+    if ( m_interface->isInterfaceAlwaysOnTop() )
+        return;
+
+    Qt::WindowFlags oldflags = m_window->flags();
+    Qt::WindowFlags newflags;
+
+    if( on_top )
+        newflags = oldflags | Qt::WindowStaysOnTopHint;
+    else
+        newflags = oldflags & ~Qt::WindowStaysOnTopHint;
+    if( newflags != oldflags && !m_videoFullScreen )
+    {
+        m_window->setFlags( newflags );
+        m_window->show(); /* necessary to apply window flags */
+    }
+}
diff --git a/modules/gui/qt/maininterface/video_window_handler.hpp b/modules/gui/qt/maininterface/video_window_handler.hpp
new file mode 100644
index 0000000000..164e9166c5
--- /dev/null
+++ b/modules/gui/qt/maininterface/video_window_handler.hpp
@@ -0,0 +1,75 @@
+/*****************************************************************************
+ * Copyright (C) 2020 VLC authors and VideoLAN
+ *
+ * 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 VIDEOWINDOWHANDLER_HPP
+#define VIDEOWINDOWHANDLER_HPP
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_interface.h>
+
+#include <QWindow>
+#include <QObject>
+
+class MainInterface;
+
+class VideoWindowHandler : public QObject
+{
+    Q_OBJECT
+public:
+    explicit VideoWindowHandler(intf_thread_t *intf, MainInterface* mainInterace, QObject *parent = nullptr);
+
+public:
+    void setWindow(QWindow* window);
+
+    void disable();
+    void requestResizeVideo( unsigned, unsigned );
+    void requestVideoState( unsigned );
+    void requestVideoWindowed( );
+    void requestVideoFullScreen( const char * );
+
+signals:
+    void askVideoToResize( unsigned int, unsigned int );
+    void askVideoSetFullScreen( bool );
+    void askVideoOnTop( bool );
+
+protected slots:
+    /* Manage the Video Functions from the vout threads */
+    void setVideoSize(unsigned int w, unsigned int h);
+    virtual void setVideoFullScreen( bool );
+    void setVideoOnTop( bool );
+
+private:
+    intf_thread_t *m_intf = nullptr;
+    MainInterface* m_interface = nullptr;
+    QWindow* m_window = nullptr;
+
+    bool m_videoFullScreen = false;
+    bool m_autoresize = false;
+
+    QRect   m_lastWinGeometry;
+    QScreen* m_lastWinScreen = nullptr;
+
+#ifdef QT5_HAS_WAYLAND
+    bool m_hasWayland = false;
+#endif
+};
+
+#endif // VIDEOWINDOWHANDLER_HPP
-- 
2.25.1



More information about the vlc-devel mailing list