Implement DesktopThumbnailItem as a collection of window thumbnails
The main motivation behind this change is to refactor scene code in order to allow us set WindowItem visibility upfront before compositing starts.
This commit is contained in:
parent
96e82a3631
commit
953cf452a3
13 changed files with 58 additions and 174 deletions
|
@ -121,8 +121,6 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene)
|
|||
, fullscreen_effect(nullptr)
|
||||
, m_compositor(compositor)
|
||||
, m_scene(scene)
|
||||
, m_desktopRendering(false)
|
||||
, m_currentRenderedDesktop(0)
|
||||
, m_effectLoader(new EffectLoader(this))
|
||||
, m_trackingCursorChanges(0)
|
||||
{
|
||||
|
@ -376,22 +374,6 @@ void EffectsHandlerImpl::paintScreen(int mask, const QRegion ®ion, ScreenPain
|
|||
}
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::paintDesktop(int desktop, int mask, QRegion region, ScreenPaintData &data)
|
||||
{
|
||||
if (desktop < 1 || desktop > numberOfDesktops()) {
|
||||
return;
|
||||
}
|
||||
m_currentRenderedDesktop = desktop;
|
||||
m_desktopRendering = true;
|
||||
// save the paint screen iterator
|
||||
EffectsIterator savedIterator = m_currentPaintScreenIterator;
|
||||
m_currentPaintScreenIterator = m_activeEffects.constBegin();
|
||||
effects->paintScreen(mask, region, data);
|
||||
// restore the saved iterator
|
||||
m_currentPaintScreenIterator = savedIterator;
|
||||
m_desktopRendering = false;
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::postPaintScreen()
|
||||
{
|
||||
if (m_currentPaintScreenIterator != m_activeEffects.constEnd()) {
|
||||
|
|
|
@ -61,10 +61,6 @@ public:
|
|||
~EffectsHandlerImpl() override;
|
||||
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
||||
/**
|
||||
* Special hook to perform a paintScreen but just with the windows on @p desktop.
|
||||
*/
|
||||
void paintDesktop(int desktop, int mask, QRegion region, ScreenPaintData &data);
|
||||
void postPaintScreen() override;
|
||||
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||
void paintWindow(EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data) override;
|
||||
|
@ -204,21 +200,6 @@ public:
|
|||
*/
|
||||
bool blocksDirectScanout() const;
|
||||
|
||||
/**
|
||||
* @returns Whether we are currently in a desktop rendering process triggered by paintDesktop hook
|
||||
*/
|
||||
bool isDesktopRendering() const
|
||||
{
|
||||
return m_desktopRendering;
|
||||
}
|
||||
/**
|
||||
* @returns the desktop currently being rendered in the paintDesktop hook.
|
||||
*/
|
||||
int currentRenderedDesktop() const
|
||||
{
|
||||
return m_currentRenderedDesktop;
|
||||
}
|
||||
|
||||
KWaylandServer::Display *waylandDisplay() const override;
|
||||
|
||||
bool animationsSupported() const override;
|
||||
|
@ -367,8 +348,6 @@ private:
|
|||
QHash<QByteArray, qulonglong> m_managedProperties;
|
||||
Compositor *m_compositor;
|
||||
Scene *m_scene;
|
||||
bool m_desktopRendering;
|
||||
int m_currentRenderedDesktop;
|
||||
QList<Effect *> m_grabbedMouseEffects;
|
||||
EffectLoader *m_effectLoader;
|
||||
int m_trackingCursorChanges;
|
||||
|
|
|
@ -602,11 +602,6 @@ void Scene::paintWindow(SceneWindow *w, int mask, const QRegion ®ion)
|
|||
effects->paintWindow(effectWindow(w), mask, region, data);
|
||||
}
|
||||
|
||||
void Scene::paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data)
|
||||
{
|
||||
static_cast<EffectsHandlerImpl *>(effects)->paintDesktop(desktop, mask, region, data);
|
||||
}
|
||||
|
||||
// the function that'll be eventually called by paintWindow() above
|
||||
void Scene::finalPaintWindow(EffectWindowImpl *w, int mask, const QRegion ®ion, WindowPaintData &data)
|
||||
{
|
||||
|
@ -766,14 +761,8 @@ void SceneWindow::resetPaintingEnabled()
|
|||
if (toplevel->isDeleted()) {
|
||||
disable_painting |= PAINT_DISABLED_BY_DELETE;
|
||||
}
|
||||
if (static_cast<EffectsHandlerImpl *>(effects)->isDesktopRendering()) {
|
||||
if (!toplevel->isOnDesktop(static_cast<EffectsHandlerImpl *>(effects)->currentRenderedDesktop())) {
|
||||
disable_painting |= PAINT_DISABLED_BY_DESKTOP;
|
||||
}
|
||||
} else {
|
||||
if (!toplevel->isOnCurrentDesktop()) {
|
||||
disable_painting |= PAINT_DISABLED_BY_DESKTOP;
|
||||
}
|
||||
if (!toplevel->isOnCurrentDesktop()) {
|
||||
disable_painting |= PAINT_DISABLED_BY_DESKTOP;
|
||||
}
|
||||
if (!toplevel->isOnCurrentActivity()) {
|
||||
disable_painting |= PAINT_DISABLED_BY_ACTIVITY;
|
||||
|
|
|
@ -202,8 +202,6 @@ public:
|
|||
virtual SurfaceTexture *createSurfaceTextureX11(SurfacePixmapX11 *pixmap);
|
||||
virtual SurfaceTexture *createSurfaceTextureWayland(SurfacePixmapWayland *pixmap);
|
||||
|
||||
virtual void paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data);
|
||||
|
||||
QMatrix4x4 renderTargetProjectionMatrix() const;
|
||||
QRect renderTargetRect() const;
|
||||
void setRenderTargetRect(const QRect &rect);
|
||||
|
|
|
@ -152,15 +152,6 @@ void SceneOpenGL::paintBackground(const QRegion ®ion)
|
|||
}
|
||||
}
|
||||
|
||||
void SceneOpenGL::paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data)
|
||||
{
|
||||
const QRect r = region.boundingRect();
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(r.x(), geometry().size().height() - r.y() - r.height(), r.width(), r.height());
|
||||
KWin::Scene::paintDesktop(desktop, mask, region, data);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
void SceneOpenGL::paintOffscreenQuickView(OffscreenQuickView *w)
|
||||
{
|
||||
GLTexture *t = w->bufferAsTexture();
|
||||
|
|
|
@ -64,7 +64,6 @@ public:
|
|||
protected:
|
||||
void paintBackground(const QRegion ®ion) override;
|
||||
QMatrix4x4 transformation(int mask, const ScreenPaintData &data) const;
|
||||
void paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
||||
void paintOffscreenQuickView(OffscreenQuickView *w) override;
|
||||
|
||||
void paintSimpleScreen(int mask, const QRegion ®ion) override;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
add_subdirectory(v2)
|
||||
|
||||
if (KWIN_BUILD_KCMS)
|
||||
set(kcm_kwin4_genericscripted_SRCS genericscriptedconfig.cpp)
|
||||
qt_add_dbus_interface(kcm_kwin4_genericscripted_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
|
||||
|
|
|
@ -641,7 +641,6 @@ KWin::Scripting::Scripting(QObject *parent)
|
|||
|
||||
void KWin::Scripting::init()
|
||||
{
|
||||
qmlRegisterType<DesktopThumbnailItem>("org.kde.kwin", 2, 0, "DesktopThumbnailItem");
|
||||
qmlRegisterType<WindowThumbnailItem>("org.kde.kwin", 2, 0, "ThumbnailItem");
|
||||
qmlRegisterType<DBusCall>("org.kde.kwin", 2, 0, "DBusCall");
|
||||
qmlRegisterType<ScreenEdgeItem>("org.kde.kwin", 2, 0, "ScreenEdgeItem");
|
||||
|
|
|
@ -440,89 +440,4 @@ void WindowThumbnailItem::updateOffscreenTexture()
|
|||
update();
|
||||
}
|
||||
|
||||
DesktopThumbnailItem::DesktopThumbnailItem(QQuickItem *parent)
|
||||
: ThumbnailItemBase(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int DesktopThumbnailItem::desktop() const
|
||||
{
|
||||
return m_desktop;
|
||||
}
|
||||
|
||||
void DesktopThumbnailItem::setDesktop(int desktop)
|
||||
{
|
||||
desktop = qBound<int>(1, desktop, VirtualDesktopManager::self()->count());
|
||||
if (m_desktop != desktop) {
|
||||
m_desktop = desktop;
|
||||
invalidateOffscreenTexture();
|
||||
Q_EMIT desktopChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QImage DesktopThumbnailItem::fallbackImage() const
|
||||
{
|
||||
return QImage();
|
||||
}
|
||||
|
||||
QRectF DesktopThumbnailItem::paintedRect() const
|
||||
{
|
||||
return centeredSize(boundingRect(), screens()->size());
|
||||
}
|
||||
|
||||
void DesktopThumbnailItem::invalidateOffscreenTexture()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void DesktopThumbnailItem::updateOffscreenTexture()
|
||||
{
|
||||
if (m_acquireFence) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QRect geometry = screens()->geometry();
|
||||
QSize textureSize = geometry.size();
|
||||
if (sourceSize().width() > 0) {
|
||||
textureSize.setWidth(sourceSize().width());
|
||||
}
|
||||
if (sourceSize().height() > 0) {
|
||||
textureSize.setHeight(sourceSize().height());
|
||||
}
|
||||
|
||||
m_devicePixelRatio = window()->devicePixelRatio();
|
||||
textureSize *= m_devicePixelRatio;
|
||||
|
||||
if (!m_offscreenTexture || m_offscreenTexture->size() != textureSize) {
|
||||
m_offscreenTexture.reset(new GLTexture(GL_RGBA8, textureSize));
|
||||
m_offscreenTexture->setFilter(GL_LINEAR);
|
||||
m_offscreenTexture->setWrapMode(GL_CLAMP_TO_EDGE);
|
||||
m_offscreenTexture->setYInverted(true);
|
||||
m_offscreenTarget.reset(new GLFramebuffer(m_offscreenTexture.data()));
|
||||
}
|
||||
|
||||
GLFramebuffer::pushFramebuffer(m_offscreenTarget.data());
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
QMatrix4x4 projectionMatrix;
|
||||
projectionMatrix.ortho(geometry);
|
||||
ScreenPaintData data(projectionMatrix);
|
||||
|
||||
// The thumbnail must be rendered using kwin's opengl context as VAOs are not
|
||||
// shared across contexts. Unfortunately, this also introduces a latency of 1
|
||||
// frame, which is not ideal, but it is acceptable for things such as thumbnails.
|
||||
const int mask = Scene::PAINT_WINDOW_TRANSFORMED | Scene::PAINT_SCREEN_TRANSFORMED;
|
||||
Scene *scene = Compositor::self()->scene();
|
||||
scene->paintDesktop(m_desktop, mask, infiniteRegion(), data);
|
||||
GLFramebuffer::popFramebuffer();
|
||||
|
||||
// The fence is needed to avoid the case where qtquick renderer starts using
|
||||
// the texture while all rendering commands to it haven't completed yet.
|
||||
m_acquireFence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
|
||||
// We know that the texture has changed, so schedule an item update.
|
||||
update();
|
||||
}
|
||||
|
||||
} // namespace KWin
|
||||
|
|
|
@ -128,28 +128,4 @@ private:
|
|||
bool m_dirty = false;
|
||||
};
|
||||
|
||||
class DesktopThumbnailItem : public ThumbnailItemBase
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int desktop READ desktop WRITE setDesktop NOTIFY desktopChanged)
|
||||
|
||||
public:
|
||||
explicit DesktopThumbnailItem(QQuickItem *parent = nullptr);
|
||||
|
||||
int desktop() const;
|
||||
void setDesktop(int desktop);
|
||||
|
||||
Q_SIGNALS:
|
||||
void desktopChanged();
|
||||
|
||||
protected:
|
||||
QImage fallbackImage() const override;
|
||||
QRectF paintedRect() const override;
|
||||
void invalidateOffscreenTexture() override;
|
||||
void updateOffscreenTexture() override;
|
||||
|
||||
private:
|
||||
int m_desktop = 1;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
||||
|
|
6
src/scripting/v2/CMakeLists.txt
Normal file
6
src/scripting/v2/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
# SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
install(DIRECTORY qml/
|
||||
DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kwin.2)
|
41
src/scripting/v2/qml/DesktopThumbnailItem.qml
Normal file
41
src/scripting/v2/qml/DesktopThumbnailItem.qml
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.12
|
||||
import org.kde.kwin 2.0 as KWinComponents
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property int desktop: 1
|
||||
|
||||
// These unused properties exist for compatibility reasons.
|
||||
property real brightness: 1
|
||||
property real saturation: 1
|
||||
property Item clipTo: null
|
||||
|
||||
Item {
|
||||
id: container
|
||||
anchors.centerIn: parent
|
||||
width: workspace.virtualScreenSize.width
|
||||
height: workspace.virtualScreenSize.height
|
||||
scale: Math.min(parent.width / container.width, parent.height / container.height)
|
||||
|
||||
Repeater {
|
||||
model: KWinComponents.ClientModel {
|
||||
exclusions: KWinComponents.ClientModel.OtherActivitiesExclusion
|
||||
}
|
||||
|
||||
KWinComponents.ThumbnailItem {
|
||||
client: model.client
|
||||
x: model.client.x
|
||||
y: model.client.y
|
||||
z: model.client.stackingOrder
|
||||
visible: (model.client.desktop === -1 || model.client.desktop === root.desktop) && !model.client.minimized
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
src/scripting/v2/qml/qmldir
Normal file
7
src/scripting/v2/qml/qmldir
Normal file
|
@ -0,0 +1,7 @@
|
|||
# SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
#
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module org.kde.kwin
|
||||
|
||||
DesktopThumbnailItem 2.0 DesktopThumbnailItem.qml
|
Loading…
Reference in a new issue