[vlc-devel] [PATCH 7/7] qt: provide detached video mode for win7
Pierre Lamot
pierre at videolabs.io
Fri Aug 14 18:49:05 CEST 2020
---
.../gui/qt/maininterface/compositor_win7.cpp | 133 ++++++++++++++++--
.../gui/qt/maininterface/compositor_win7.hpp | 14 +-
2 files changed, 132 insertions(+), 15 deletions(-)
diff --git a/modules/gui/qt/maininterface/compositor_win7.cpp b/modules/gui/qt/maininterface/compositor_win7.cpp
index dab17a6997..a250f340dc 100644
--- a/modules/gui/qt/maininterface/compositor_win7.cpp
+++ b/modules/gui/qt/maininterface/compositor_win7.cpp
@@ -30,16 +30,18 @@ int CompositorWin7::window_enable(struct vout_window_t * p_wnd, const vout_windo
{
CompositorWin7* that = static_cast<CompositorWin7*>(p_wnd->sys);
msg_Dbg(that->m_intf, "window_enable");
- that->m_qmlVideoSurfaceProvider->enable(p_wnd);
+ that->m_videoSurfaceProvider->enable(p_wnd);
+ that->setVideoSurface(VideoSurfaceTarget::EMBED);
return VLC_SUCCESS;
}
void CompositorWin7::window_disable(struct vout_window_t * p_wnd)
{
CompositorWin7* that = static_cast<CompositorWin7*>(p_wnd->sys);
- that->m_qmlVideoSurfaceProvider->disable();
- that->m_videoWindowHandler->disable();
msg_Dbg(that->m_intf, "window_disable");
+ that->setVideoSurface(VideoSurfaceTarget::UNDEF);
+ that->m_videoWindowHandler->disable();
+ that->m_videoSurfaceProvider->disable();
}
void CompositorWin7::window_resize(struct vout_window_t * p_wnd, unsigned width, unsigned height)
@@ -53,6 +55,7 @@ void CompositorWin7::window_destroy(struct vout_window_t * p_wnd)
{
CompositorWin7* that = static_cast<CompositorWin7*>(p_wnd->sys);
msg_Dbg(that->m_intf, "window_destroy");
+ that->m_voutWindow = nullptr;
}
void CompositorWin7::window_set_state(struct vout_window_t * p_wnd, unsigned state)
@@ -149,7 +152,9 @@ MainInterface* CompositorWin7::makeMainInterface()
* m_stable is not attached to the main interface because dialogs are attached to the mainInterface
* and showing them would raise the video widget above the interface
*/
- m_stable = new QWidget(nullptr, Qt::Tool | Qt::FramelessWindowHint);
+
+ m_videoWidget = new QWidget(nullptr, Qt::Tool | Qt::FramelessWindowHint);
+ m_stable = new QWidget();
m_stable->setContextMenuPolicy( Qt::PreventContextMenu );
QPalette plt = m_rootWindow->palette();
@@ -162,16 +167,24 @@ MainInterface* CompositorWin7::makeMainInterface()
m_stable->setMouseTracking( true );
m_stable->setWindowFlags( Qt::Tool | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus );
m_stable->setAttribute( Qt::WA_ShowWithoutActivating );
- m_stable->show();
+ m_stable->setVisible(true);
+
+ m_videoWidgetLayout = new QVBoxLayout();
+ m_videoWidgetLayout->setMargin(0);
+ m_videoWidgetLayout->setSpacing(0);
+ m_videoWidgetLayout->addWidget(m_stable);
- m_videoWindowHWND = (HWND)m_stable->winId();
+ m_videoWidget->setLayout(m_videoWidgetLayout);
+ m_videoWidget->show();
+
+ m_videoWindowHWND = (HWND)m_videoWidget->winId();
BOOL excluseFromPeek = TRUE;
DwmSetWindowAttribute(m_videoWindowHWND, DWMWA_EXCLUDED_FROM_PEEK, &excluseFromPeek, sizeof(excluseFromPeek));
DwmSetWindowAttribute(m_videoWindowHWND, DWMWA_DISALLOW_PEEK, &excluseFromPeek, sizeof(excluseFromPeek));
- m_qmlVideoSurfaceProvider = std::make_unique<VideoSurfaceProvider>();
- m_rootWindow->setVideoSurfaceProvider(m_qmlVideoSurfaceProvider.get());
+ m_videoSurfaceProvider = std::make_unique<VideoSurfaceProvider>();
+ m_rootWindow->setVideoSurfaceProvider(m_videoSurfaceProvider.get());
m_qmlView = std::make_unique<QQuickView>();
m_qmlView->setResizeMode(QQuickView::SizeRootObjectToView);
@@ -239,6 +252,7 @@ bool CompositorWin7::setupVoutWindow(vout_window_t *p_wnd)
p_wnd->display.x11 = nullptr;
p_wnd->ops = &ops;
p_wnd->info.has_double_click = true;
+ m_voutWindow = p_wnd;
return true;
}
@@ -252,16 +266,16 @@ bool CompositorWin7::eventFilter(QObject*, QEvent* ev)
case QEvent::Move:
case QEvent::Resize:
case QEvent::ApplicationStateChange:
- m_stable->setGeometry(m_qmlView->geometry());
+ m_videoWidget->setGeometry(m_qmlView->geometry());
resetVideoZOrder();
break;
case QEvent::WindowStateChange:
if (m_qmlView->windowStates() & Qt::WindowMinimized)
- m_stable->hide();
+ m_videoWidget->hide();
else
{
- m_stable->show();
- m_stable->setGeometry(m_qmlView->geometry());
+ m_videoWidget->show();
+ m_videoWidget->setGeometry(m_qmlView->geometry());
resetVideoZOrder();
}
break;
@@ -270,11 +284,11 @@ bool CompositorWin7::eventFilter(QObject*, QEvent* ev)
resetVideoZOrder();
break;
case QEvent::Show:
- m_stable->show();
+ m_videoWidget->show();
resetVideoZOrder();
break;
case QEvent::Hide:
- m_stable->hide();
+ m_videoWidget->hide();
break;
default:
break;
@@ -302,6 +316,97 @@ void CompositorWin7::resetVideoZOrder()
);
}
+
+Compositor::VideoSurfaceTarget CompositorWin7::getSupportedVideoSurfaceModes() const
+{
+ return static_cast<VideoSurfaceTarget>(VideoSurfaceTarget::EMBED | VideoSurfaceTarget::WINDOWED | VideoSurfaceTarget::FULLSCREEN);
+}
+
+void CompositorWin7::setVideoSurface(VideoSurfaceTarget target, QVariant targetParam)
+{
+ assert(m_stable != nullptr);
+ switch (m_currentVideoSurface)
+ {
+ case VideoSurfaceTarget::EMBED:
+ //no longer respond to events from the QML surface
+ m_videoSurfaceProvider->setVideoEmbed(false);
+ m_videoWindowHandler->setWindow(nullptr);
+ m_videoWidgetLayout->removeWidget(m_stable);
+ m_stable->setParent(nullptr);
+ msg_Dbg(m_intf, "disable EMBED video surface");
+ break;
+ case VideoSurfaceTarget::FULLSCREEN:
+ case VideoSurfaceTarget::WINDOWED:
+ assert(m_detachedVideoWindow);
+ m_videoWindowHandler->setWindow(nullptr);
+ ((QHBoxLayout*)m_detachedVideoWindow->layout())->removeWidget(m_stable);
+ //reset parent, otherwise m_stable is still attached to m_detachedVideoWindow
+ m_stable->setParent(nullptr);
+ m_detachedVideoWindow.reset();
+ msg_Dbg(m_intf, "disable WINDOWED video surface");
+ break;
+ default:
+ //N/A
+ break;
+ }
+
+ switch (target)
+ {
+ case VideoSurfaceTarget::EMBED:
+ {
+ m_videoWidgetLayout->addWidget(m_stable);
+ m_videoWindowHandler->setWindow(m_qmlView.get());
+ VideoSurfaceProvider* videoSurface = m_videoSurfaceProvider.get();
+ videoSurface->setVideoEmbed(true);
+ }
+ break;
+ case VideoSurfaceTarget::FULLSCREEN:
+ case VideoSurfaceTarget::WINDOWED:
+ {
+ m_detachedVideoWindow = std::make_unique<DetachedVideoWindow>(m_intf, m_voutWindow);
+ QHBoxLayout* detachedVideoWidgetlayout = new QHBoxLayout();
+ detachedVideoWidgetlayout->setContentsMargins( 0, 0, 0, 0 );
+ m_detachedVideoWindow->setLayout(detachedVideoWidgetlayout);
+ detachedVideoWidgetlayout->addWidget(m_stable);
+
+ connect(m_detachedVideoWindow.get(), &DetachedVideoWindow::windowClosed,
+ this, [this]() {
+ this->setVideoSurface(vlc::Compositor::VideoSurfaceTarget::EMBED);
+ }, Qt::QueuedConnection);
+
+ if (target == VideoSurfaceTarget::FULLSCREEN)
+ {
+ QString screename = targetParam.toString();
+ //ensure that the window is actually created
+ m_detachedVideoWindow->winId();
+ m_detachedVideoWindow->showFSOnScreen(screename, m_qmlView.get());
+ }
+ else
+ {
+ m_detachedVideoWindow->resize(m_stable->size());
+ m_detachedVideoWindow->show();
+ }
+ m_videoWindowHandler->setWindow(m_detachedVideoWindow->windowHandle());
+
+ QSize windowSize = m_detachedVideoWindow->size() * m_detachedVideoWindow->devicePixelRatioF();
+ VideoSurfaceProvider* videoSurface = m_videoSurfaceProvider.get();
+ QMetaObject::invokeMethod(videoSurface, [videoSurface, windowSize]() {
+ videoSurface->onSurfaceSizeChanged(windowSize);
+ }, Qt::QueuedConnection);
+
+ break;
+ }
+ default:
+ //N/A
+ break;
+ }
+
+ m_currentVideoSurface = target;
+ m_currentVideoSurfaceParam = targetParam;
+ emit videoSurfaceChanged(m_currentVideoSurface, m_currentVideoSurfaceParam);
+}
+
+
Win7NativeEventFilter::Win7NativeEventFilter(QObject* parent)
: QObject(parent)
{
diff --git a/modules/gui/qt/maininterface/compositor_win7.hpp b/modules/gui/qt/maininterface/compositor_win7.hpp
index a62650dc8b..b658dea193 100644
--- a/modules/gui/qt/maininterface/compositor_win7.hpp
+++ b/modules/gui/qt/maininterface/compositor_win7.hpp
@@ -21,10 +21,12 @@
#include "compositor_dummy.hpp"
#include "videosurface.hpp"
#include "video_window_handler.hpp"
+#include "detached_video_window.hpp"
#include <QAbstractNativeEventFilter>
#include <memory>
class WinTaskbarWidget;
+class QMainWindow;
namespace vlc {
@@ -51,6 +53,9 @@ public:
virtual MainInterface *makeMainInterface() override;
virtual bool setupVoutWindow(vout_window_t*) override;
+ Compositor::VideoSurfaceTarget getSupportedVideoSurfaceModes() const override;
+ void setVideoSurface(VideoSurfaceTarget target, QVariant targetParam = QVariant()) override;
+
protected:
bool eventFilter(QObject *obj, QEvent *ev) override;
@@ -67,16 +72,23 @@ private slots:
void resetVideoZOrder();
private:
+ QWidget* m_videoWidget = nullptr;
+ QVBoxLayout* m_videoWidgetLayout = nullptr;
QWidget* m_stable = nullptr;
std::unique_ptr<QQuickView> m_qmlView;
std::unique_ptr<VideoWindowHandler> m_videoWindowHandler;
- std::unique_ptr<VideoSurfaceProvider> m_qmlVideoSurfaceProvider;
+ std::unique_ptr<VideoSurfaceProvider> m_videoSurfaceProvider;
WinTaskbarWidget* m_taskbarWidget = nullptr;
Win7NativeEventFilter* m_nativeEventFilter = nullptr;
HWND m_qmlWindowHWND = nullptr;
HWND m_videoWindowHWND = nullptr;
+ vout_window_t *m_voutWindow = nullptr;
+
+ std::unique_ptr<DetachedVideoWindow> m_detachedVideoWindow;;
+ VideoSurfaceTarget m_currentVideoSurface = VideoSurfaceTarget::EMBED;
+ QVariant m_currentVideoSurfaceParam;
};
}
--
2.25.1
More information about the vlc-devel
mailing list