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:
parent
a13fd02ea8
commit
7e9c6587db
26 changed files with 179 additions and 108 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
10
src/item.h
10
src/item.h
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
class SurfacePixmapInternal;
|
||||
|
||||
class KWIN_EXPORT PlatformOpenGLSurfaceTextureInternal : public PlatformOpenGLSurfaceTexture
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
class SurfacePixmapWayland;
|
||||
|
||||
class KWIN_EXPORT PlatformOpenGLSurfaceTextureWayland : public PlatformOpenGLSurfaceTexture
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
class SurfacePixmapX11;
|
||||
|
||||
class KWIN_EXPORT PlatformOpenGLSurfaceTextureX11 : public PlatformOpenGLSurfaceTexture
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
class SurfacePixmapInternal;
|
||||
|
||||
class KWIN_EXPORT PlatformQPainterSurfaceTextureInternal : public PlatformQPainterSurfaceTexture
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "platformqpaintersurfacetexture_wayland.h"
|
||||
#include "surfaceitem_wayland.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <KWaylandServer/shmclientbuffer.h>
|
||||
#include <KWaylandServer/surface_interface.h>
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
class SurfacePixmapWayland;
|
||||
|
||||
class KWIN_EXPORT PlatformQPainterSurfaceTextureWayland : public PlatformQPainterSurfaceTexture
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "eglonxbackend.h"
|
||||
#include "platformopenglsurfacetexture_x11.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <kwingltexture.h>
|
||||
#include <kwingltexture_p.h>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue