Move ownership of Shadow to Toplevel
This decouples the management of Shadow from the scene window and allows multiple items share the same Shadow. Currently, kwin has a single scene graph, but it makes sense to create a scene graph per output as they could have different layers, etc. This would also allow QtQuick share more textures with kwin, which is worth doing for optimization purposes in the future.
This commit is contained in:
parent
b40fb76c71
commit
935fa6a9e1
11 changed files with 47 additions and 17 deletions
|
@ -48,6 +48,7 @@ Deleted::~Deleted()
|
|||
workspace()->removeDeleted(this);
|
||||
}
|
||||
deleteEffectWindow();
|
||||
deleteShadow();
|
||||
}
|
||||
|
||||
Deleted* Deleted::create(Toplevel* c)
|
||||
|
|
|
@ -466,7 +466,6 @@ void Scene::addToplevel(Toplevel *c)
|
|||
connect(c, &Toplevel::windowClosed, this, &Scene::windowClosed);
|
||||
|
||||
c->effectWindow()->setSceneWindow(w);
|
||||
c->updateShadow();
|
||||
}
|
||||
|
||||
void Scene::removeToplevel(Toplevel *toplevel)
|
||||
|
@ -486,9 +485,6 @@ void Scene::windowClosed(Toplevel *toplevel, Deleted *deleted)
|
|||
Q_ASSERT(m_windows.contains(toplevel));
|
||||
Window *window = m_windows.take(toplevel);
|
||||
window->updateToplevel(deleted);
|
||||
if (window->shadowItem()) {
|
||||
window->shadowItem()->shadow()->setToplevel(deleted);
|
||||
}
|
||||
m_windows[deleted] = window;
|
||||
}
|
||||
|
||||
|
|
|
@ -325,6 +325,11 @@ bool Shadow::updateShadow()
|
|||
return true;
|
||||
}
|
||||
|
||||
Toplevel *Shadow::toplevel() const
|
||||
{
|
||||
return m_topLevel;
|
||||
}
|
||||
|
||||
void Shadow::setToplevel(Toplevel *topLevel)
|
||||
{
|
||||
m_topLevel = topLevel;
|
||||
|
|
|
@ -73,6 +73,7 @@ public:
|
|||
*/
|
||||
static Shadow *createShadow(Toplevel *toplevel);
|
||||
|
||||
Toplevel *toplevel() const;
|
||||
/**
|
||||
* Reparents the shadow to @p toplevel.
|
||||
* Used when a window is deleted.
|
||||
|
|
|
@ -32,7 +32,7 @@ ShadowItem::~ShadowItem()
|
|||
|
||||
Shadow *ShadowItem::shadow() const
|
||||
{
|
||||
return m_shadow.data();
|
||||
return m_shadow;
|
||||
}
|
||||
|
||||
void ShadowItem::updateGeometry()
|
||||
|
|
|
@ -38,7 +38,7 @@ private Q_SLOTS:
|
|||
|
||||
private:
|
||||
Toplevel *m_window;
|
||||
QScopedPointer<Shadow> m_shadow;
|
||||
Shadow *m_shadow = nullptr;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
||||
|
|
|
@ -118,6 +118,10 @@ void Toplevel::copyToDeleted(Toplevel* c)
|
|||
effect_window = c->effect_window;
|
||||
if (effect_window != nullptr)
|
||||
effect_window->setWindow(this);
|
||||
m_shadow = c->m_shadow;
|
||||
if (m_shadow) {
|
||||
m_shadow->setToplevel(this);
|
||||
}
|
||||
resource_name = c->resourceName();
|
||||
resource_class = c->resourceClass();
|
||||
m_clientMachine = c->m_clientMachine;
|
||||
|
@ -271,6 +275,7 @@ bool Toplevel::setupCompositing()
|
|||
return false;
|
||||
|
||||
effect_window = new EffectWindowImpl(this);
|
||||
updateShadow();
|
||||
Compositor::self()->scene()->addToplevel(this);
|
||||
|
||||
connect(windowItem(), &WindowItem::positionChanged, this, &Toplevel::visibleGeometryChanged);
|
||||
|
@ -287,6 +292,9 @@ void Toplevel::finishCompositing(ReleaseReason releaseReason)
|
|||
item->destroyDamage();
|
||||
}
|
||||
}
|
||||
if (m_shadow && m_shadow->toplevel() == this) { // otherwise it's already passed to Deleted, don't free data
|
||||
deleteShadow();
|
||||
}
|
||||
if (effect_window && effect_window->window() == this) { // otherwise it's already passed to Deleted, don't free data
|
||||
deleteEffectWindow();
|
||||
}
|
||||
|
@ -359,6 +367,12 @@ void Toplevel::setReadyForPainting()
|
|||
}
|
||||
}
|
||||
|
||||
void Toplevel::deleteShadow()
|
||||
{
|
||||
delete m_shadow;
|
||||
m_shadow = nullptr;
|
||||
}
|
||||
|
||||
void Toplevel::deleteEffectWindow()
|
||||
{
|
||||
delete effect_window;
|
||||
|
@ -425,21 +439,24 @@ bool Toplevel::isOnOutput(AbstractOutput *output) const
|
|||
return output->geometry().intersects(frameGeometry());
|
||||
}
|
||||
|
||||
Shadow *Toplevel::shadow() const
|
||||
{
|
||||
return m_shadow;
|
||||
}
|
||||
|
||||
void Toplevel::updateShadow()
|
||||
{
|
||||
WindowItem *windowItem = this->windowItem();
|
||||
if (!windowItem) {
|
||||
if (!Compositor::compositing()) {
|
||||
return;
|
||||
}
|
||||
if (auto shadowItem = windowItem->shadowItem()) {
|
||||
if (!shadowItem->shadow()->updateShadow()) {
|
||||
windowItem->setShadow(nullptr);
|
||||
if (m_shadow) {
|
||||
if (!m_shadow->updateShadow()) {
|
||||
deleteShadow();
|
||||
}
|
||||
Q_EMIT shadowChanged();
|
||||
} else {
|
||||
Shadow *shadow = Shadow::createShadow(this);
|
||||
if (shadow) {
|
||||
windowItem->setShadow(shadow);
|
||||
m_shadow = Shadow::createShadow(this);
|
||||
if (m_shadow) {
|
||||
Q_EMIT shadowChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -466,6 +466,10 @@ public:
|
|||
*/
|
||||
void elevate(bool elevate);
|
||||
|
||||
/**
|
||||
* Returns the Shadow associated with this Toplevel or @c null if it has no shadow.
|
||||
*/
|
||||
Shadow *shadow() const;
|
||||
/**
|
||||
* Updates the Shadow associated with this Toplevel from X11 Property.
|
||||
* Call this method when the Property changes or Compositing is started.
|
||||
|
@ -692,6 +696,7 @@ protected:
|
|||
void getSkipCloseAnimation();
|
||||
void copyToDeleted(Toplevel* c);
|
||||
void disownDataPassedToDeleted();
|
||||
void deleteShadow();
|
||||
void deleteEffectWindow();
|
||||
void setDepth(int depth);
|
||||
QRect m_frameGeometry;
|
||||
|
@ -713,6 +718,7 @@ private:
|
|||
Xcb::Window m_client;
|
||||
bool is_shape;
|
||||
EffectWindowImpl* effect_window;
|
||||
Shadow *m_shadow = nullptr;
|
||||
QByteArray resource_name;
|
||||
QByteArray resource_class;
|
||||
ClientMachine *m_clientMachine;
|
||||
|
|
|
@ -25,6 +25,9 @@ WindowItem::WindowItem(Toplevel *window, Item *parent)
|
|||
connect(client, &AbstractClient::decorationChanged, this, &WindowItem::updateDecorationItem);
|
||||
updateDecorationItem();
|
||||
}
|
||||
connect(window, &Toplevel::shadowChanged, this, &WindowItem::updateShadowItem);
|
||||
updateShadowItem();
|
||||
|
||||
connect(window, &Toplevel::windowClosed, this, &WindowItem::handleWindowClosed);
|
||||
}
|
||||
|
||||
|
@ -79,8 +82,9 @@ void WindowItem::updateSurfaceVisibility()
|
|||
m_surfaceItem->setVisible(!m_window->isShade());
|
||||
}
|
||||
|
||||
void WindowItem::setShadow(Shadow *shadow)
|
||||
void WindowItem::updateShadowItem()
|
||||
{
|
||||
Shadow *shadow = m_window->shadow();
|
||||
if (shadow) {
|
||||
if (!m_shadowItem || m_shadowItem->shadow() != shadow) {
|
||||
m_shadowItem.reset(new ShadowItem(shadow, m_window, this));
|
||||
|
|
|
@ -38,8 +38,6 @@ public:
|
|||
ShadowItem *shadowItem() const;
|
||||
Toplevel *window() const;
|
||||
|
||||
void setShadow(Shadow *shadow);
|
||||
|
||||
protected:
|
||||
explicit WindowItem(Toplevel *window, Item *parent = nullptr);
|
||||
void updateSurfaceItem(SurfaceItem *surfaceItem);
|
||||
|
@ -47,6 +45,7 @@ protected:
|
|||
private Q_SLOTS:
|
||||
void handleWindowClosed(Toplevel *original, Deleted *deleted);
|
||||
void updateDecorationItem();
|
||||
void updateShadowItem();
|
||||
void updateSurfacePosition();
|
||||
void updateSurfaceVisibility();
|
||||
|
||||
|
|
|
@ -493,6 +493,7 @@ Workspace::~Workspace()
|
|||
|
||||
for (auto it = deleted.begin(); it != deleted.end();) {
|
||||
Q_EMIT deletedRemoved(*it);
|
||||
(*it)->finishCompositing();
|
||||
it = deleted.erase(it);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue