diff --git a/src/decorationitem.cpp b/src/decorationitem.cpp index 906bfaaf7e..23fcb79462 100644 --- a/src/decorationitem.cpp +++ b/src/decorationitem.cpp @@ -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(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(toplevel)) { + if (const AbstractClient *client = qobject_cast(m_window)) { client->layoutDecorationRects(rects[0], rects[1], rects[2], rects[3]); - } else if (const Deleted *deleted = qobject_cast(toplevel)) { + } else if (const Deleted *deleted = qobject_cast(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); diff --git a/src/decorationitem.h b/src/decorationitem.h index d15476c6e0..3adc05f7f6 100644 --- a/src/decorationitem.h +++ b/src/decorationitem.h @@ -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 m_decoration; QScopedPointer m_renderer; }; diff --git a/src/item.cpp b/src/item.cpp index cca7a0e296..9fd9cea2fa 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -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::childItems() const return m_childItems; } -Scene::Window *Item::window() const -{ - return m_window; -} - QPoint Item::position() const { return m_position; diff --git a/src/item.h b/src/item.h index 9d94f0d4a5..a01ec23bf5 100644 --- a/src/item.h +++ b/src/item.h @@ -6,7 +6,11 @@ #pragma once -#include "scene.h" +#include "kwinglobals.h" +#include "kwineffects.h" + +#include +#include #include @@ -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 childItems() const; QList 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 m_parentItem; QList m_childItems; QMatrix4x4 m_transform; diff --git a/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.cpp b/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.cpp index b2d5b4c929..c2336f9c00 100644 --- a/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.cpp +++ b/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.cpp @@ -10,6 +10,7 @@ #include "kwingltexture.h" #include "logging.h" #include "surfaceitem_wayland.h" +#include "utils.h" #include #include diff --git a/src/platformsupport/scenes/opengl/platformopenglsurfacetexture_internal.h b/src/platformsupport/scenes/opengl/platformopenglsurfacetexture_internal.h index 24d6e272cf..a8d9af9af2 100644 --- a/src/platformsupport/scenes/opengl/platformopenglsurfacetexture_internal.h +++ b/src/platformsupport/scenes/opengl/platformopenglsurfacetexture_internal.h @@ -11,6 +11,8 @@ namespace KWin { +class SurfacePixmapInternal; + class KWIN_EXPORT PlatformOpenGLSurfaceTextureInternal : public PlatformOpenGLSurfaceTexture { public: diff --git a/src/platformsupport/scenes/opengl/platformopenglsurfacetexture_wayland.h b/src/platformsupport/scenes/opengl/platformopenglsurfacetexture_wayland.h index 4c244fce7c..a95a8776e2 100644 --- a/src/platformsupport/scenes/opengl/platformopenglsurfacetexture_wayland.h +++ b/src/platformsupport/scenes/opengl/platformopenglsurfacetexture_wayland.h @@ -11,6 +11,8 @@ namespace KWin { +class SurfacePixmapWayland; + class KWIN_EXPORT PlatformOpenGLSurfaceTextureWayland : public PlatformOpenGLSurfaceTexture { public: diff --git a/src/platformsupport/scenes/opengl/platformopenglsurfacetexture_x11.h b/src/platformsupport/scenes/opengl/platformopenglsurfacetexture_x11.h index e46325932b..7a613e7910 100644 --- a/src/platformsupport/scenes/opengl/platformopenglsurfacetexture_x11.h +++ b/src/platformsupport/scenes/opengl/platformopenglsurfacetexture_x11.h @@ -11,6 +11,8 @@ namespace KWin { +class SurfacePixmapX11; + class KWIN_EXPORT PlatformOpenGLSurfaceTextureX11 : public PlatformOpenGLSurfaceTexture { public: diff --git a/src/platformsupport/scenes/qpainter/platformqpaintersurfacetexture_internal.h b/src/platformsupport/scenes/qpainter/platformqpaintersurfacetexture_internal.h index 544ee98e52..5298e2ee27 100644 --- a/src/platformsupport/scenes/qpainter/platformqpaintersurfacetexture_internal.h +++ b/src/platformsupport/scenes/qpainter/platformqpaintersurfacetexture_internal.h @@ -11,6 +11,8 @@ namespace KWin { +class SurfacePixmapInternal; + class KWIN_EXPORT PlatformQPainterSurfaceTextureInternal : public PlatformQPainterSurfaceTexture { public: diff --git a/src/platformsupport/scenes/qpainter/platformqpaintersurfacetexture_wayland.cpp b/src/platformsupport/scenes/qpainter/platformqpaintersurfacetexture_wayland.cpp index e9e78990c0..36d744be79 100644 --- a/src/platformsupport/scenes/qpainter/platformqpaintersurfacetexture_wayland.cpp +++ b/src/platformsupport/scenes/qpainter/platformqpaintersurfacetexture_wayland.cpp @@ -6,6 +6,7 @@ #include "platformqpaintersurfacetexture_wayland.h" #include "surfaceitem_wayland.h" +#include "utils.h" #include #include diff --git a/src/platformsupport/scenes/qpainter/platformqpaintersurfacetexture_wayland.h b/src/platformsupport/scenes/qpainter/platformqpaintersurfacetexture_wayland.h index a375ebe545..b94a5fd1ec 100644 --- a/src/platformsupport/scenes/qpainter/platformqpaintersurfacetexture_wayland.h +++ b/src/platformsupport/scenes/qpainter/platformqpaintersurfacetexture_wayland.h @@ -11,6 +11,8 @@ namespace KWin { +class SurfacePixmapWayland; + class KWIN_EXPORT PlatformQPainterSurfaceTextureWayland : public PlatformQPainterSurfaceTexture { public: diff --git a/src/plugins/platforms/x11/standalone/eglbackend.h b/src/plugins/platforms/x11/standalone/eglbackend.h index dabb418b4a..af6399e197 100644 --- a/src/plugins/platforms/x11/standalone/eglbackend.h +++ b/src/plugins/platforms/x11/standalone/eglbackend.h @@ -8,6 +8,7 @@ #include "eglonxbackend.h" #include "platformopenglsurfacetexture_x11.h" +#include "utils.h" #include #include diff --git a/src/plugins/platforms/x11/standalone/glxbackend.h b/src/plugins/platforms/x11/standalone/glxbackend.h index f963b291b1..fffe349062 100644 --- a/src/plugins/platforms/x11/standalone/glxbackend.h +++ b/src/plugins/platforms/x11/standalone/glxbackend.h @@ -11,6 +11,7 @@ #include "openglbackend.h" #include "platformopenglsurfacetexture_x11.h" #include "x11eventfilter.h" +#include "utils.h" #include #include diff --git a/src/scene.cpp b/src/scene.cpp index 60f8eb3cc3..0f792ff958 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -598,11 +598,11 @@ Scene::Window::Window(Toplevel *client, QObject *parent) , disable_painting(0) { if (qobject_cast(client)) { - m_windowItem.reset(new WindowItemWayland(this)); + m_windowItem.reset(new WindowItemWayland(toplevel)); } else if (qobject_cast(client) || qobject_cast(client)) { - m_windowItem.reset(new WindowItemX11(this)); + m_windowItem.reset(new WindowItemX11(toplevel)); } else if (qobject_cast(client)) { - m_windowItem.reset(new WindowItemInternal(this)); + m_windowItem.reset(new WindowItemInternal(toplevel)); } else { Q_UNREACHABLE(); } diff --git a/src/shadowitem.cpp b/src/shadowitem.cpp index 9e6fc16ece..0f14d754d5 100644 --- a/src/shadowitem.cpp +++ b/src/shadowitem.cpp @@ -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(); } diff --git a/src/shadowitem.h b/src/shadowitem.h index cee196a2a3..4b06f18f58 100644 --- a/src/shadowitem.h +++ b/src/shadowitem.h @@ -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 m_shadow; }; diff --git a/src/surfaceitem.cpp b/src/surfaceitem.cpp index a6c923c3c5..08fe342fab 100644 --- a/src/surfaceitem.cpp +++ b/src/surfaceitem.cpp @@ -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 ®ion) 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() diff --git a/src/surfaceitem.h b/src/surfaceitem.h index c702281541..4f521565b3 100644 --- a/src/surfaceitem.h +++ b/src/surfaceitem.h @@ -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 m_pixmap; QScopedPointer m_previousPixmap; diff --git a/src/surfaceitem_internal.cpp b/src/surfaceitem_internal.cpp index 2ea90c33c5..7069753bf1 100644 --- a/src/surfaceitem_internal.cpp +++ b/src/surfaceitem_internal.cpp @@ -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(); } } diff --git a/src/surfaceitem_internal.h b/src/surfaceitem_internal.h index ddda9b3784..3fce87a06a 100644 --- a/src/surfaceitem_internal.h +++ b/src/surfaceitem_internal.h @@ -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; diff --git a/src/surfaceitem_wayland.cpp b/src/surfaceitem_wayland.cpp index c7cc83a777..4c280e169e 100644 --- a/src/surfaceitem_wayland.cpp +++ b/src/surfaceitem_wayland.cpp @@ -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; } diff --git a/src/surfaceitem_wayland.h b/src/surfaceitem_wayland.h index b4e3b3f4db..73072753dc 100644 --- a/src/surfaceitem_wayland.h +++ b/src/surfaceitem_wayland.h @@ -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; }; diff --git a/src/surfaceitem_x11.cpp b/src/surfaceitem_x11.cpp index c260928d9c..3529e72211 100644 --- a/src/surfaceitem_x11.cpp +++ b/src/surfaceitem_x11.cpp @@ -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; } diff --git a/src/surfaceitem_x11.h b/src/surfaceitem_x11.h index c6770c421c..e7136aa134 100644 --- a/src/surfaceitem_x11.h +++ b/src/surfaceitem_x11.h @@ -8,6 +8,9 @@ #include "surfaceitem.h" +#include +#include + 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; diff --git a/src/windowitem.cpp b/src/windowitem.cpp index 1bd86f2a80..1336a85e85 100644 --- a/src/windowitem.cpp +++ b/src/windowitem.cpp @@ -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(window->window()); + AbstractClient *client = qobject_cast(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(window()->window()); + AbstractClient *client = qobject_cast(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)); diff --git a/src/windowitem.h b/src/windowitem.h index 3d9a506c7e..a72b9927d3 100644 --- a/src/windowitem.h +++ b/src/windowitem.h @@ -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 m_surfaceItem; QScopedPointer m_decorationItem; QScopedPointer 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