scene: Decouple SurfaceItem from Window
The main motivation is to allow SurfaceItem used to be to present non window contents.
This commit is contained in:
parent
93f053b514
commit
f8fb0feab8
12 changed files with 91 additions and 39 deletions
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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<SurfacePixmap> createPixmap() = 0;
|
||||
void preprocess() override;
|
||||
WindowQuadList buildQuads() const override;
|
||||
|
||||
void handleWindowClosed(Window *original, Deleted *deleted);
|
||||
|
||||
Window *m_window;
|
||||
QRegion m_damage;
|
||||
std::unique_ptr<SurfacePixmap> m_pixmap;
|
||||
std::unique_ptr<SurfacePixmap> m_previousPixmap;
|
||||
|
|
|
@ -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<QRectF> 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)
|
||||
|
|
|
@ -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<QRectF> shape() const override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void handleBufferGeometryChanged(Window *window, const QRectF &old);
|
||||
void handleWindowClosed(Window *original, Deleted *deleted);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<SurfacePixmap> createPixmap() override;
|
||||
|
||||
private:
|
||||
Window *m_window;
|
||||
};
|
||||
|
||||
class KWIN_EXPORT SurfacePixmapInternal final : public SurfacePixmap
|
||||
|
|
|
@ -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<QRectF> SurfaceItemXwayland::shape() const
|
||||
{
|
||||
const QRectF clipRect = rect() & window()->clientGeometry().translated(-window()->bufferGeometry().topLeft());
|
||||
QVector<QRectF> shape = window()->shapeRegion();
|
||||
const QRectF clipRect = rect() & m_window->clientGeometry().translated(-m_window->bufferGeometry().topLeft());
|
||||
QVector<QRectF> shape = m_window->shapeRegion();
|
||||
|
||||
// bounded to clipRect
|
||||
for (QRectF &shapePart : shape) {
|
||||
|
@ -220,4 +222,9 @@ QVector<QRectF> SurfaceItemXwayland::shape() const
|
|||
return shape;
|
||||
}
|
||||
|
||||
void SurfaceItemXwayland::handleWindowClosed(Window *original, Deleted *deleted)
|
||||
{
|
||||
m_window = deleted;
|
||||
}
|
||||
|
||||
} // namespace KWin
|
||||
|
|
|
@ -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<QRectF> shape() const override;
|
||||
QRegion opaque() const override;
|
||||
|
@ -89,6 +90,11 @@ public:
|
|||
explicit SurfaceItemXwayland(Window *window, Item *parent = nullptr);
|
||||
|
||||
QVector<QRectF> shape() const override;
|
||||
|
||||
private:
|
||||
void handleWindowClosed(Window *original, Deleted *deleted);
|
||||
|
||||
Window *m_window;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
||||
|
|
|
@ -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<QRectF> SurfaceItemX11::shape() const
|
||||
{
|
||||
const QRectF clipRect = window()->clientGeometry().translated(-window()->bufferGeometry().topLeft());
|
||||
QVector<QRectF> shape = window()->shapeRegion();
|
||||
const QRectF clipRect = m_window->clientGeometry().translated(-m_window->bufferGeometry().topLeft());
|
||||
QVector<QRectF> 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();
|
||||
}
|
||||
|
|
|
@ -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<SurfacePixmap> 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;
|
||||
|
|
|
@ -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<SurfaceItem *>(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)
|
||||
|
|
|
@ -68,6 +68,7 @@ private Q_SLOTS:
|
|||
private:
|
||||
bool computeVisibility() const;
|
||||
void updateVisibility();
|
||||
void markDamaged();
|
||||
|
||||
Window *m_window;
|
||||
std::unique_ptr<SurfaceItem> m_surfaceItem;
|
||||
|
|
Loading…
Reference in a new issue