diff --git a/src/item.cpp b/src/item.cpp index 1254f2e4aa..694e3b6e85 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -91,6 +91,8 @@ void Item::addChild(Item *item) updateBoundingRect(); scheduleRepaint(item->boundingRect().translated(item->position())); + + Q_EMIT childAdded(item); } void Item::removeChild(Item *item) diff --git a/src/item.h b/src/item.h index b3db8c9319..220f9fc517 100644 --- a/src/item.h +++ b/src/item.h @@ -108,6 +108,7 @@ public: virtual void preprocess(); Q_SIGNALS: + void childAdded(Item *item); /** * This signal is emitted when the position of this item has changed. */ diff --git a/src/surfaceitem.cpp b/src/surfaceitem.cpp index f3edb1fb2e..ace8c23feb 100644 --- a/src/surfaceitem.cpp +++ b/src/surfaceitem.cpp @@ -5,26 +5,13 @@ */ #include "surfaceitem.h" -#include "deleted.h" namespace KWin { -SurfaceItem::SurfaceItem(Window *window, Item *parent) +SurfaceItem::SurfaceItem(Item *parent) : Item(parent) - , m_window(window) { - connect(window, &Window::windowClosed, this, &SurfaceItem::handleWindowClosed); -} - -Window *SurfaceItem::window() const -{ - return m_window; -} - -void SurfaceItem::handleWindowClosed(Window *original, Deleted *deleted) -{ - m_window = deleted; } QMatrix4x4 SurfaceItem::surfaceToBufferMatrix() const @@ -41,8 +28,7 @@ void SurfaceItem::addDamage(const QRegion ®ion) { m_damage += region; scheduleRepaint(region); - - Q_EMIT m_window->damaged(m_window); + Q_EMIT damaged(); } void SurfaceItem::resetDamage() diff --git a/src/surfaceitem.h b/src/surfaceitem.h index 3660ae1249..a850bef9c3 100644 --- a/src/surfaceitem.h +++ b/src/surfaceitem.h @@ -12,7 +12,6 @@ namespace KWin { -class Deleted; class SurfacePixmap; class Window; @@ -27,8 +26,6 @@ public: QMatrix4x4 surfaceToBufferMatrix() const; void setSurfaceToBufferMatrix(const QMatrix4x4 &matrix); - Window *window() const; - void addDamage(const QRegion ®ion); void resetDamage(); QRegion damage() const; @@ -44,16 +41,16 @@ public: virtual ContentType contentType() const; +Q_SIGNALS: + void damaged(); + protected: - explicit SurfaceItem(Window *window, Item *parent = nullptr); + explicit SurfaceItem(Item *parent = nullptr); virtual std::unique_ptr createPixmap() = 0; void preprocess() override; WindowQuadList buildQuads() const override; - void handleWindowClosed(Window *original, Deleted *deleted); - - Window *m_window; QRegion m_damage; std::unique_ptr m_pixmap; std::unique_ptr m_previousPixmap; diff --git a/src/surfaceitem_internal.cpp b/src/surfaceitem_internal.cpp index 16141ea8d7..ccd7069222 100644 --- a/src/surfaceitem_internal.cpp +++ b/src/surfaceitem_internal.cpp @@ -6,6 +6,7 @@ #include "surfaceitem_internal.h" #include "composite.h" +#include "deleted.h" #include "internalwindow.h" #include "scene.h" @@ -15,10 +16,13 @@ namespace KWin { SurfaceItemInternal::SurfaceItemInternal(InternalWindow *window, Item *parent) - : SurfaceItem(window, parent) + : SurfaceItem(parent) + , m_window(window) { connect(window, &Window::bufferGeometryChanged, this, &SurfaceItemInternal::handleBufferGeometryChanged); + connect(window, &Window::windowClosed, + this, &SurfaceItemInternal::handleWindowClosed); setSize(window->bufferGeometry().size()); @@ -28,6 +32,11 @@ SurfaceItemInternal::SurfaceItemInternal(InternalWindow *window, Item *parent) setSurfaceToBufferMatrix(surfaceToBufferMatrix); } +Window *SurfaceItemInternal::window() const +{ + return m_window; +} + QVector SurfaceItemInternal::shape() const { return {rect()}; @@ -46,6 +55,11 @@ void SurfaceItemInternal::handleBufferGeometryChanged(Window *window, const QRec setSize(window->bufferGeometry().size()); } +void SurfaceItemInternal::handleWindowClosed(Window *original, Deleted *deleted) +{ + m_window = deleted; +} + SurfacePixmapInternal::SurfacePixmapInternal(SurfaceItemInternal *item, QObject *parent) : SurfacePixmap(Compositor::self()->scene()->createSurfaceTextureInternal(this), parent) , m_item(item) diff --git a/src/surfaceitem_internal.h b/src/surfaceitem_internal.h index 9a49fb35e6..bc2fe729cf 100644 --- a/src/surfaceitem_internal.h +++ b/src/surfaceitem_internal.h @@ -13,6 +13,7 @@ class QOpenGLFramebufferObject; namespace KWin { +class Deleted; class InternalWindow; /** @@ -25,13 +26,19 @@ class KWIN_EXPORT SurfaceItemInternal : public SurfaceItem public: explicit SurfaceItemInternal(InternalWindow *window, Item *parent = nullptr); + Window *window() const; + QVector shape() const override; private Q_SLOTS: void handleBufferGeometryChanged(Window *window, const QRectF &old); + void handleWindowClosed(Window *original, Deleted *deleted); protected: std::unique_ptr createPixmap() override; + +private: + Window *m_window; }; class KWIN_EXPORT SurfacePixmapInternal final : public SurfacePixmap diff --git a/src/surfaceitem_wayland.cpp b/src/surfaceitem_wayland.cpp index b2375de6a2..9665028e12 100644 --- a/src/surfaceitem_wayland.cpp +++ b/src/surfaceitem_wayland.cpp @@ -6,6 +6,7 @@ #include "surfaceitem_wayland.h" #include "composite.h" +#include "deleted.h" #include "scene.h" #include "wayland/clientbuffer.h" #include "wayland/subcompositor_interface.h" @@ -14,9 +15,8 @@ namespace KWin { -SurfaceItemWayland::SurfaceItemWayland(KWaylandServer::SurfaceInterface *surface, - Window *window, Item *parent) - : SurfaceItem(window, parent) +SurfaceItemWayland::SurfaceItemWayland(KWaylandServer::SurfaceInterface *surface, Item *parent) + : SurfaceItem(parent) , m_surface(surface) { connect(surface, &KWaylandServer::SurfaceInterface::surfaceToBufferMatrixChanged, @@ -94,7 +94,7 @@ SurfaceItemWayland *SurfaceItemWayland::getOrCreateSubSurfaceItem(KWaylandServer { SurfaceItemWayland *&item = m_subsurfaces[child]; if (!item) { - item = new SurfaceItemWayland(child->surface(), window()); + item = new SurfaceItemWayland(child->surface()); item->setParent(this); item->setParentItem(this); } @@ -203,15 +203,17 @@ void SurfacePixmapWayland::setBuffer(KWaylandServer::ClientBuffer *buffer) } SurfaceItemXwayland::SurfaceItemXwayland(Window *window, Item *parent) - : SurfaceItemWayland(window->surface(), window, parent) + : SurfaceItemWayland(window->surface(), parent) + , m_window(window) { connect(window, &Window::geometryShapeChanged, this, &SurfaceItemXwayland::discardQuads); + connect(window, &Window::windowClosed, this, &SurfaceItemXwayland::handleWindowClosed); } QVector SurfaceItemXwayland::shape() const { - const QRectF clipRect = rect() & window()->clientGeometry().translated(-window()->bufferGeometry().topLeft()); - QVector shape = window()->shapeRegion(); + const QRectF clipRect = rect() & m_window->clientGeometry().translated(-m_window->bufferGeometry().topLeft()); + QVector shape = m_window->shapeRegion(); // bounded to clipRect for (QRectF &shapePart : shape) { @@ -220,4 +222,9 @@ QVector SurfaceItemXwayland::shape() const return shape; } +void SurfaceItemXwayland::handleWindowClosed(Window *original, Deleted *deleted) +{ + m_window = deleted; +} + } // namespace KWin diff --git a/src/surfaceitem_wayland.h b/src/surfaceitem_wayland.h index 4483fdee55..28ab4bb0fb 100644 --- a/src/surfaceitem_wayland.h +++ b/src/surfaceitem_wayland.h @@ -18,6 +18,8 @@ class SurfaceInterface; namespace KWin { +class Deleted; + /** * The SurfaceItemWayland class represents a Wayland surface in the scene. */ @@ -26,8 +28,7 @@ class KWIN_EXPORT SurfaceItemWayland : public SurfaceItem Q_OBJECT public: - explicit SurfaceItemWayland(KWaylandServer::SurfaceInterface *surface, - Window *window, Item *parent = nullptr); + explicit SurfaceItemWayland(KWaylandServer::SurfaceInterface *surface, Item *parent = nullptr); QVector shape() const override; QRegion opaque() const override; @@ -89,6 +90,11 @@ public: explicit SurfaceItemXwayland(Window *window, Item *parent = nullptr); QVector shape() const override; + +private: + void handleWindowClosed(Window *original, Deleted *deleted); + + Window *m_window; }; } // namespace KWin diff --git a/src/surfaceitem_x11.cpp b/src/surfaceitem_x11.cpp index 7345dbabdd..b26c23dc40 100644 --- a/src/surfaceitem_x11.cpp +++ b/src/surfaceitem_x11.cpp @@ -6,6 +6,7 @@ #include "surfaceitem_x11.h" #include "composite.h" +#include "deleted.h" #include "scene.h" #include "x11syncmanager.h" @@ -13,12 +14,15 @@ namespace KWin { SurfaceItemX11::SurfaceItemX11(Window *window, Item *parent) - : SurfaceItem(window, parent) + : SurfaceItem(parent) + , m_window(window) { connect(window, &Window::bufferGeometryChanged, this, &SurfaceItemX11::handleBufferGeometryChanged); connect(window, &Window::geometryShapeChanged, this, &SurfaceItemX11::handleGeometryShapeChanged); + connect(window, &Window::windowClosed, + this, &SurfaceItemX11::handleWindowClosed); m_damageHandle = xcb_generate_id(kwinApp()->x11Connection()); xcb_damage_create(kwinApp()->x11Connection(), m_damageHandle, window->frameId(), @@ -40,6 +44,16 @@ SurfaceItemX11::~SurfaceItemX11() // destroyDamage() will be called by the associated Window. } +Window *SurfaceItemX11::window() const +{ + return m_window; +} + +void SurfaceItemX11::handleWindowClosed(Window *original, Deleted *deleted) +{ + m_window = deleted; +} + void SurfaceItemX11::preprocess() { if (!damage().isEmpty()) { @@ -140,8 +154,8 @@ void SurfaceItemX11::handleGeometryShapeChanged() QVector SurfaceItemX11::shape() const { - const QRectF clipRect = window()->clientGeometry().translated(-window()->bufferGeometry().topLeft()); - QVector shape = window()->shapeRegion(); + const QRectF clipRect = m_window->clientGeometry().translated(-m_window->bufferGeometry().topLeft()); + QVector shape = m_window->shapeRegion(); // bounded to clipRect for (QRectF &shapePart : shape) { shapePart = shapePart.intersected(clipRect); @@ -155,10 +169,10 @@ QRegion SurfaceItemX11::opaque() const for (const QRectF &shapePart : shape()) { shapeRegion |= shapePart.toRect(); } - if (!window()->hasAlpha()) { + if (!m_window->hasAlpha()) { return shapeRegion; } else { - return window()->opaqueRegion() & shapeRegion; + return m_window->opaqueRegion() & shapeRegion; } return QRegion(); } diff --git a/src/surfaceitem_x11.h b/src/surfaceitem_x11.h index 71e04d0aca..8f6539279d 100644 --- a/src/surfaceitem_x11.h +++ b/src/surfaceitem_x11.h @@ -14,6 +14,8 @@ namespace KWin { +class Deleted; + /** * The SurfaceItemX11 class represents an X11 surface in the scene. */ @@ -25,6 +27,8 @@ public: explicit SurfaceItemX11(Window *window, Item *parent = nullptr); ~SurfaceItemX11() override; + Window *window() const; + void preprocess() override; void processDamage(); @@ -38,11 +42,13 @@ public: private Q_SLOTS: void handleBufferGeometryChanged(Window *window, const QRectF &old); void handleGeometryShapeChanged(); + void handleWindowClosed(Window *original, Deleted *deleted); protected: std::unique_ptr createPixmap() override; private: + Window *m_window; xcb_damage_damage_t m_damageHandle = XCB_NONE; xcb_xfixes_fetch_region_cookie_t m_damageCookie; bool m_isDamaged = false; diff --git a/src/windowitem.cpp b/src/windowitem.cpp index 6270af38b7..045db40aff 100644 --- a/src/windowitem.cpp +++ b/src/windowitem.cpp @@ -176,6 +176,12 @@ void WindowItem::updateSurfaceItem(SurfaceItem *surfaceItem) connect(m_window, &Window::bufferGeometryChanged, this, &WindowItem::updateSurfacePosition); connect(m_window, &Window::frameGeometryChanged, this, &WindowItem::updateSurfacePosition); + connect(surfaceItem, &SurfaceItem::damaged, this, &WindowItem::markDamaged); + connect(surfaceItem, &SurfaceItem::childAdded, this, [this](Item *item) { + auto surfaceItem = static_cast(item); + connect(surfaceItem, &SurfaceItem::damaged, this, &WindowItem::markDamaged); + }); + updateSurfacePosition(); updateSurfaceVisibility(); } else { @@ -237,6 +243,11 @@ void WindowItem::updateOpacity() setOpacity(m_window->opacity()); } +void WindowItem::markDamaged() +{ + Q_EMIT m_window->damaged(m_window); +} + WindowItemX11::WindowItemX11(Window *window, Item *parent) : WindowItem(window, parent) { @@ -267,7 +278,7 @@ void WindowItemX11::initialize() WindowItemWayland::WindowItemWayland(Window *window, Item *parent) : WindowItem(window, parent) { - updateSurfaceItem(new SurfaceItemWayland(window->surface(), window, this)); + updateSurfaceItem(new SurfaceItemWayland(window->surface(), this)); } WindowItemInternal::WindowItemInternal(InternalWindow *window, Item *parent) diff --git a/src/windowitem.h b/src/windowitem.h index 9491997794..1ad051c7d7 100644 --- a/src/windowitem.h +++ b/src/windowitem.h @@ -68,6 +68,7 @@ private Q_SLOTS: private: bool computeVisibility() const; void updateVisibility(); + void markDamaged(); Window *m_window; std::unique_ptr m_surfaceItem;