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

23
scene.h
View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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