mirror of https://code.videolan.org/videolan/vlc
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:
parent
231e170918
commit
c71f0c08e2
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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 */
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue