[vlc-devel] [PATCH v2 09/16] qt: separate video window handling code from main interface
Pierre Lamot
pierre at videolabs.io
Fri Aug 14 18:43:43 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 | 185 ++++++++++++++++++
.../qt/maininterface/video_window_handler.hpp | 75 +++++++
3 files changed, 263 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 fa62dfb0f7..305f94103d 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..760cbe219d
--- /dev/null
+++ b/modules/gui/qt/maininterface/video_window_handler.cpp
@@ -0,0 +1,185 @@
+/*****************************************************************************
+ * 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)
+{
+ if (!m_window)
+ return;
+ 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 )
+{
+ if (!m_window)
+ return;
+ 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 )
+{
+ if (!m_window)
+ return;
+ //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