Remove scene window traces in scene items

This further decouples scene items from scene windows. The SurfaceItem
still needs to access the underlying window, I would like to re-iterate
over that later.

With this change, it will be possible to introduce WindowItem factory
function in the Toplevel class.
This commit is contained in:
Vlad Zahorodnii 2021-08-12 12:07:38 +03:00
parent a13fd02ea8
commit 7e9c6587db
26 changed files with 179 additions and 108 deletions

View file

@ -103,16 +103,18 @@ void DecorationRenderer::renderToPainter(QPainter *painter, const QRect &rect)
client()->decoration()->paint(painter, rect);
}
DecorationItem::DecorationItem(KDecoration2::Decoration *decoration, Scene::Window *window, Item *parent)
: Item(window, parent)
DecorationItem::DecorationItem(KDecoration2::Decoration *decoration, AbstractClient *window, Item *parent)
: Item(parent)
, m_window(window)
{
AbstractClient *client = qobject_cast<AbstractClient *>(window->window());
m_renderer.reset(Compositor::self()->scene()->createDecorationRenderer(client->decoratedClient()));
m_renderer.reset(Compositor::self()->scene()->createDecorationRenderer(window->decoratedClient()));
connect(client, &Toplevel::frameGeometryChanged,
connect(window, &Toplevel::frameGeometryChanged,
this, &DecorationItem::handleFrameGeometryChanged);
connect(window, &Toplevel::windowClosed,
this, &DecorationItem::handleWindowClosed);
connect(client, &Toplevel::screenScaleChanged,
connect(window, &Toplevel::screenScaleChanged,
this, &DecorationItem::discardQuads);
connect(decoration, &KDecoration2::Decoration::bordersChanged,
this, &DecorationItem::discardQuads);
@ -120,10 +122,7 @@ DecorationItem::DecorationItem(KDecoration2::Decoration *decoration, Scene::Wind
connect(renderer(), &DecorationRenderer::damaged,
this, &DecorationItem::scheduleRepaint);
// If the decoration is about to be destroyed, render the decoration for the last time.
connect(client, &Toplevel::markedAsZombie, this, &DecorationItem::preprocess);
setSize(client->size());
setSize(window->size());
}
void DecorationItem::preprocess()
@ -137,7 +136,16 @@ void DecorationItem::preprocess()
void DecorationItem::handleFrameGeometryChanged()
{
setSize(window()->size());
setSize(m_window->size());
}
void DecorationItem::handleWindowClosed(Toplevel *original, Deleted *deleted)
{
Q_UNUSED(original)
m_window = deleted;
// If the decoration is about to be destroyed, render the decoration for the last time.
preprocess();
}
DecorationRenderer *DecorationItem::renderer() const
@ -147,20 +155,19 @@ DecorationRenderer *DecorationItem::renderer() const
WindowQuadList DecorationItem::buildQuads() const
{
const Toplevel *toplevel = window()->window();
if (toplevel->frameMargins().isNull()) {
if (m_window->frameMargins().isNull()) {
return WindowQuadList();
}
QRect rects[4];
if (const AbstractClient *client = qobject_cast<const AbstractClient *>(toplevel)) {
if (const AbstractClient *client = qobject_cast<const AbstractClient *>(m_window)) {
client->layoutDecorationRects(rects[0], rects[1], rects[2], rects[3]);
} else if (const Deleted *deleted = qobject_cast<const Deleted *>(toplevel)) {
} else if (const Deleted *deleted = qobject_cast<const Deleted *>(m_window)) {
deleted->layoutDecorationRects(rects[0], rects[1], rects[2], rects[3]);
}
const qreal textureScale = toplevel->screenScale();
const qreal textureScale = m_window->screenScale();
const int padding = 1;
const QPoint topSpritePosition(padding, padding);

View file

@ -16,6 +16,10 @@ class Decoration;
namespace KWin
{
class AbstractClient;
class Deleted;
class Toplevel;
namespace Decoration
{
class DecoratedClientImpl;
@ -65,18 +69,20 @@ class KWIN_EXPORT DecorationItem : public Item
Q_OBJECT
public:
explicit DecorationItem(KDecoration2::Decoration *decoration, Scene::Window *window, Item *parent = nullptr);
explicit DecorationItem(KDecoration2::Decoration *decoration, AbstractClient *window, Item *parent = nullptr);
DecorationRenderer *renderer() const;
private Q_SLOTS:
void handleFrameGeometryChanged();
void handleWindowClosed(Toplevel *original, Deleted *deleted);
protected:
void preprocess() override;
WindowQuadList buildQuads() const override;
private:
Toplevel *m_window;
QPointer<KDecoration2::Decoration> m_decoration;
QScopedPointer<DecorationRenderer> m_renderer;
};

View file

@ -11,12 +11,12 @@
#include "platform.h"
#include "renderloop.h"
#include "screens.h"
#include "utils.h"
namespace KWin
{
Item::Item(Scene::Window *window, Item *parent)
: m_window(window)
Item::Item(Item *parent)
{
setParentItem(parent);
@ -103,11 +103,6 @@ QList<Item *> Item::childItems() const
return m_childItems;
}
Scene::Window *Item::window() const
{
return m_window;
}
QPoint Item::position() const
{
return m_position;

View file

@ -6,7 +6,11 @@
#pragma once
#include "scene.h"
#include "kwinglobals.h"
#include "kwineffects.h"
#include <QMatrix4x4>
#include <QObject>
#include <optional>
@ -21,7 +25,7 @@ class KWIN_EXPORT Item : public QObject
Q_OBJECT
public:
explicit Item(Scene::Window *window, Item *parent = nullptr);
explicit Item(Item *parent = nullptr);
~Item() override;
QPoint position() const;
@ -51,7 +55,6 @@ public:
QList<Item *> childItems() const;
QList<Item *> sortedChildItems() const;
Scene::Window *window() const;
QPoint rootPosition() const;
QMatrix4x4 transform() const;
@ -119,7 +122,6 @@ private:
bool computeEffectiveVisibility() const;
void updateEffectiveVisibility();
Scene::Window *m_window;
QPointer<Item> m_parentItem;
QList<Item *> m_childItems;
QMatrix4x4 m_transform;

View file

@ -10,6 +10,7 @@
#include "kwingltexture.h"
#include "logging.h"
#include "surfaceitem_wayland.h"
#include "utils.h"
#include <KWaylandServer/drmclientbuffer.h>
#include <KWaylandServer/linuxdmabufv1clientbuffer.h>

View file

@ -11,6 +11,8 @@
namespace KWin
{
class SurfacePixmapInternal;
class KWIN_EXPORT PlatformOpenGLSurfaceTextureInternal : public PlatformOpenGLSurfaceTexture
{
public:

View file

@ -11,6 +11,8 @@
namespace KWin
{
class SurfacePixmapWayland;
class KWIN_EXPORT PlatformOpenGLSurfaceTextureWayland : public PlatformOpenGLSurfaceTexture
{
public:

View file

@ -11,6 +11,8 @@
namespace KWin
{
class SurfacePixmapX11;
class KWIN_EXPORT PlatformOpenGLSurfaceTextureX11 : public PlatformOpenGLSurfaceTexture
{
public:

View file

@ -11,6 +11,8 @@
namespace KWin
{
class SurfacePixmapInternal;
class KWIN_EXPORT PlatformQPainterSurfaceTextureInternal : public PlatformQPainterSurfaceTexture
{
public:

View file

@ -6,6 +6,7 @@
#include "platformqpaintersurfacetexture_wayland.h"
#include "surfaceitem_wayland.h"
#include "utils.h"
#include <KWaylandServer/shmclientbuffer.h>
#include <KWaylandServer/surface_interface.h>

View file

@ -11,6 +11,8 @@
namespace KWin
{
class SurfacePixmapWayland;
class KWIN_EXPORT PlatformQPainterSurfaceTextureWayland : public PlatformQPainterSurfaceTexture
{
public:

View file

@ -8,6 +8,7 @@
#include "eglonxbackend.h"
#include "platformopenglsurfacetexture_x11.h"
#include "utils.h"
#include <kwingltexture.h>
#include <kwingltexture_p.h>

View file

@ -11,6 +11,7 @@
#include "openglbackend.h"
#include "platformopenglsurfacetexture_x11.h"
#include "x11eventfilter.h"
#include "utils.h"
#include <xcb/glx.h>
#include <epoxy/glx.h>

View file

@ -598,11 +598,11 @@ Scene::Window::Window(Toplevel *client, QObject *parent)
, disable_painting(0)
{
if (qobject_cast<WaylandClient *>(client)) {
m_windowItem.reset(new WindowItemWayland(this));
m_windowItem.reset(new WindowItemWayland(toplevel));
} else if (qobject_cast<X11Client *>(client) || qobject_cast<Unmanaged *>(client)) {
m_windowItem.reset(new WindowItemX11(this));
m_windowItem.reset(new WindowItemX11(toplevel));
} else if (qobject_cast<InternalClient *>(client)) {
m_windowItem.reset(new WindowItemInternal(this));
m_windowItem.reset(new WindowItemInternal(toplevel));
} else {
Q_UNREACHABLE();
}

View file

@ -5,15 +5,19 @@
*/
#include "shadowitem.h"
#include "deleted.h"
#include "shadow.h"
namespace KWin
{
ShadowItem::ShadowItem(Shadow *shadow, Scene::Window *window, Item *parent)
: Item(window, parent)
ShadowItem::ShadowItem(Shadow *shadow, Toplevel *window, Item *parent)
: Item(parent)
, m_window(window)
, m_shadow(shadow)
{
connect(window, &Toplevel::windowClosed, this, &ShadowItem::handleWindowClosed);
connect(shadow, &Shadow::offsetChanged, this, &ShadowItem::updateGeometry);
connect(shadow, &Shadow::rectChanged, this, &ShadowItem::updateGeometry);
connect(shadow, &Shadow::textureChanged, this, &ShadowItem::handleTextureChanged);
@ -46,6 +50,12 @@ void ShadowItem::handleTextureChanged()
discardQuads();
}
void ShadowItem::handleWindowClosed(Toplevel *original, Deleted *deleted)
{
Q_UNUSED(original)
m_window = deleted;
}
static inline void distributeHorizontally(QRectF &leftRect, QRectF &rightRect)
{
if (leftRect.right() > rightRect.left()) {
@ -70,10 +80,8 @@ static inline void distributeVertically(QRectF &topRect, QRectF &bottomRect)
WindowQuadList ShadowItem::buildQuads() const
{
const Toplevel *toplevel = window()->window();
// Do not draw shadows if window width or window height is less than 5 px. 5 is an arbitrary choice.
if (!toplevel->wantsShadowToBeRendered() || toplevel->width() < 5 || toplevel->height() < 5) {
if (!m_window->wantsShadowToBeRendered() || m_window->width() < 5 || m_window->height() < 5) {
return WindowQuadList();
}

View file

@ -11,6 +11,10 @@
namespace KWin
{
class Deleted;
class Shadow;
class Toplevel;
/**
* The ShadowItem class represents a nine-tile patch server-side drop-shadow.
*/
@ -19,7 +23,7 @@ class KWIN_EXPORT ShadowItem : public Item
Q_OBJECT
public:
explicit ShadowItem(Shadow *shadow, Scene::Window *window, Item *parent = nullptr);
explicit ShadowItem(Shadow *shadow, Toplevel *window, Item *parent = nullptr);
~ShadowItem() override;
Shadow *shadow() const;
@ -30,8 +34,10 @@ protected:
private Q_SLOTS:
void handleTextureChanged();
void updateGeometry();
void handleWindowClosed(Toplevel *original, Deleted *deleted);
private:
Toplevel *m_window;
QScopedPointer<Shadow> m_shadow;
};

View file

@ -5,13 +5,27 @@
*/
#include "surfaceitem.h"
#include "deleted.h"
namespace KWin
{
SurfaceItem::SurfaceItem(Scene::Window *window, Item *parent)
: Item(window, parent)
SurfaceItem::SurfaceItem(Toplevel *window, Item *parent)
: Item(parent)
, m_window(window)
{
connect(window, &Toplevel::windowClosed, this, &SurfaceItem::handleWindowClosed);
}
Toplevel *SurfaceItem::window() const
{
return m_window;
}
void SurfaceItem::handleWindowClosed(Toplevel *original, Deleted *deleted)
{
Q_UNUSED(original)
m_window = deleted;
}
QMatrix4x4 SurfaceItem::surfaceToBufferMatrix() const
@ -39,8 +53,7 @@ void SurfaceItem::addDamage(const QRegion &region)
m_damage += region;
scheduleRepaint(region);
Toplevel *toplevel = window()->window();
Q_EMIT toplevel->damaged(toplevel, region);
Q_EMIT m_window->damaged(m_window, region);
}
void SurfaceItem::resetDamage()

View file

@ -11,7 +11,9 @@
namespace KWin
{
class Deleted;
class SurfacePixmap;
class Toplevel;
/**
* The SurfaceItem class represents a surface with some contents.
@ -24,6 +26,8 @@ public:
QMatrix4x4 surfaceToBufferMatrix() const;
void setSurfaceToBufferMatrix(const QMatrix4x4 &matrix);
Toplevel *window() const;
virtual QRegion shape() const;
virtual QRegion opaque() const;
@ -41,12 +45,15 @@ public:
void unreferencePreviousPixmap();
protected:
explicit SurfaceItem(Scene::Window *window, Item *parent = nullptr);
explicit SurfaceItem(Toplevel *window, Item *parent = nullptr);
virtual SurfacePixmap *createPixmap() = 0;
void preprocess() override;
WindowQuadList buildQuads() const override;
void handleWindowClosed(Toplevel *original, Deleted *deleted);
Toplevel *m_window;
QRegion m_damage;
QScopedPointer<SurfacePixmap> m_pixmap;
QScopedPointer<SurfacePixmap> m_previousPixmap;

View file

@ -11,19 +11,17 @@
namespace KWin
{
SurfaceItemInternal::SurfaceItemInternal(Scene::Window *window, Item *parent)
SurfaceItemInternal::SurfaceItemInternal(Toplevel *window, Item *parent)
: SurfaceItem(window, parent)
{
Toplevel *toplevel = window->window();
connect(toplevel, &Toplevel::bufferGeometryChanged,
connect(window, &Toplevel::bufferGeometryChanged,
this, &SurfaceItemInternal::handleBufferGeometryChanged);
setSize(toplevel->bufferGeometry().size());
setSize(window->bufferGeometry().size());
// The device pixel ratio of the internal window is static.
QMatrix4x4 surfaceToBufferMatrix;
surfaceToBufferMatrix.scale(toplevel->bufferScale());
surfaceToBufferMatrix.scale(window->bufferScale());
setSurfaceToBufferMatrix(surfaceToBufferMatrix);
}
@ -68,13 +66,13 @@ void SurfacePixmapInternal::create()
void SurfacePixmapInternal::update()
{
const Toplevel *toplevel = m_item->window()->window();
const Toplevel *window = m_item->window();
if (toplevel->internalFramebufferObject()) {
m_fbo = toplevel->internalFramebufferObject();
if (window->internalFramebufferObject()) {
m_fbo = window->internalFramebufferObject();
m_hasAlphaChannel = true;
} else if (!toplevel->internalImageObject().isNull()) {
m_rasterBuffer = toplevel->internalImageObject();
} else if (!window->internalImageObject().isNull()) {
m_rasterBuffer = window->internalImageObject();
m_hasAlphaChannel = m_rasterBuffer.hasAlphaChannel();
}
}

View file

@ -8,6 +8,8 @@
#include "surfaceitem.h"
class QOpenGLFramebufferObject;
namespace KWin
{
@ -19,7 +21,7 @@ class KWIN_EXPORT SurfaceItemInternal : public SurfaceItem
Q_OBJECT
public:
explicit SurfaceItemInternal(Scene::Window *window, Item *parent = nullptr);
explicit SurfaceItemInternal(Toplevel *window, Item *parent = nullptr);
QRegion shape() const override;

View file

@ -16,7 +16,7 @@ namespace KWin
{
SurfaceItemWayland::SurfaceItemWayland(KWaylandServer::SurfaceInterface *surface,
Scene::Window *window, Item *parent)
Toplevel *window, Item *parent)
: SurfaceItem(window, parent)
, m_surface(surface)
{
@ -197,18 +197,16 @@ void SurfacePixmapWayland::setBuffer(KWaylandServer::ClientBuffer *buffer)
}
}
SurfaceItemXwayland::SurfaceItemXwayland(Scene::Window *window, Item *parent)
: SurfaceItemWayland(window->window()->surface(), window, parent)
SurfaceItemXwayland::SurfaceItemXwayland(Toplevel *window, Item *parent)
: SurfaceItemWayland(window->surface(), window, parent)
{
const Toplevel *toplevel = window->window();
connect(toplevel, &Toplevel::geometryShapeChanged, this, &SurfaceItemXwayland::discardQuads);
connect(window, &Toplevel::geometryShapeChanged, this, &SurfaceItemXwayland::discardQuads);
}
QRegion SurfaceItemXwayland::shape() const
{
const Toplevel *toplevel = window()->window();
const QRect clipRect = rect() & toplevel->clientGeometry().translated(-toplevel->bufferGeometry().topLeft());
const QRegion shape = toplevel->shapeRegion();
const QRect clipRect = rect() & window()->clientGeometry().translated(-window()->bufferGeometry().topLeft());
const QRegion shape = window()->shapeRegion();
return shape & clipRect;
}

View file

@ -27,7 +27,7 @@ class KWIN_EXPORT SurfaceItemWayland : public SurfaceItem
public:
explicit SurfaceItemWayland(KWaylandServer::SurfaceInterface *surface,
Scene::Window *window, Item *parent = nullptr);
Toplevel *window, Item *parent = nullptr);
QRegion shape() const override;
QRegion opaque() const override;
@ -85,7 +85,7 @@ class KWIN_EXPORT SurfaceItemXwayland : public SurfaceItemWayland
Q_OBJECT
public:
explicit SurfaceItemXwayland(Scene::Window *window, Item *parent = nullptr);
explicit SurfaceItemXwayland(Toplevel *window, Item *parent = nullptr);
QRegion shape() const override;
};

View file

@ -12,21 +12,19 @@
namespace KWin
{
SurfaceItemX11::SurfaceItemX11(Scene::Window *window, Item *parent)
SurfaceItemX11::SurfaceItemX11(Toplevel *window, Item *parent)
: SurfaceItem(window, parent)
{
Toplevel *toplevel = window->window();
connect(toplevel, &Toplevel::bufferGeometryChanged,
connect(window, &Toplevel::bufferGeometryChanged,
this, &SurfaceItemX11::handleBufferGeometryChanged);
connect(toplevel, &Toplevel::geometryShapeChanged,
connect(window, &Toplevel::geometryShapeChanged,
this, &SurfaceItemX11::discardQuads);
m_damageHandle = xcb_generate_id(kwinApp()->x11Connection());
xcb_damage_create(kwinApp()->x11Connection(), m_damageHandle, toplevel->frameId(),
xcb_damage_create(kwinApp()->x11Connection(), m_damageHandle, window->frameId(),
XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY);
setSize(toplevel->bufferGeometry().size());
setSize(window->bufferGeometry().size());
}
SurfaceItemX11::~SurfaceItemX11()
@ -127,16 +125,15 @@ void SurfaceItemX11::handleBufferGeometryChanged(Toplevel *toplevel, const QRect
QRegion SurfaceItemX11::shape() const
{
const Toplevel *toplevel = window()->window();
const QRect clipRect = toplevel->clientGeometry().translated(-toplevel->bufferGeometry().topLeft());
const QRegion shape = toplevel->shapeRegion();
const QRect clipRect = window()->clientGeometry().translated(-window()->bufferGeometry().topLeft());
const QRegion shape = window()->shapeRegion();
return shape & clipRect;
}
QRegion SurfaceItemX11::opaque() const
{
return window()->window()->opaqueRegion();
return window()->opaqueRegion();
}
SurfacePixmap *SurfaceItemX11::createPixmap()
@ -169,12 +166,12 @@ xcb_pixmap_t SurfacePixmapX11::pixmap() const
xcb_visualid_t SurfacePixmapX11::visual() const
{
return m_item->window()->window()->visual();
return m_item->window()->visual();
}
void SurfacePixmapX11::create()
{
const Toplevel *toplevel = m_item->window()->window();
const Toplevel *toplevel = m_item->window();
if (toplevel->isDeleted()) {
return;
}

View file

@ -8,6 +8,9 @@
#include "surfaceitem.h"
#include <xcb/damage.h>
#include <xcb/xfixes.h>
namespace KWin
{
@ -19,7 +22,7 @@ class KWIN_EXPORT SurfaceItemX11 : public SurfaceItem
Q_OBJECT
public:
explicit SurfaceItemX11(Scene::Window *window, Item *parent = nullptr);
explicit SurfaceItemX11(Toplevel *window, Item *parent = nullptr);
~SurfaceItemX11() override;
void preprocess() override;

View file

@ -7,6 +7,7 @@
#include "windowitem.h"
#include "abstract_client.h"
#include "decorationitem.h"
#include "deleted.h"
#include "shadowitem.h"
#include "surfaceitem_internal.h"
#include "surfaceitem_wayland.h"
@ -15,14 +16,16 @@
namespace KWin
{
WindowItem::WindowItem(Scene::Window *window, Item *parent)
: Item(window, parent)
WindowItem::WindowItem(Toplevel *window, Item *parent)
: Item(parent)
, m_window(window)
{
AbstractClient *client = qobject_cast<AbstractClient *>(window->window());
AbstractClient *client = qobject_cast<AbstractClient *>(window);
if (client) {
connect(client, &AbstractClient::decorationChanged, this, &WindowItem::updateDecorationItem);
updateDecorationItem();
}
connect(window, &Toplevel::windowClosed, this, &WindowItem::handleWindowClosed);
}
SurfaceItem *WindowItem::surfaceItem() const
@ -40,15 +43,24 @@ ShadowItem *WindowItem::shadowItem() const
return m_shadowItem.data();
}
Toplevel *WindowItem::window() const
{
return m_window;
}
void WindowItem::handleWindowClosed(Toplevel *original, Deleted *deleted)
{
Q_UNUSED(original)
m_window = deleted;
}
void WindowItem::updateSurfaceItem(SurfaceItem *surfaceItem)
{
Toplevel *toplevel = window()->window();
m_surfaceItem.reset(surfaceItem);
connect(toplevel, &Toplevel::shadeChanged, this, &WindowItem::updateSurfaceVisibility);
connect(toplevel, &Toplevel::bufferGeometryChanged, this, &WindowItem::updateSurfacePosition);
connect(toplevel, &Toplevel::frameGeometryChanged, this, &WindowItem::updateSurfacePosition);
connect(m_window, &Toplevel::shadeChanged, this, &WindowItem::updateSurfaceVisibility);
connect(m_window, &Toplevel::bufferGeometryChanged, this, &WindowItem::updateSurfacePosition);
connect(m_window, &Toplevel::frameGeometryChanged, this, &WindowItem::updateSurfacePosition);
updateSurfacePosition();
updateSurfaceVisibility();
@ -56,24 +68,22 @@ void WindowItem::updateSurfaceItem(SurfaceItem *surfaceItem)
void WindowItem::updateSurfacePosition()
{
const Toplevel *toplevel = window()->window();
const QRect bufferGeometry = toplevel->bufferGeometry();
const QRect frameGeometry = toplevel->frameGeometry();
const QRect bufferGeometry = m_window->bufferGeometry();
const QRect frameGeometry = m_window->frameGeometry();
m_surfaceItem->setPosition(bufferGeometry.topLeft() - frameGeometry.topLeft());
}
void WindowItem::updateSurfaceVisibility()
{
m_surfaceItem->setVisible(!window()->window()->isShade());
m_surfaceItem->setVisible(!m_window->isShade());
}
void WindowItem::setShadow(Shadow *shadow)
{
if (shadow) {
if (!m_shadowItem || m_shadowItem->shadow() != shadow) {
m_shadowItem.reset(new ShadowItem(shadow, window(), this));
m_shadowItem.reset(new ShadowItem(shadow, m_window, this));
}
if (m_decorationItem) {
m_shadowItem->stackBefore(m_decorationItem.data());
@ -87,12 +97,12 @@ void WindowItem::setShadow(Shadow *shadow)
void WindowItem::updateDecorationItem()
{
AbstractClient *client = qobject_cast<AbstractClient *>(window()->window());
AbstractClient *client = qobject_cast<AbstractClient *>(m_window);
if (!client || client->isZombie()) {
return;
}
if (client->decoration()) {
m_decorationItem.reset(new DecorationItem(client->decoration(), window(), this));
m_decorationItem.reset(new DecorationItem(client->decoration(), client, this));
if (m_shadowItem) {
m_decorationItem->stackAfter(m_shadowItem.data());
} else if (m_surfaceItem) {
@ -103,21 +113,19 @@ void WindowItem::updateDecorationItem()
}
}
WindowItemX11::WindowItemX11(Scene::Window *window, Item *parent)
WindowItemX11::WindowItemX11(Toplevel *window, Item *parent)
: WindowItem(window, parent)
{
Toplevel *toplevel = window->window();
switch (kwinApp()->operationMode()) {
case Application::OperationModeX11:
initialize();
break;
case Application::OperationModeXwayland:
// Xwayland windows and Wayland surfaces are associated asynchronously.
if (toplevel->surface()) {
if (window->surface()) {
initialize();
} else {
connect(toplevel, &Toplevel::surfaceChanged, this, &WindowItemX11::initialize);
connect(window, &Toplevel::surfaceChanged, this, &WindowItemX11::initialize);
}
break;
case Application::OperationModeWaylandOnly:
@ -127,21 +135,20 @@ WindowItemX11::WindowItemX11(Scene::Window *window, Item *parent)
void WindowItemX11::initialize()
{
if (!window()->window()->surface()) {
if (!window()->surface()) {
updateSurfaceItem(new SurfaceItemX11(window(), this));
} else {
updateSurfaceItem(new SurfaceItemXwayland(window(), this));
}
}
WindowItemWayland::WindowItemWayland(Scene::Window *window, Item *parent)
WindowItemWayland::WindowItemWayland(Toplevel *window, Item *parent)
: WindowItem(window, parent)
{
Toplevel *toplevel = window->window();
updateSurfaceItem(new SurfaceItemWayland(toplevel->surface(), window, this));
updateSurfaceItem(new SurfaceItemWayland(window->surface(), window, this));
}
WindowItemInternal::WindowItemInternal(Scene::Window *window, Item *parent)
WindowItemInternal::WindowItemInternal(Toplevel *window, Item *parent)
: WindowItem(window, parent)
{
updateSurfaceItem(new SurfaceItemInternal(window, this));

View file

@ -16,6 +16,11 @@ class Decoration;
namespace KWin
{
class DecorationItem;
class Deleted;
class Shadow;
class ShadowItem;
class SurfaceItem;
class Toplevel;
/**
* The WindowItem class represents a window in the scene.
@ -31,19 +36,22 @@ public:
SurfaceItem *surfaceItem() const;
DecorationItem *decorationItem() const;
ShadowItem *shadowItem() const;
Toplevel *window() const;
void setShadow(Shadow *shadow);
protected:
explicit WindowItem(Scene::Window *window, Item *parent = nullptr);
explicit WindowItem(Toplevel *window, Item *parent = nullptr);
void updateSurfaceItem(SurfaceItem *surfaceItem);
private Q_SLOTS:
void handleWindowClosed(Toplevel *original, Deleted *deleted);
void updateDecorationItem();
void updateSurfacePosition();
void updateSurfaceVisibility();
private:
Toplevel *m_window;
QScopedPointer<SurfaceItem> m_surfaceItem;
QScopedPointer<DecorationItem> m_decorationItem;
QScopedPointer<ShadowItem> m_shadowItem;
@ -60,7 +68,7 @@ class KWIN_EXPORT WindowItemX11 : public WindowItem
Q_OBJECT
public:
explicit WindowItemX11(Scene::Window *window, Item *parent = nullptr);
explicit WindowItemX11(Toplevel *window, Item *parent = nullptr);
private Q_SLOTS:
void initialize();
@ -74,7 +82,7 @@ class KWIN_EXPORT WindowItemWayland : public WindowItem
Q_OBJECT
public:
explicit WindowItemWayland(Scene::Window *window, Item *parent = nullptr);
explicit WindowItemWayland(Toplevel *window, Item *parent = nullptr);
};
/**
@ -86,7 +94,7 @@ class KWIN_EXPORT WindowItemInternal : public WindowItem
Q_OBJECT
public:
explicit WindowItemInternal(Scene::Window *window, Item *parent = nullptr);
explicit WindowItemInternal(Toplevel *window, Item *parent = nullptr);
};
} // namespace KWin