qt: add base window classes for compositors

CompositorOffscreenWindow allows to fake making the window visible without
instantiating it

DummyRenderWindow is a simple window that doesn't draw anything, as using a bare
QWindow on Linux makes the window freeze while resizing
This commit is contained in:
Pierre Lamot 2023-03-03 14:08:53 +01:00 committed by Steve Lhomme
parent 231e170918
commit c71f0c08e2
4 changed files with 252 additions and 0 deletions

View File

@ -164,6 +164,8 @@ libqt_plugin_la_SOURCES = \
gui/qt/dialogs/playlists/playlists.cpp gui/qt/dialogs/playlists/playlists.hpp \
gui/qt/maininterface/compositor.hpp \
gui/qt/maininterface/compositor.cpp \
gui/qt/maininterface/compositor_common.hpp \
gui/qt/maininterface/compositor_common.cpp \
gui/qt/maininterface/compositor_dummy.hpp \
gui/qt/maininterface/compositor_dummy.cpp \
gui/qt/maininterface/interface_window_handler.cpp \
@ -440,6 +442,7 @@ nodist_libqt_plugin_la_SOURCES = \
gui/qt/dialogs/toolbar/controlbar_profile_model.moc.cpp \
gui/qt/dialogs/playlists/playlists.moc.cpp \
gui/qt/maininterface/compositor.moc.cpp \
gui/qt/maininterface/compositor_common.moc.cpp \
gui/qt/maininterface/compositor_dummy.moc.cpp \
gui/qt/maininterface/interface_window_handler.moc.cpp \
gui/qt/maininterface/mainctx.moc.cpp \

View File

@ -0,0 +1,172 @@
/*****************************************************************************
* Copyright (C) 2023 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 "compositor_common.hpp"
#include <QBackingStore>
#ifndef QT_NO_ACCESSIBILITY
#include <QAccessible>
#endif
#ifdef QT5_DECLARATIVE_PRIVATE
#include <private/qquickwindow_p.h>
#endif
using namespace vlc;
DummyRenderWindow::DummyRenderWindow(QWindow* parent)
: QWindow(parent)
{
setSurfaceType(RasterSurface);
QSurfaceFormat fmt = format();
fmt.setAlphaBufferSize(8);
setFormat(fmt);
}
QAccessibleInterface* DummyRenderWindow::accessibleRoot() const
{
#ifndef QT_NO_ACCESSIBILITY
QAccessibleInterface* iface = QAccessible::queryAccessibleInterface(
const_cast<DummyRenderWindow*>(this));
return iface;
#else
return nullptr;
#endif
}
bool DummyRenderWindow::event(QEvent* event)
{
switch (event->type() )
{
case QEvent::UpdateRequest:
render();
return true;
case QEvent::Expose:
if (isExposed())
requestUpdate();
return true;
default:
break;
}
return QWindow::event(event);
}
void DummyRenderWindow::resizeEvent(QResizeEvent* resizeEvent)
{
if (!m_backingStore)
return;
if (!m_initialized)
init();
m_backingStore->resize(resizeEvent->size());
}
void DummyRenderWindow::init()
{
if (m_initialized)
return;
m_initialized = true;
m_backingStore = new QBackingStore(this);
}
void DummyRenderWindow::render()
{
if (!m_initialized)
init();
if (!isExposed())
return;
QRect rect(0, 0, width(), height());
if (m_backingStore->size() != size())
{
m_backingStore->resize(size());
}
//note that we don't need to actually use our backing store
//drawing anything would just lead to flickering
m_backingStore->flush(QRect(0, 0, 1, 1));
return;
}
#ifdef QT5_DECLARATIVE_PRIVATE
class OffscreenWindowPrivate: public QQuickWindowPrivate
{
public:
void setVisible(bool newVisible) override {
Q_Q(QWindow);
if (visible != newVisible)
{
visible = newVisible;
q->visibleChanged(newVisible);
// this stays always invisible
visibility = newVisible ? QWindow::Windowed : QWindow::Hidden;
q->visibilityChanged(visibility); // workaround for QTBUG-49054
}
}
};
CompositorOffscreenWindow::CompositorOffscreenWindow(QQuickRenderControl* renderControl)
: QQuickWindow(* (new OffscreenWindowPrivate()), renderControl)
{
}
static Qt::WindowState resolveWindowState(Qt::WindowStates states)
{
// No more than one of these 3 can be set
if (states & Qt::WindowMinimized)
return Qt::WindowMinimized;
if (states & Qt::WindowMaximized)
return Qt::WindowMaximized;
if (states & Qt::WindowFullScreen)
return Qt::WindowFullScreen;
// No state means "windowed" - we ignore Qt::WindowActive
return Qt::WindowNoState;
}
void CompositorOffscreenWindow::setWindowStateExt(Qt::WindowState state)
{
QWindow::setWindowState(resolveWindowState(state));
}
void CompositorOffscreenWindow::setPseudoVisible(bool visible)
{
setVisible(visible);
}
#else
CompositorOffscreenWindow::CompositorOffscreenWindow(QQuickRenderControl* renderControl)
: QQuickWindow(renderControl)
{
}
void CompositorOffscreenWindow::setWindowStateExt(Qt::WindowState state)
{
QWindow::setWindowState(state);
}
//don't set the window visible, this would create the window, and show make it actually visible
void CompositorOffscreenWindow::setPseudoVisible(bool)
{
}
#endif

View File

@ -0,0 +1,74 @@
/*****************************************************************************
* Copyright (C) 2023 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 COMPOSITOR_COMMON_HPP
#define COMPOSITOR_COMMON_HPP
#include <QWindow>
#include <QQuickWindow>
namespace vlc {
/**
* a minimal window with no content
* this may be useful on linux platform to provide a
* window which can be drawn into, using a bare QWindow
* usually freeze on resize
*/
class DummyRenderWindow : public QWindow
{
Q_OBJECT
public:
explicit DummyRenderWindow(QWindow* parent = nullptr);
virtual QAccessibleInterface *accessibleRoot() const override;
protected:
bool event(QEvent *event) override;
void resizeEvent(QResizeEvent *resizeEvent) override;
private:
void init();
void render();
QBackingStore* m_backingStore = nullptr;
bool m_initialized = false;;
};
/**
* @brief The CompositorOffscreenWindow class allows to fake the visiblilty
* of the the QQuickWindow, note that this feature will only work if QT5_DECLARATIVE_PRIVATE
* are available
*/
class CompositorOffscreenWindow : public QQuickWindow
{
Q_OBJECT
public:
explicit CompositorOffscreenWindow(QQuickRenderControl* renderControl);
void setWindowStateExt(Qt::WindowState);
void setPseudoVisible(bool visible);
};
}
#endif /* COMPOSITOR_COMMON_HPP */

View File

@ -65,6 +65,7 @@ moc_headers = files(
'dialogs/playlists/playlists.hpp',
'dialogs/vlm/vlm.hpp',
'maininterface/compositor.hpp',
'maininterface/compositor_common.hpp',
'maininterface/compositor_dummy.hpp',
'maininterface/interface_window_handler.hpp',
'maininterface/mainctx.hpp',
@ -272,6 +273,8 @@ some_sources = files(
'dialogs/playlists/playlists.hpp',
'maininterface/compositor.hpp',
'maininterface/compositor.cpp',
'maininterface/compositor_common.hpp',
'maininterface/compositor_common.cpp',
'maininterface/compositor_dummy.hpp',
'maininterface/compositor_dummy.cpp',
'maininterface/interface_window_handler.cpp',