[scene] Rebuild window quads when sub-surface tree changes
Sub-surface contribute to the window quads cache. So, we must re-build it, if any sub-surface has been changed. Differential Revision: https://phabricator.kde.org/D29131
This commit is contained in:
parent
f2c8981f7e
commit
9bfcfb7f74
4 changed files with 203 additions and 12 deletions
|
@ -491,6 +491,7 @@ set(kwin_SRCS
|
|||
scripting/workspace_wrapper.cpp
|
||||
shadow.cpp
|
||||
sm.cpp
|
||||
subsurfacemonitor.cpp
|
||||
syncalarmx11filter.cpp
|
||||
thumbnailitem.cpp
|
||||
toplevel.cpp
|
||||
|
|
38
scene.cpp
38
scene.cpp
|
@ -77,6 +77,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "overlaywindow.h"
|
||||
#include "screens.h"
|
||||
#include "shadow.h"
|
||||
#include "subsurfacemonitor.h"
|
||||
#include "wayland_server.h"
|
||||
|
||||
#include "thumbnailitem.h"
|
||||
|
@ -395,25 +396,38 @@ void Scene::addToplevel(Toplevel *c)
|
|||
Q_ASSERT(!m_windows.contains(c));
|
||||
Scene::Window *w = createWindow(c);
|
||||
m_windows[ c ] = w;
|
||||
|
||||
auto discardPixmap = [w]() { w->discardPixmap(); };
|
||||
auto discardQuads = [w]() { w->invalidateQuadsCache(); };
|
||||
|
||||
connect(c, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), SLOT(windowGeometryShapeChanged(KWin::Toplevel*)));
|
||||
connect(c, SIGNAL(windowClosed(KWin::Toplevel*,KWin::Deleted*)), SLOT(windowClosed(KWin::Toplevel*,KWin::Deleted*)));
|
||||
//A change of scale won't affect the geometry in compositor co-ordinates, but will affect the window quads.
|
||||
if (c->surface()) {
|
||||
connect(c->surface(), &KWaylandServer::SurfaceInterface::scaleChanged, this, std::bind(&Scene::windowGeometryShapeChanged, this, c));
|
||||
// We generate window quads for sub-surfaces so it's quite important to discard
|
||||
// the pixmap tree and cached window quads when the sub-surface tree is changed.
|
||||
SubSurfaceMonitor *monitor = new SubSurfaceMonitor(c->surface(), this);
|
||||
|
||||
// TODO(vlad): Is there a more efficient way to manage window pixmap trees?
|
||||
connect(monitor, &SubSurfaceMonitor::subSurfaceAdded, this, discardPixmap);
|
||||
connect(monitor, &SubSurfaceMonitor::subSurfaceRemoved, this, discardPixmap);
|
||||
connect(monitor, &SubSurfaceMonitor::subSurfaceResized, this, discardPixmap);
|
||||
connect(monitor, &SubSurfaceMonitor::subSurfaceMapped, this, discardPixmap);
|
||||
connect(monitor, &SubSurfaceMonitor::subSurfaceUnmapped, this, discardPixmap);
|
||||
|
||||
connect(monitor, &SubSurfaceMonitor::subSurfaceAdded, this, discardQuads);
|
||||
connect(monitor, &SubSurfaceMonitor::subSurfaceRemoved, this, discardQuads);
|
||||
connect(monitor, &SubSurfaceMonitor::subSurfaceMoved, this, discardQuads);
|
||||
connect(monitor, &SubSurfaceMonitor::subSurfaceResized, this, discardQuads);
|
||||
connect(monitor, &SubSurfaceMonitor::subSurfaceMapped, this, discardQuads);
|
||||
connect(monitor, &SubSurfaceMonitor::subSurfaceUnmapped, this, discardQuads);
|
||||
|
||||
connect(c->surface(), &KWaylandServer::SurfaceInterface::scaleChanged, this, discardQuads);
|
||||
}
|
||||
connect(c, &Toplevel::screenScaleChanged, this,
|
||||
[this, c] {
|
||||
windowGeometryShapeChanged(c);
|
||||
}
|
||||
);
|
||||
connect(c, &Toplevel::screenScaleChanged, this, discardQuads);
|
||||
c->effectWindow()->setSceneWindow(w);
|
||||
c->updateShadow();
|
||||
w->updateShadow(c->shadow());
|
||||
connect(c, &Toplevel::shadowChanged, this,
|
||||
[w] {
|
||||
w->invalidateQuadsCache();
|
||||
}
|
||||
);
|
||||
connect(c, &Toplevel::shadowChanged, this, discardQuads);
|
||||
}
|
||||
|
||||
void Scene::removeToplevel(Toplevel *toplevel)
|
||||
|
|
95
subsurfacemonitor.cpp
Normal file
95
subsurfacemonitor.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#include "subsurfacemonitor.h"
|
||||
|
||||
#include <KWaylandServer/subcompositor_interface.h>
|
||||
#include <KWaylandServer/surface_interface.h>
|
||||
|
||||
using namespace KWaylandServer;
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
SubSurfaceMonitor::SubSurfaceMonitor(SurfaceInterface *surface, QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
registerSurface(surface);
|
||||
}
|
||||
|
||||
void SubSurfaceMonitor::registerSubSurface(SubSurfaceInterface *subSurface)
|
||||
{
|
||||
SurfaceInterface *surface = subSurface->surface();
|
||||
|
||||
connect(subSurface, &SubSurfaceInterface::positionChanged,
|
||||
this, &SubSurfaceMonitor::subSurfaceMoved);
|
||||
connect(surface, &SurfaceInterface::sizeChanged,
|
||||
this, &SubSurfaceMonitor::subSurfaceResized);
|
||||
connect(surface, &SurfaceInterface::mapped,
|
||||
this, &SubSurfaceMonitor::subSurfaceMapped);
|
||||
connect(surface, &SurfaceInterface::unmapped,
|
||||
this, &SubSurfaceMonitor::subSurfaceUnmapped);
|
||||
|
||||
registerSurface(surface);
|
||||
}
|
||||
|
||||
void SubSurfaceMonitor::unregisterSubSurface(SubSurfaceInterface *subSurface)
|
||||
{
|
||||
SurfaceInterface *surface = subSurface->surface();
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
disconnect(subSurface, &SubSurfaceInterface::positionChanged,
|
||||
this, &SubSurfaceMonitor::subSurfaceMoved);
|
||||
disconnect(surface, &SurfaceInterface::sizeChanged,
|
||||
this, &SubSurfaceMonitor::subSurfaceResized);
|
||||
disconnect(surface, &SurfaceInterface::mapped,
|
||||
this, &SubSurfaceMonitor::subSurfaceMapped);
|
||||
disconnect(surface, &SurfaceInterface::unmapped,
|
||||
this, &SubSurfaceMonitor::subSurfaceUnmapped);
|
||||
|
||||
unregisterSurface(surface);
|
||||
}
|
||||
|
||||
void SubSurfaceMonitor::registerSurface(SurfaceInterface *surface)
|
||||
{
|
||||
connect(surface, &SurfaceInterface::childSubSurfaceAdded,
|
||||
this, &SubSurfaceMonitor::subSurfaceAdded);
|
||||
connect(surface, &SurfaceInterface::childSubSurfaceRemoved,
|
||||
this, &SubSurfaceMonitor::subSurfaceRemoved);
|
||||
connect(surface, &SurfaceInterface::childSubSurfaceAdded,
|
||||
this, &SubSurfaceMonitor::registerSubSurface);
|
||||
connect(surface, &SurfaceInterface::childSubSurfaceRemoved,
|
||||
this, &SubSurfaceMonitor::unregisterSubSurface);
|
||||
}
|
||||
|
||||
void SubSurfaceMonitor::unregisterSurface(SurfaceInterface *surface)
|
||||
{
|
||||
disconnect(surface, &SurfaceInterface::childSubSurfaceAdded,
|
||||
this, &SubSurfaceMonitor::subSurfaceAdded);
|
||||
disconnect(surface, &SurfaceInterface::childSubSurfaceRemoved,
|
||||
this, &SubSurfaceMonitor::subSurfaceRemoved);
|
||||
disconnect(surface, &SurfaceInterface::childSubSurfaceAdded,
|
||||
this, &SubSurfaceMonitor::registerSubSurface);
|
||||
disconnect(surface, &SurfaceInterface::childSubSurfaceRemoved,
|
||||
this, &SubSurfaceMonitor::unregisterSubSurface);
|
||||
}
|
||||
|
||||
} // namespace KWin
|
81
subsurfacemonitor.h
Normal file
81
subsurfacemonitor.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
class SurfaceInterface;
|
||||
class SubSurfaceInterface;
|
||||
}
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
/**
|
||||
* The SubSurfaceMonitor class provides a convenient way for monitoring changes in
|
||||
* sub-surface trees, e.g. addition or removal of sub-surfaces, etc.
|
||||
*/
|
||||
class SubSurfaceMonitor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructs a SubSurfaceTreeMonitor with the given @a surface and @a parent.
|
||||
*/
|
||||
SubSurfaceMonitor(KWaylandServer::SurfaceInterface *surface, QObject *parent);
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This signal is emitted when a new sub-surface has been added to the tree.
|
||||
*/
|
||||
void subSurfaceAdded();
|
||||
/**
|
||||
* This signal is emitted when a sub-surface has been removed from the tree.
|
||||
*/
|
||||
void subSurfaceRemoved();
|
||||
/**
|
||||
* This signal is emitted when a sub-surface has been moved relative to its parent.
|
||||
*/
|
||||
void subSurfaceMoved();
|
||||
/**
|
||||
* This signal is emitted when a sub-surface has been resized.
|
||||
*/
|
||||
void subSurfaceResized();
|
||||
/**
|
||||
* This signal is emitted when a sub-surface is mapped.
|
||||
*/
|
||||
void subSurfaceMapped();
|
||||
/**
|
||||
* This signal is emitted when a sub-surface is unmapped.
|
||||
*/
|
||||
void subSurfaceUnmapped();
|
||||
|
||||
private:
|
||||
void registerSubSurface(KWaylandServer::SubSurfaceInterface *subSurface);
|
||||
void unregisterSubSurface(KWaylandServer::SubSurfaceInterface *subSurface);
|
||||
void registerSurface(KWaylandServer::SurfaceInterface *surface);
|
||||
void unregisterSurface(KWaylandServer::SurfaceInterface *surface);
|
||||
};
|
||||
|
||||
} // namespace KWin
|
Loading…
Reference in a new issue