[vlc-devel] [PATCH 14/16] qt: extract interface window handling from MainInterface
Pierre Lamot
pierre at videolabs.io
Thu Aug 6 09:44:00 CEST 2020
---
modules/gui/qt/Makefile.am | 3 +
.../gui/qt/maininterface/compositor_dcomp.cpp | 8 +-
.../gui/qt/maininterface/compositor_dcomp.hpp | 2 +
.../gui/qt/maininterface/compositor_dummy.cpp | 3 +
.../interface_window_handler.cpp | 229 ++++++++++++++++++
.../interface_window_handler.hpp | 72 ++++++
.../gui/qt/maininterface/main_interface.cpp | 142 +----------
.../gui/qt/maininterface/main_interface.hpp | 90 ++++++-
.../qt/maininterface/main_interface_win32.cpp | 111 +++++++--
.../qt/maininterface/main_interface_win32.hpp | 13 +-
.../qt/maininterface/video_window_handler.cpp | 37 +--
11 files changed, 512 insertions(+), 198 deletions(-)
create mode 100644 modules/gui/qt/maininterface/interface_window_handler.cpp
create mode 100644 modules/gui/qt/maininterface/interface_window_handler.hpp
diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index 5ce6527b44..b5bcc03f73 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -118,6 +118,8 @@ libqt_plugin_la_SOURCES = \
gui/qt/maininterface/compositor.cpp \
gui/qt/maininterface/compositor_dummy.hpp \
gui/qt/maininterface/compositor_dummy.cpp \
+ gui/qt/maininterface/interface_window_handler.cpp \
+ gui/qt/maininterface/interface_window_handler.hpp \
gui/qt/maininterface/main_interface.cpp \
gui/qt/maininterface/main_interface.hpp \
gui/qt/maininterface/mainui.cpp \
@@ -288,6 +290,7 @@ nodist_libqt_plugin_la_SOURCES = \
gui/qt/dialogs/sout/sout_widgets.moc.cpp \
gui/qt/dialogs/toolbar/toolbareditor.moc.cpp \
gui/qt/maininterface/compositor_dummy.moc.cpp \
+ gui/qt/maininterface/interface_window_handler.moc.cpp \
gui/qt/maininterface/main_interface.moc.cpp \
gui/qt/maininterface/mainui.moc.cpp \
gui/qt/maininterface/videosurface.moc.cpp \
diff --git a/modules/gui/qt/maininterface/compositor_dcomp.cpp b/modules/gui/qt/maininterface/compositor_dcomp.cpp
index 667da18d0d..2405a3177a 100644
--- a/modules/gui/qt/maininterface/compositor_dcomp.cpp
+++ b/modules/gui/qt/maininterface/compositor_dcomp.cpp
@@ -36,7 +36,7 @@
#include <qpa/qplatformnativeinterface.h>
#include "compositor_dcomp_error.hpp"
-
+#include "maininterface/interface_window_handler.hpp"
namespace vlc {
@@ -223,9 +223,15 @@ MainInterface* CompositorDirectComposition::makeMainInterface()
m_videoWindowHandler = std::make_unique<VideoWindowHandler>(m_intf, m_rootWindow);
m_videoWindowHandler->setWindow( m_rootWindow->windowHandle() );
+ m_interfaceWindowHandler = new InterfaceWindowHandlerWin32(m_intf, m_rootWindow, m_rootWindow->windowHandle(), m_rootWindow);
+
m_qmlVideoSurfaceProvider = std::make_unique<VideoSurfaceProvider>();
m_rootWindow->setVideoSurfaceProvider(m_qmlVideoSurfaceProvider.get());
+ connect(m_qmlVideoSurfaceProvider.get(), &VideoSurfaceProvider::hasVideoChanged,
+ m_interfaceWindowHandler, &InterfaceWindowHandlerWin32::onVideoEmbedChanged);
+
+
HR(m_dcompDevice->CreateTargetForHwnd((HWND)m_rootWindow->windowHandle()->winId(), TRUE, &m_dcompTarget), "create target");
HR(m_dcompDevice->CreateVisual(&m_rootVisual), "create root visual");
HR(m_dcompTarget->SetRoot(m_rootVisual.Get()), "set root visual");
diff --git a/modules/gui/qt/maininterface/compositor_dcomp.hpp b/modules/gui/qt/maininterface/compositor_dcomp.hpp
index 51afc1843c..186de507ea 100644
--- a/modules/gui/qt/maininterface/compositor_dcomp.hpp
+++ b/modules/gui/qt/maininterface/compositor_dcomp.hpp
@@ -29,6 +29,7 @@
#include "maininterface/mainui.hpp"
#include "compositor_dcomp_uisurface.hpp"
#include "videosurface.hpp"
+#include "interface_window_handler.hpp"
#include "video_window_handler.hpp"
#include <QOpenGLContext>
@@ -68,6 +69,7 @@ private:
std::unique_ptr<MainUI> m_ui;
std::unique_ptr<VideoWindowHandler> m_videoWindowHandler;
std::unique_ptr<VideoSurfaceProvider> m_qmlVideoSurfaceProvider;
+ InterfaceWindowHandler* m_interfaceWindowHandler = nullptr;
//main window composition
HINSTANCE m_dcomp_dll = nullptr;
diff --git a/modules/gui/qt/maininterface/compositor_dummy.cpp b/modules/gui/qt/maininterface/compositor_dummy.cpp
index c645552bf7..e49ca23431 100644
--- a/modules/gui/qt/maininterface/compositor_dummy.cpp
+++ b/modules/gui/qt/maininterface/compositor_dummy.cpp
@@ -19,6 +19,7 @@
#include "maininterface/main_interface.hpp"
#include "maininterface/mainui.hpp"
+#include "maininterface/interface_window_handler.hpp"
namespace vlc {
@@ -35,6 +36,8 @@ MainInterface* CompositorDummy::makeMainInterface()
QQuickWidget* centralWidget = new QQuickWidget(m_rootWindow);
centralWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
+ new InterfaceWindowHandler(m_intf, m_rootWindow, m_rootWindow->windowHandle(), m_rootWindow);
+
MainUI* m_ui = new MainUI(m_intf, m_rootWindow, this);
m_ui->setup(centralWidget->engine());
centralWidget->setContent(QUrl(), m_ui->getComponent(), m_ui->createRootItem());
diff --git a/modules/gui/qt/maininterface/interface_window_handler.cpp b/modules/gui/qt/maininterface/interface_window_handler.cpp
new file mode 100644
index 0000000000..e7bbbc86c3
--- /dev/null
+++ b/modules/gui/qt/maininterface/interface_window_handler.cpp
@@ -0,0 +1,229 @@
+/*****************************************************************************
+ * Copyright (C) 2020 VideoLAN and AUTHORS
+ *
+ * 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 "interface_window_handler.hpp"
+#include "main_interface.hpp"
+#include <player/player_controller.hpp>
+#include <playlist/playlist_controller.hpp>
+
+InterfaceWindowHandler::InterfaceWindowHandler(intf_thread_t *_p_intf, MainInterface* mainInterface, QWindow* window, QObject *parent)
+ : QObject(parent)
+ , p_intf(_p_intf)
+ , m_window(window)
+ , m_mainInterface(mainInterface)
+{
+ assert(m_window);
+ assert(m_mainInterface);
+
+ /* */
+ m_pauseOnMinimize = var_InheritBool( p_intf, "qt-pause-minimized" );
+
+ m_window->setIcon( QApplication::windowIcon() );
+ m_window->setOpacity( var_InheritFloat( p_intf, "qt-opacity" ) );
+
+ WindowStateHolder::holdOnTop( m_window, WindowStateHolder::INTERFACE, m_mainInterface->isInterfaceAlwaysOnTop() );
+ WindowStateHolder::holdFullscreen( m_window, WindowStateHolder::INTERFACE, m_mainInterface->isInterfaceFullScreen() );
+
+ if (m_mainInterface->isHideAfterCreation())
+ {
+ //this needs to be called asynchronously
+ //otherwise QQuickWidget won't initialize properly
+ QMetaObject::invokeMethod(this, [this]() {
+ m_window->hide();
+ }, Qt::QueuedConnection, nullptr);
+ }
+
+
+ m_window->setTitle("");
+
+ if( var_InheritBool( p_intf, "qt-name-in-title" ) )
+ {
+ connect( THEMIM, &PlayerController::nameChanged, m_window, &QWindow::setTitle );
+ }
+
+ connect( m_mainInterface, &MainInterface::askBoss,
+ this, &InterfaceWindowHandler::setBoss, Qt::QueuedConnection );
+ connect( m_mainInterface, &MainInterface::askRaise,
+ this, &InterfaceWindowHandler::setRaise, Qt::QueuedConnection );
+
+ connect( m_mainInterface, &MainInterface::interfaceAlwaysOnTopChanged,
+ this, &InterfaceWindowHandler::setInterfaceAlwaysOnTop);
+
+ connect( m_mainInterface, &MainInterface::interfaceFullScreenChanged,
+ this, &InterfaceWindowHandler::setInterfaceFullScreen);
+
+ connect( m_mainInterface, &MainInterface::toggleWindowVisibility,
+ this, &InterfaceWindowHandler::toggleWindowVisiblity);
+
+ connect( m_mainInterface, &MainInterface::setInterfaceVisibible,
+ this, &InterfaceWindowHandler::setInterfaceVisible);
+
+ m_window->installEventFilter(this);
+}
+
+InterfaceWindowHandler::~InterfaceWindowHandler()
+{
+ m_window->removeEventFilter(this);
+ WindowStateHolder::holdOnTop( m_window, WindowStateHolder::INTERFACE, false );
+ WindowStateHolder::holdFullscreen( m_window, WindowStateHolder::INTERFACE, false );
+}
+
+bool InterfaceWindowHandler::eventFilter(QObject*, QEvent* event)
+{
+ if( event->type() == QEvent::WindowStateChange )
+ {
+ QWindowStateChangeEvent *windowStateChangeEvent = static_cast<QWindowStateChangeEvent*>(event);
+ Qt::WindowStates newState = m_window->windowStates();
+ Qt::WindowStates oldState = windowStateChangeEvent->oldState();
+
+ /* b_maximizedView stores if the window was maximized before entering fullscreen.
+ * It is set when entering maximized mode, unset when leaving it to normal mode.
+ * Upon leaving full screen, if b_maximizedView is set,
+ * the window should be maximized again. */
+ if( newState & Qt::WindowMaximized &&
+ !( oldState & Qt::WindowMaximized ) )
+ m_maximizedView = true;
+
+ if( !( newState & Qt::WindowMaximized ) &&
+ oldState & Qt::WindowMaximized ) //FIXME && !b_videoFullScreen )
+ m_maximizedView = false;
+
+ if( !( newState & Qt::WindowFullScreen ) &&
+ oldState & Qt::WindowFullScreen &&
+ m_maximizedView )
+ {
+ m_window->showMaximized();
+ return false;
+ }
+
+ if( newState & Qt::WindowMinimized )
+ {
+
+ m_hasPausedWhenMinimized = false;
+
+ if( THEMIM->getPlayingState() == PlayerController::PLAYING_STATE_PLAYING &&
+ THEMIM->hasVideoOutput() && !THEMIM->hasAudioVisualization() &&
+ m_pauseOnMinimize )
+ {
+ m_hasPausedWhenMinimized = true;
+ THEMPL->pause();
+ }
+ }
+ else if( oldState & Qt::WindowMinimized && !( newState & Qt::WindowMinimized ) )
+ {
+ if( m_hasPausedWhenMinimized )
+ {
+ THEMPL->play();
+ }
+ }
+ }
+
+ return false;
+}
+
+void InterfaceWindowHandler::onVideoEmbedChanged(bool embed)
+{
+ if (embed)
+ {
+ m_interfaceGeometry = m_window->geometry();
+ }
+ else if (!m_interfaceGeometry.isNull())
+ {
+ m_window->setGeometry(m_interfaceGeometry);
+ m_interfaceGeometry = QRect();
+ }
+}
+
+
+void InterfaceWindowHandler::toggleWindowVisiblity()
+{
+ switch ( m_window->visibility() )
+ {
+ case QWindow::Hidden:
+ /* If hidden, show it */
+ m_window->show();
+ m_window->requestActivate();
+ break;
+ case QWindow::Minimized:
+ m_window->showNormal();
+ m_window->requestActivate();
+ break;
+ default:
+ m_window->hide();
+ break;
+ }
+}
+
+
+void InterfaceWindowHandler::setInterfaceVisible(bool visible)
+{
+ if (visible)
+ {
+ switch ( m_window->visibility() )
+ {
+ case QWindow::Hidden:
+ m_window->show();
+ break;
+ case QWindow::Minimized:
+ m_window->showNormal();
+ break;
+ default:
+ break;
+ }
+ m_window->requestActivate();
+ }
+ else
+ {
+ m_window->hide();
+ }
+}
+
+
+void InterfaceWindowHandler::setFullScreen( bool fs )
+{
+ WindowStateHolder::holdFullscreen(m_window, WindowStateHolder::INTERFACE, fs);
+}
+
+void InterfaceWindowHandler::setInterfaceFullScreen( bool fs )
+{
+ setFullScreen(fs);
+ emit interfaceFullScreenChanged( fs );
+}
+
+void InterfaceWindowHandler::setRaise()
+{
+ m_window->requestActivate();
+ m_window->raise();
+}
+
+void InterfaceWindowHandler::setBoss()
+{
+ THEMPL->pause();
+ if( m_mainInterface->getSysTray() )
+ {
+ m_window->hide();
+ }
+ else
+ {
+ m_window->showMinimized();
+ }
+}
+
+void InterfaceWindowHandler::setInterfaceAlwaysOnTop( bool on_top )
+{
+ WindowStateHolder::holdOnTop(m_window, WindowStateHolder::INTERFACE, on_top);
+}
diff --git a/modules/gui/qt/maininterface/interface_window_handler.hpp b/modules/gui/qt/maininterface/interface_window_handler.hpp
new file mode 100644
index 0000000000..dcb2f43680
--- /dev/null
+++ b/modules/gui/qt/maininterface/interface_window_handler.hpp
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * Copyright (C) 2020 VideoLAN and AUTHORS
+ *
+ * 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 INTERFACEWINDOWHANDLER_H
+#define INTERFACEWINDOWHANDLER_H
+
+#include "qt.hpp"
+
+#include <QObject>
+#include <QWindow>
+
+class MainInterface;
+class InterfaceWindowHandler : public QObject
+{
+ Q_OBJECT
+public:
+ explicit InterfaceWindowHandler(intf_thread_t *_p_intf, MainInterface* mainInterface, QWindow* window, QObject *parent = nullptr);
+ virtual ~InterfaceWindowHandler();
+
+public slots:
+ virtual void onVideoEmbedChanged( bool embed );
+
+protected slots:
+ virtual void setFullScreen( bool fs );
+ virtual void setInterfaceFullScreen( bool fs );
+ virtual void setInterfaceAlwaysOnTop( bool on_top );
+ virtual void toggleWindowVisiblity();
+ virtual void setInterfaceVisible(bool);
+
+
+ virtual void setRaise();
+ virtual void setBoss();
+
+ virtual bool eventFilter(QObject*, QEvent* event) override;
+
+signals:
+ void minimalViewToggled( bool );
+ void fullscreenInterfaceToggled( bool );
+ void interfaceAlwaysOnTopChanged(bool);
+ void interfaceFullScreenChanged(bool);
+
+protected:
+ intf_thread_t* p_intf = nullptr;
+ QWindow* m_window = nullptr;
+ MainInterface* m_mainInterface = nullptr;
+
+ bool m_hasPausedWhenMinimized = false;
+
+ bool m_isWindowTiled = false;
+
+ bool m_pauseOnMinimize ;
+ bool m_maximizedView = false;
+ bool m_hideAfterCreation = false; // --qt-start-minimized
+
+ QRect m_interfaceGeometry;
+};
+
+#endif // INTERFACEWINDOWHANDLER_H
diff --git a/modules/gui/qt/maininterface/main_interface.cpp b/modules/gui/qt/maininterface/main_interface.cpp
index 0542dc6aed..0a01208e19 100644
--- a/modules/gui/qt/maininterface/main_interface.cpp
+++ b/modules/gui/qt/maininterface/main_interface.cpp
@@ -109,10 +109,7 @@ MainInterface::MainInterface(intf_thread_t *_p_intf , QWidget* parent, Qt::Windo
b_hideAfterCreation = false; // --qt-start-minimized
playlistVisible = false;
b_interfaceFullScreen= false;
- b_hasPausedWhenMinimized = false;
i_kc_offset = false;
- b_maximizedView = false;
- b_isWindowTiled = false;
/**
* Configuration and settings
@@ -126,8 +123,6 @@ MainInterface::MainInterface(intf_thread_t *_p_intf , QWidget* parent, Qt::Windo
i_notificationSetting = var_InheritInteger( p_intf, "qt-notification" );
/* */
- b_pauseOnMinimize = var_InheritBool( p_intf, "qt-pause-minimized" );
-
m_intfUserScaleFactor = var_InheritFloat(p_intf, "qt-interface-scale");
winId(); //force window creation
QWindow* window = windowHandle();
@@ -157,17 +152,10 @@ MainInterface::MainInterface(intf_thread_t *_p_intf , QWidget* parent, Qt::Windo
/**************************
* UI and Widgets design
**************************/
- setWindowTitle("");
/* Main settings */
setFocusPolicy( Qt::StrongFocus );
setAcceptDrops( true );
- setWindowRole( "vlc-main" );
- setWindowIcon( QApplication::windowIcon() );
- setWindowOpacity( var_InheritFloat( p_intf, "qt-opacity" ) );
- if ( b_interfaceOnTop )
- setWindowFlags( windowFlags() | Qt::WindowStaysOnTopHint );
-
/*********************************
* Create the Systray Management *
@@ -184,18 +172,12 @@ MainInterface::MainInterface(intf_thread_t *_p_intf , QWidget* parent, Qt::Windo
**/
/* Main Interface statusbar */
/* and title of the Main Interface*/
- if( var_InheritBool( p_intf, "qt-name-in-title" ) )
- {
- connect( THEMIM, &PlayerController::nameChanged, this, &MainInterface::setWindowTitle );
- }
connect( THEMIM, &PlayerController::inputChanged, this, &MainInterface::onInputChanged );
/* END CONNECTS ON IM */
/* VideoWidget connects for asynchronous calls */
connect( this, &MainInterface::askToQuit, THEDP, &DialogsProvider::quit, Qt::QueuedConnection );
- connect( this, &MainInterface::askBoss, this, &MainInterface::setBoss, Qt::QueuedConnection );
- connect( this, &MainInterface::askRaise, this, &MainInterface::setRaise, Qt::QueuedConnection );
connect( THEDP, &DialogsProvider::toolBarConfUpdated, this, &MainInterface::toolBarConfUpdated );
@@ -223,9 +205,6 @@ MainInterface::MainInterface(intf_thread_t *_p_intf , QWidget* parent, Qt::Windo
widget->setStyleSheet("background-color: transparent");
setCentralWidget(widget);
-
- setVisible( !b_hideAfterCreation );
-
computeMinimumSize();
}
@@ -274,7 +253,6 @@ void MainInterface::computeMinimumSize()
void MainInterface::reloadPrefs()
{
i_notificationSetting = var_InheritInteger( p_intf, "qt-notification" );
- b_pauseOnMinimize = var_InheritBool( p_intf, "qt-pause-minimized" );
}
@@ -365,17 +343,6 @@ void MainInterface::setShowRemainingTime( bool show )
void MainInterface::setInterfaceAlwaysOnTop( bool on_top )
{
b_interfaceOnTop = on_top;
- Qt::WindowFlags oldflags = windowFlags(), newflags;
-
- if( on_top )
- newflags = oldflags | Qt::WindowStaysOnTopHint;
- else
- newflags = oldflags & ~Qt::WindowStaysOnTopHint;
- if( newflags != oldflags ) //FIXME && !b_videoFullScreen )
- {
- setWindowFlags( newflags );
- show(); /* necessary to apply window flags */
- }
emit interfaceAlwaysOnTopChanged(on_top);
}
@@ -450,33 +417,12 @@ void MainInterface::createSystray()
this, &MainInterface::updateSystrayTooltipStatus );
}
-void MainInterface::toggleUpdateSystrayMenuWhenVisible()
-{
- hide();
-}
-
/**
* Updates the Systray Icon's menu and toggle the main interface
*/
void MainInterface::toggleUpdateSystrayMenu()
{
- /* If hidden, show it */
- if( isHidden() )
- {
- show();
- activateWindow();
- }
- else if( isMinimized() )
- {
- /* Minimized */
- showNormal();
- activateWindow();
- }
- else
- {
- /* Visible (possibly under other windows) */
- toggleUpdateSystrayMenuWhenVisible();
- }
+ emit toggleWindowVisibility();
if( sysTray )
VLCMenuBar::updateSystrayMenu( this, p_intf );
}
@@ -484,19 +430,14 @@ void MainInterface::toggleUpdateSystrayMenu()
/* First Item of the systray menu */
void MainInterface::showUpdateSystrayMenu()
{
- if( isHidden() )
- show();
- if( isMinimized() )
- showNormal();
- activateWindow();
-
+ emit setInterfaceVisibible(true);
VLCMenuBar::updateSystrayMenu( this, p_intf );
}
/* First Item of the systray menu */
void MainInterface::hideUpdateSystrayMenu()
{
- hide();
+ emit setInterfaceVisibible(false);
VLCMenuBar::updateSystrayMenu( this, p_intf );
}
@@ -557,57 +498,6 @@ void MainInterface::updateSystrayTooltipStatus( PlayerController::PlayingState )
VLCMenuBar::updateSystrayMenu( this, p_intf );
}
-void MainInterface::changeEvent(QEvent *event)
-{
- if( event->type() == QEvent::WindowStateChange )
- {
- QWindowStateChangeEvent *windowStateChangeEvent = static_cast<QWindowStateChangeEvent*>(event);
- Qt::WindowStates newState = windowState();
- Qt::WindowStates oldState = windowStateChangeEvent->oldState();
-
- /* b_maximizedView stores if the window was maximized before entering fullscreen.
- * It is set when entering maximized mode, unset when leaving it to normal mode.
- * Upon leaving full screen, if b_maximizedView is set,
- * the window should be maximized again. */
- if( newState & Qt::WindowMaximized &&
- !( oldState & Qt::WindowMaximized ) )
- b_maximizedView = true;
-
- if( !( newState & Qt::WindowMaximized ) &&
- oldState & Qt::WindowMaximized ) //FIXME && !b_videoFullScreen )
- b_maximizedView = false;
-
- if( !( newState & Qt::WindowFullScreen ) &&
- oldState & Qt::WindowFullScreen &&
- b_maximizedView )
- {
- showMaximized();
- return;
- }
-
- if( newState & Qt::WindowMinimized )
- {
- b_hasPausedWhenMinimized = false;
-
- if( THEMIM->getPlayingState() == PlayerController::PLAYING_STATE_PLAYING &&
- THEMIM->hasVideoOutput() && !THEMIM->hasAudioVisualization() &&
- b_pauseOnMinimize )
- {
- b_hasPausedWhenMinimized = true;
- THEMPL->pause();
- }
- }
- else if( oldState & Qt::WindowMinimized && !( newState & Qt::WindowMinimized ) )
- {
- if( b_hasPausedWhenMinimized )
- {
- THEMPL->play();
- }
- }
- }
-
- QWidget::changeEvent(event);
-}
/************************************************************************
* D&D Events
@@ -733,18 +623,9 @@ void MainInterface::closeEvent( QCloseEvent *e )
}
}
-void MainInterface::setFullScreen( bool fs )
-{
- if( fs )
- setWindowState( windowState() | Qt::WindowFullScreen );
- else
- setWindowState( windowState() & ~Qt::WindowFullScreen );
-}
-
void MainInterface::setInterfaceFullScreen( bool fs )
{
b_interfaceFullScreen = fs;
- setFullScreen(fs);
emit interfaceFullScreenChanged( fs );
}
@@ -758,18 +639,6 @@ void MainInterface::emitBoss()
{
emit askBoss();
}
-void MainInterface::setBoss()
-{
- THEMPL->pause();
- if( sysTray )
- {
- hide();
- }
- else
- {
- showMinimized();
- }
-}
void MainInterface::emitShow()
{
@@ -785,11 +654,6 @@ void MainInterface::emitRaise()
{
emit askRaise();
}
-void MainInterface::setRaise()
-{
- activateWindow();
- raise();
-}
VLCVarChoiceModel* MainInterface::getExtraInterfaces()
{
diff --git a/modules/gui/qt/maininterface/main_interface.hpp b/modules/gui/qt/maininterface/main_interface.hpp
index 6fedd3a3f3..6b7e2fd045 100644
--- a/modules/gui/qt/maininterface/main_interface.hpp
+++ b/modules/gui/qt/maininterface/main_interface.hpp
@@ -58,6 +58,83 @@ class StandardPLPanel;
struct vout_window_t;
class VideoSurfaceProvider;
+class WindowStateHolder : public QObject
+{
+public:
+ enum Source {
+ INTERFACE = 1,
+ VIDEO = 2,
+ };
+
+ static bool holdFullscreen( QWindow* window, Source source, bool hold )
+ {
+ QVariant prop = window->property("__windowFullScreen");
+ bool ok = false;
+ unsigned fullscreenCounter = prop.toUInt(&ok);
+ if (!ok)
+ fullscreenCounter = 0;
+
+ if (hold)
+ fullscreenCounter |= source;
+ else
+ fullscreenCounter &= ~source;
+
+ Qt::WindowStates oldflags = window->windowStates();
+ Qt::WindowStates newflags;
+
+ if( fullscreenCounter != 0 )
+ newflags = oldflags | Qt::WindowFullScreen;
+ else
+ newflags = oldflags & ~Qt::WindowFullScreen;
+
+ if( newflags != oldflags )
+ {
+ window->setWindowStates( newflags );
+ }
+
+ window->setProperty("__windowFullScreen", QVariant::fromValue(fullscreenCounter));
+
+ return fullscreenCounter != 0;
+ }
+
+
+ static bool holdOnTop( QWindow* window, Source source, bool hold )
+ {
+ QVariant prop = window->property("__windowOnTop");
+ bool ok = false;
+ unsigned onTopCounter = prop.toUInt(&ok);
+ if (!ok)
+ onTopCounter = 0;
+
+ if (hold)
+ onTopCounter |= source;
+ else
+ onTopCounter &= ~source;
+
+ Qt::WindowStates oldStates = window->windowStates();
+ Qt::WindowFlags oldflags = window->flags();
+ Qt::WindowFlags newflags;
+
+ if( onTopCounter != 0 )
+ newflags = oldflags | Qt::WindowStaysOnTopHint;
+ else
+ newflags = oldflags & ~Qt::WindowStaysOnTopHint;
+ if( newflags != oldflags )
+ {
+
+ window->setFlags( newflags );
+ window->show(); /* necessary to apply window flags */
+ //workaround: removing onTop state might drop fullscreen state
+ window->setWindowStates(oldStates);
+ }
+
+ window->setProperty("__windowOnTop", QVariant::fromValue(onTopCounter));
+
+ return onTopCounter != 0;
+ }
+
+};
+
class MainInterface : public QVLCMW
{
Q_OBJECT
@@ -99,6 +176,7 @@ public:
bool isPlaylistDocked() { return b_playlistDocked; }
bool isPlaylistVisible() { return playlistVisible; }
bool isInterfaceAlwaysOnTop() { return b_interfaceOnTop; }
+ inline bool isHideAfterCreation() const { return b_hideAfterCreation; }
inline bool isShowRemainingTime() const { return m_showRemainingTime; }
inline float getIntfScaleFactor() const { return m_intfScaleFactor; }
@@ -108,13 +186,11 @@ public:
protected:
void dropEventPlay( QDropEvent* event, bool b_play );
- void changeEvent( QEvent * ) Q_DECL_OVERRIDE;
void dropEvent( QDropEvent *) Q_DECL_OVERRIDE;
void dragEnterEvent( QDragEnterEvent * ) Q_DECL_OVERRIDE;
void dragMoveEvent( QDragMoveEvent * ) Q_DECL_OVERRIDE;
void dragLeaveEvent( QDragLeaveEvent * ) Q_DECL_OVERRIDE;
void closeEvent( QCloseEvent *) Q_DECL_OVERRIDE;
- virtual void toggleUpdateSystrayMenuWhenVisible();
protected:
/* Systray */
@@ -160,9 +236,6 @@ protected:
bool b_playlistDocked;
bool b_interfaceFullScreen;
bool b_interfaceOnTop; ///keep UI on top
- bool b_pauseOnMinimize;
- bool b_maximizedView;
- bool b_isWindowTiled;
#ifdef QT5_HAS_WAYLAND
bool b_hasWayland;
#endif
@@ -170,8 +243,6 @@ protected:
/* States */
bool playlistVisible; ///< Is the playlist visible ?
- bool b_hasPausedWhenMinimized;
-
static const Qt::Key kc[10]; /* easter eggs */
int i_kc_offset;
@@ -202,9 +273,6 @@ protected slots:
void showBuffering( float );
- void setBoss();
- void setRaise();
- void setFullScreen( bool );
void onInputChanged( bool );
void updateIntfScaleFactor();
@@ -213,6 +281,8 @@ protected slots:
signals:
void minimalViewToggled( bool );
void fullscreenInterfaceToggled( bool );
+ void setInterfaceVisibible(bool );
+ void toggleWindowVisibility();
void askToQuit();
void askShow();
void askBoss();
diff --git a/modules/gui/qt/maininterface/main_interface_win32.cpp b/modules/gui/qt/maininterface/main_interface_win32.cpp
index 28a826581d..a4c47cb9cc 100644
--- a/modules/gui/qt/maininterface/main_interface_win32.cpp
+++ b/modules/gui/qt/maininterface/main_interface_win32.cpp
@@ -410,32 +410,101 @@ bool MainInterfaceWin32::nativeEvent(const QByteArray &eventType, void *message,
return false;
}
-void MainInterfaceWin32::toggleUpdateSystrayMenuWhenVisible()
+InterfaceWindowHandlerWin32::InterfaceWindowHandlerWin32(intf_thread_t *_p_intf, MainInterface* mainInterface, QWindow* window, QObject *parent)
+ : InterfaceWindowHandler(_p_intf, mainInterface, window, parent)
{
- /* check if any visible window is above vlc in the z-order,
- * but ignore the ones always on top
- * and the ones which can't be activated */
- HWND winId = WinId(this->windowHandle());
-
- WINDOWINFO wi;
- HWND hwnd;
- wi.cbSize = sizeof( WINDOWINFO );
- for( hwnd = GetNextWindow( winId, GW_HWNDPREV );
- hwnd && ( !IsWindowVisible( hwnd ) || ( GetWindowInfo( hwnd, &wi ) &&
- ( wi.dwExStyle&WS_EX_NOACTIVATE ) ) );
- hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) )
- {
- }
- if( !hwnd || !GetWindowInfo( hwnd, &wi ) || (wi.dwExStyle&WS_EX_TOPMOST) )
- hide();
- else
- activateWindow();
}
-
-
void MainInterfaceWin32::reloadPrefs()
{
p_intf->p_sys->disable_volume_keys = var_InheritBool( p_intf, "qt-disable-volume-keys" );
MainInterface::reloadPrefs();
}
+
+
+void InterfaceWindowHandlerWin32::toggleWindowVisiblity()
+{
+
+ switch ( m_window->visibility() )
+ {
+ case QWindow::Hidden:
+ /* If hidden, show it */
+ m_window->show();
+ m_window->requestActivate();
+ break;
+ case QWindow::Minimized:
+ m_window->showNormal();
+ m_window->requestActivate();
+ break;
+ default:
+ {
+ /* check if any visible window is above vlc in the z-order,
+ * but ignore the ones always on top
+ * and the ones which can't be activated */
+ HWND winId = WinId(m_window);
+
+ WINDOWINFO wi;
+ HWND hwnd;
+ wi.cbSize = sizeof( WINDOWINFO );
+ for( hwnd = GetNextWindow( winId, GW_HWNDPREV );
+ hwnd && ( !IsWindowVisible( hwnd ) || ( GetWindowInfo( hwnd, &wi ) &&
+ ( wi.dwExStyle&WS_EX_NOACTIVATE ) ) );
+ hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) )
+ {
+ }
+ if( !hwnd || !GetWindowInfo( hwnd, &wi ) || (wi.dwExStyle&WS_EX_TOPMOST) )
+ m_window->hide();
+ else
+ m_window->requestActivate();
+ }
+ break;
+ }
+
+}
+
+
+bool InterfaceWindowHandlerWin32::eventFilter(QObject* obj, QEvent* ev)
+{
+ bool ret = InterfaceWindowHandler::eventFilter(obj, ev);
+ if (ret)
+ return ret;
+
+ if (ev->type() == QEvent::Resize)
+ {
+ /*
+ * Detects if window placement is not in its normal position (ex: win7 aero snap)
+ * This function compares the normal position (non snapped) to the current position.
+ * The current position is translated from screen referential to workspace referential
+ * to workspace referential
+ */
+ m_isWindowTiled = false;
+ HWND winHwnd = WinId( m_window );
+
+ WINDOWPLACEMENT windowPlacement;
+ windowPlacement.length = sizeof( windowPlacement );
+ if ( GetWindowPlacement( winHwnd, &windowPlacement ) == 0 )
+ return ret;
+
+ if ( windowPlacement.showCmd != SW_SHOWNORMAL )
+ return ret;
+
+ HMONITOR monitor = MonitorFromWindow( winHwnd, MONITOR_DEFAULTTONEAREST );
+
+ MONITORINFO monitorInfo;
+ monitorInfo.cbSize = sizeof( monitorInfo );
+ if ( GetMonitorInfo( monitor, &monitorInfo ) == 0 )
+ return ret;
+
+ RECT windowRect;
+ if ( GetWindowRect( winHwnd, &windowRect ) == 0 )
+ return ret;
+
+ OffsetRect( &windowRect,
+ monitorInfo.rcMonitor.left - monitorInfo.rcWork.left ,
+ monitorInfo.rcMonitor.top - monitorInfo.rcWork.top );
+
+ m_isWindowTiled = ( EqualRect( &windowPlacement.rcNormalPosition, &windowRect ) == 0 );
+ }
+
+ return ret;
+}
diff --git a/modules/gui/qt/maininterface/main_interface_win32.hpp b/modules/gui/qt/maininterface/main_interface_win32.hpp
index 1cbb99d51a..422905ca52 100644
--- a/modules/gui/qt/maininterface/main_interface_win32.hpp
+++ b/modules/gui/qt/maininterface/main_interface_win32.hpp
@@ -25,6 +25,7 @@
#define MAIN_INTERFACE_WIN32_HPP
#include "maininterface/main_interface.hpp"
+#include "interface_window_handler.hpp"
#include <QAbstractNativeEventFilter>
class WinTaskbarWidget : public QObject, public QAbstractNativeEventFilter
@@ -63,11 +64,21 @@ public:
private:
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
- virtual void toggleUpdateSystrayMenuWhenVisible() override;
public slots:
virtual void reloadPrefs() override;
};
+class InterfaceWindowHandlerWin32 : public InterfaceWindowHandler
+{
+ Q_OBJECT
+public:
+ explicit InterfaceWindowHandlerWin32(intf_thread_t *_p_intf, MainInterface* mainInterface, QWindow* window, QObject *parent = nullptr);
+ virtual ~InterfaceWindowHandlerWin32() = default;
+ virtual void toggleWindowVisiblity() override;
+
+ virtual bool eventFilter(QObject*, QEvent* event) override;
+};
+
#endif // MAIN_INTERFACE_WIN32_HPP
diff --git a/modules/gui/qt/maininterface/video_window_handler.cpp b/modules/gui/qt/maininterface/video_window_handler.cpp
index c54fef03f5..10a9f66945 100644
--- a/modules/gui/qt/maininterface/video_window_handler.cpp
+++ b/modules/gui/qt/maininterface/video_window_handler.cpp
@@ -41,7 +41,13 @@ VideoWindowHandler::VideoWindowHandler(intf_thread_t* intf, MainInterface* mainI
void VideoWindowHandler::setWindow(QWindow* window)
{
+ if (m_window && m_window != window)
+ {
+ WindowStateHolder::holdOnTop(m_window, WindowStateHolder::VIDEO, false);
+ WindowStateHolder::holdFullscreen(m_window, WindowStateHolder::VIDEO, false);
+ }
m_window = window;
+ m_lastWinGeometry = m_window->geometry();
}
void VideoWindowHandler::disable()
@@ -106,8 +112,6 @@ void VideoWindowHandler::setVideoSize(unsigned int w, unsigned int 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" );
@@ -127,18 +131,15 @@ void VideoWindowHandler::setVideoFullScreen( bool fs )
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);
+ WindowStateHolder::holdFullscreen(m_window, WindowStateHolder::VIDEO, true);
}
else
{
- if (m_interface->isInterfaceFullScreen())
- m_window->setWindowStates(states | Qt::WindowFullScreen);
- else
- m_window->setWindowStates(states & ~Qt::WindowFullScreen);
+ bool hold = WindowStateHolder::holdFullscreen(m_window, WindowStateHolder::VIDEO, false);
+
#ifdef QT5_HAS_WAYLAND
if( m_lastWinScreen != NULL && !m_hasWayland )
m_window->setScreen(m_lastWinScreen);
@@ -146,8 +147,7 @@ void VideoWindowHandler::setVideoFullScreen( bool fs )
if( m_lastWinScreen != NULL )
m_window->setScreen(m_lastWinScreen);
#endif
- //FIXME m_interface->restorePosition();
- if( m_lastWinGeometry.isNull() == false )
+ if( !hold && m_lastWinGeometry.isNull() == false )
{
m_window->setGeometry( m_lastWinGeometry );
m_lastWinGeometry = QRect();
@@ -160,20 +160,5 @@ void VideoWindowHandler::setVideoFullScreen( bool fs )
* 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 */
- }
+ WindowStateHolder::holdOnTop(m_window, WindowStateHolder::VIDEO, on_top);
}
--
2.25.1
More information about the vlc-devel
mailing list