diff --git a/scene.cpp b/scene.cpp index c85d325b31..6ef81f8c52 100644 --- a/scene.cpp +++ b/scene.cpp @@ -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(toplevel)->effectWindow(), ret); cached_quad_list = new WindowQuadList(ret); diff --git a/scene.h b/scene.h index 89e6038b24..564cb74761 100644 --- a/scene.h +++ b/scene.h @@ -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 diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 07f1c87953..fc249ce85a 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -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 ®ion, const WindowPaintData &data) { WindowQuadList quads = data.quads.select(type); - Texture *texture = static_cast(toplevel->shadow())->textureForQuadType(type); + Texture *texture = static_cast(m_shadow)->textureForQuadType(type); if (!texture) { return; } diff --git a/shadow.cpp b/shadow.cpp index 5f3fa4de56..309a146b18 100644 --- a/shadow.cpp +++ b/shadow.cpp @@ -20,6 +20,7 @@ along with this program. If not, see . #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 diff --git a/shadow.h b/shadow.h index eb2009f610..ee6dec35dc 100644 --- a/shadow.h +++ b/shadow.h @@ -52,7 +52,7 @@ public: /** * @return Region of the shadow. **/ - const QRegion &shadowRegion() { + const QRegion &shadowRegion() const { return m_shadowRegion; }; /** diff --git a/toplevel.cpp b/toplevel.cpp index a5766b7331..b73c152256 100644 --- a/toplevel.cpp +++ b/toplevel.cpp @@ -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 diff --git a/toplevel.h b/toplevel.h index 1ac1538165..49ac824b71 100644 --- a/toplevel.h +++ b/toplevel.h @@ -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; diff --git a/unmanaged.cpp b/unmanaged.cpp index 6fcd47398d..7c36451b49 100644 --- a/unmanaged.cpp +++ b/unmanaged.cpp @@ -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);