Move ownership on Shadow from Toplevel to Scene::Window

The Shadow is clearly an aspect of the compositor. Therefore the
Shadow has to be owned and controlled by the Scene::Window.
Nevertheless Toplevel needs to know about the Shadow cause of reading
the property.
icc-effect-5.14.5
Martin Gräßlin 2011-04-03 11:31:33 +02:00
parent c82fed057f
commit 38e9ab9a4e
8 changed files with 76 additions and 27 deletions

View File

@ -353,6 +353,7 @@ QRegion Scene::selfCheckRegion() const
Scene::Window::Window(Toplevel * c)
: toplevel(c)
, filter(ImageFilterFast)
, m_shadow(NULL)
, disable_painting(0)
, shape_valid(false)
, cached_quad_list(NULL)
@ -362,6 +363,7 @@ Scene::Window::Window(Toplevel * c)
Scene::Window::~Window()
{
delete cached_quad_list;
delete m_shadow;
}
void Scene::Window::discardShape()
@ -494,8 +496,8 @@ WindowQuadList Scene::Window::buildQuads(bool force) const
ret += makeQuads(WindowQuadDecoration, right);
}
}
if (toplevel->hasShadow()) {
ret << toplevel->shadow()->shadowQuads();
if (m_shadow) {
ret << m_shadow->shadowQuads();
}
effects->buildQuads(static_cast<Client*>(toplevel)->effectWindow(), ret);
cached_quad_list = new WindowQuadList(ret);

23
scene.h
View File

@ -35,6 +35,7 @@ class Deleted;
class EffectFrameImpl;
class EffectWindowImpl;
class LanczosFilter;
class Shadow;
// The base class for compositing backends.
class Scene
@ -210,10 +211,14 @@ public:
// creates initial quad list for the window
virtual WindowQuadList buildQuads(bool force = false) const;
void suspendUnredirect(bool suspend);
void updateShadow(Shadow* shadow);
const Shadow* shadow() const;
Shadow* shadow();
protected:
WindowQuadList makeQuads(WindowQuadType type, const QRegion& reg) const;
Toplevel* toplevel;
ImageFilterType filter;
Shadow *m_shadow;
private:
int disable_painting;
mutable QRegion shape_region;
@ -319,6 +324,24 @@ void Scene::Window::suspendUnredirect(bool suspend)
toplevel->suspendUnredirect(suspend);
}
inline
void Scene::Window::updateShadow(Shadow* shadow)
{
m_shadow = shadow;
}
inline
const Shadow* Scene::Window::shadow() const
{
return m_shadow;
}
inline
Shadow* Scene::Window::shadow()
{
return m_shadow;
}
} // namespace
#endif

View File

@ -235,6 +235,8 @@ void SceneOpenGL::windowAdded(Toplevel* c)
assert(!windows.contains(c));
windows[ c ] = new Window(c);
c->effectWindow()->setSceneWindow(windows[ c ]);
c->getShadow();
windows[ c ]->updateShadow(c->shadow());
}
void SceneOpenGL::windowClosed(Toplevel* c, Deleted* deleted)
@ -244,6 +246,9 @@ void SceneOpenGL::windowClosed(Toplevel* c, Deleted* deleted)
// replace c with deleted
Window* w = windows.take(c);
w->updateToplevel(deleted);
if (w->shadow()) {
w->shadow()->setToplevel(deleted);
}
windows[ deleted ] = w;
} else {
delete windows.take(c);
@ -513,7 +518,7 @@ void SceneOpenGL::Window::performPaint(int mask, QRegion region, WindowPaintData
vbo->reset();
// shadow
if (toplevel->hasShadow()) {
if (m_shadow) {
paintShadow(WindowQuadShadowTop, region, data);
paintShadow(WindowQuadShadowTopRight, region, data);
paintShadow(WindowQuadShadowRight, region, data);
@ -669,7 +674,7 @@ void SceneOpenGL::Window::paintDecoration(const QPixmap* decoration, TextureType
void SceneOpenGL::Window::paintShadow(WindowQuadType type, const QRegion &region, const WindowPaintData &data)
{
WindowQuadList quads = data.quads.select(type);
Texture *texture = static_cast<SceneOpenGLShadow*>(toplevel->shadow())->textureForQuadType(type);
Texture *texture = static_cast<SceneOpenGLShadow*>(m_shadow)->textureForQuadType(type);
if (!texture) {
return;
}

View File

@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "shadow.h"
// kwin
#include "atoms.h"
#include "effects.h"
#include "toplevel.h"
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
#include "scene_opengl.h"
@ -29,8 +30,7 @@ namespace KWin
{
Shadow::Shadow(Toplevel *toplevel)
: QObject(toplevel)
, m_topLevel(toplevel)
: m_topLevel(toplevel)
{
}
@ -56,6 +56,9 @@ Shadow *Shadow::createShadow(Toplevel *toplevel)
delete shadow;
return NULL;
}
if (toplevel->effectWindow() && toplevel->effectWindow()->sceneWindow()) {
toplevel->effectWindow()->sceneWindow()->updateShadow(shadow);
}
}
return shadow;
} else {
@ -181,7 +184,6 @@ bool Shadow::updateShadow()
void Shadow::setToplevel(Toplevel *topLevel)
{
m_topLevel = topLevel;
setParent(topLevel);
}
} // namespace

View File

@ -52,7 +52,7 @@ public:
/**
* @return Region of the shadow.
**/
const QRegion &shadowRegion() {
const QRegion &shadowRegion() const {
return m_shadowRegion;
};
/**

View File

@ -34,7 +34,6 @@ Toplevel::Toplevel(Workspace* ws)
: vis(NULL)
, info(NULL)
, ready_for_painting(true)
, m_shadow(NULL)
, client(None)
, frame(None)
, wspace(ws)
@ -133,10 +132,6 @@ void Toplevel::copyToDeleted(Toplevel* c)
// this needs to be done already here, otherwise 'c' could very likely
// call discardWindowPixmap() in something called during cleanup
c->window_pix = None;
if (c->hasShadow()) {
m_shadow = c->m_shadow;
m_shadow->setToplevel(this);
}
}
// before being deleted, remove references to everything that's now
@ -144,7 +139,6 @@ void Toplevel::copyToDeleted(Toplevel* c)
void Toplevel::disownDataPassedToDeleted()
{
info = NULL;
m_shadow = NULL;
}
QRect Toplevel::visibleRect() const
@ -361,21 +355,37 @@ bool Toplevel::isOnScreen(int screen) const
void Toplevel::getShadow()
{
if (hasShadow()) {
m_shadow->updateShadow();
effectWindow()->sceneWindow()->shadow()->updateShadow();
} else {
m_shadow = Shadow::createShadow(this);
Shadow::createShadow(this);
addRepaintFull();
}
}
bool Toplevel::hasShadow() const
{
return m_shadow != NULL;
if (effectWindow() && effectWindow()->sceneWindow()) {
return effectWindow()->sceneWindow()->shadow() != NULL;
}
return false;
}
Shadow *Toplevel::shadow() const
Shadow *Toplevel::shadow()
{
return m_shadow;
if (effectWindow() && effectWindow()->sceneWindow()) {
return effectWindow()->sceneWindow()->shadow();
} else {
return NULL;
}
}
const Shadow *Toplevel::shadow() const
{
if (effectWindow() && effectWindow()->sceneWindow()) {
return effectWindow()->sceneWindow()->shadow();
} else {
return NULL;
}
}
} // namespace

View File

@ -135,6 +135,7 @@ public:
QRegion damage() const;
void resetDamage(const QRect& r);
EffectWindowImpl* effectWindow();
const EffectWindowImpl* effectWindow() const;
/**
* @returns Whether the Toplevel has a Shadow or not
@ -149,7 +150,13 @@ public:
* @returns The Shadow belonging to this Toplevel, may be @c NULL.
* @see hasShadow
**/
Shadow *shadow() const;
const Shadow *shadow() const;
Shadow *shadow();
/**
* Updates the Shadow associated with this Toplevel from X11 Property.
* Call this method when the Property changes or Compositing is started.
**/
void getShadow();
signals:
void opacityChanged(KWin::Toplevel* toplevel, qreal oldOpacity);
@ -173,11 +180,6 @@ protected:
void getWmClientMachine();
void getResourceClass();
void getWindowRole();
/**
* Updates the Shadow associated with this Toplevel from X11 Property.
* Call this method when the Property changes or Compositing is started.
**/
void getShadow();
virtual void debug(QDebug& stream) const = 0;
void copyToDeleted(Toplevel* c);
void disownDataPassedToDeleted();
@ -190,7 +192,6 @@ protected:
NETWinInfo2* info;
bool ready_for_painting;
QRegion repaints_region; // updating, repaint just requires repaint of that area
Shadow *m_shadow;
private:
static QByteArray staticWindowRole(WId);
static QByteArray staticSessionId(WId);
@ -414,6 +415,12 @@ EffectWindowImpl* Toplevel::effectWindow()
return effect_window;
}
inline
const EffectWindowImpl* Toplevel::effectWindow() const
{
return effect_window;
}
inline bool Toplevel::isOnAllDesktops() const
{
return desktop() == NET::OnAllDesktops;

View File

@ -92,7 +92,7 @@ void Unmanaged::release()
XShapeSelectInput(display(), window(), NoEventMask);
XSelectInput(display(), window(), NoEventMask);
}
addWorkspaceRepaint(visibleRect());
addWorkspaceRepaint(del->visibleRect());
disownDataPassedToDeleted();
del->unrefWindow();
deleteUnmanaged(this, Allowed);