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:
Vlad Zahorodnii 2022-04-27 22:39:58 +03:00
parent 96e82a3631
commit 953cf452a3
13 changed files with 58 additions and 174 deletions

View file

@ -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 &region, 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()) {

View file

@ -61,10 +61,6 @@ public:
~EffectsHandlerImpl() override;
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
void paintScreen(int mask, const QRegion &region, 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 &region, 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;

View file

@ -602,11 +602,6 @@ void Scene::paintWindow(SceneWindow *w, int mask, const QRegion &region)
effects->paintWindow(effectWindow(w), mask, region, data);
}
void Scene::paintDesktop(int desktop, int mask, const QRegion &region, 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 &region, 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;

View file

@ -202,8 +202,6 @@ public:
virtual SurfaceTexture *createSurfaceTextureX11(SurfacePixmapX11 *pixmap);
virtual SurfaceTexture *createSurfaceTextureWayland(SurfacePixmapWayland *pixmap);
virtual void paintDesktop(int desktop, int mask, const QRegion &region, ScreenPaintData &data);
QMatrix4x4 renderTargetProjectionMatrix() const;
QRect renderTargetRect() const;
void setRenderTargetRect(const QRect &rect);

View file

@ -152,15 +152,6 @@ void SceneOpenGL::paintBackground(const QRegion &region)
}
}
void SceneOpenGL::paintDesktop(int desktop, int mask, const QRegion &region, 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();

View file

@ -64,7 +64,6 @@ public:
protected:
void paintBackground(const QRegion &region) override;
QMatrix4x4 transformation(int mask, const ScreenPaintData &data) const;
void paintDesktop(int desktop, int mask, const QRegion &region, ScreenPaintData &data) override;
void paintOffscreenQuickView(OffscreenQuickView *w) override;
void paintSimpleScreen(int mask, const QRegion &region) override;

View file

@ -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)

View file

@ -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");

View file

@ -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

View file

@ -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

View 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)

View 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
}
}
}
}

View 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