diff --git a/scene.cpp b/scene.cpp index 424edff61f..333514de4a 100644 --- a/scene.cpp +++ b/scene.cpp @@ -98,6 +98,9 @@ Scene::Scene(Workspace* ws) Scene::~Scene() { + foreach (Window *w, m_windows) { + delete w; + } } // returns mask and possibly modified region @@ -391,6 +394,64 @@ void Scene::paintSimpleScreen(int orig_mask, QRegion region) } } +void Scene::windowAdded(Toplevel *c) +{ + assert(!m_windows.contains(c)); + Scene::Window *w = createWindow(c); + m_windows[ c ] = w; + 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*))); + c->effectWindow()->setSceneWindow(w); + c->getShadow(); + w->updateShadow(c->shadow()); +} + +void Scene::windowClosed(Toplevel *c, Deleted *deleted) +{ + assert(m_windows.contains(c)); + if (deleted != NULL) { + // replace c with deleted + Window* w = m_windows.take(c); + w->updateToplevel(deleted); + if (w->shadow()) { + w->shadow()->setToplevel(deleted); + } + m_windows[ deleted ] = w; + } else { + delete m_windows.take(c); + c->effectWindow()->setSceneWindow(NULL); + } +} + +void Scene::windowDeleted(Deleted *c) +{ + assert(m_windows.contains(c)); + delete m_windows.take(c); + c->effectWindow()->setSceneWindow(NULL); +} + +void Scene::windowGeometryShapeChanged(Toplevel *c) +{ + if (!m_windows.contains(c)) // this is ok, shape is not valid by default + return; + Window *w = m_windows[ c ]; + w->discardShape(); +} + +void Scene::createStackingOrder(ToplevelList toplevels) +{ + // TODO: cache the stacking_order in case it has not changed + foreach (Toplevel *c, toplevels) { + assert(m_windows.contains(c)); + stacking_order.append(m_windows[ c ]); + } +} + +void Scene::clearStackingOrder() +{ + stacking_order.clear(); +} + static Scene::Window *s_recursionCheck = NULL; void Scene::paintWindow(Window* w, int mask, QRegion region, WindowQuadList quads) diff --git a/scene.h b/scene.h index bd3e84ee29..adae150c9f 100644 --- a/scene.h +++ b/scene.h @@ -65,7 +65,7 @@ public: // Used to mainly discard cached data. // a new window has been created - virtual void windowAdded(Toplevel*) = 0; + void windowAdded(Toplevel*); /** * @brief Creates the Scene backend of an EffectFrame. * @@ -123,12 +123,15 @@ public: public Q_SLOTS: // a window has been destroyed - virtual void windowDeleted(KWin::Deleted*) = 0; + void windowDeleted(KWin::Deleted*); // shape/size of a window changed - virtual void windowGeometryShapeChanged(KWin::Toplevel* c) = 0; + void windowGeometryShapeChanged(KWin::Toplevel* c); // a window has been closed - virtual void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted) = 0; + void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted); protected: + virtual Window *createWindow(Toplevel *toplevel) = 0; + void createStackingOrder(ToplevelList toplevels); + void clearStackingOrder(); // shared implementation, starts painting the screen void paintScreen(int *mask, const QRegion &damage, const QRegion &repaint, QRegion *updateRegion, QRegion *validRegion); @@ -168,8 +171,6 @@ protected: int mask; WindowQuadList quads; }; - // windows in their stacking order - QVector< Window* > stacking_order; // The region which actually has been painted by paintScreen() and should be // copied from the buffer to the screen. I.e. the region returned from Scene::paintScreen(). // Since prePaintWindow() can extend areas to paint, these changes would have to propagate @@ -187,6 +188,9 @@ protected: private: void paintWindowThumbnails(Scene::Window *w, QRegion region, qreal opacity, qreal brightness, qreal saturation); void paintDesktopThumbnails(Scene::Window *w); + QHash< Toplevel*, Window* > m_windows; + // windows in their stacking order + QVector< Window* > stacking_order; }; // The base class for windows representations in composite backends diff --git a/scene_opengl.cpp b/scene_opengl.cpp index e3520987ec..81b909c41a 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -182,9 +182,6 @@ SceneOpenGL::~SceneOpenGL() // backend might be still needed for a different scene delete m_backend; } - foreach (Window * w, windows) { - delete w; - } // do cleanup after initBuffer() SceneOpenGL::EffectFrame::cleanup(); checkGLError("Cleanup"); @@ -360,11 +357,7 @@ void SceneOpenGL::handleGraphicsReset(GLenum status) qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels) { // actually paint the frame, flushed with the NEXT frame - foreach (Toplevel * c, toplevels) { - // TODO: cache the stacking_order in case it has not changed - assert(windows.contains(c)); - stacking_order.append(windows[ c ]); - } + createStackingOrder(toplevels); m_backend->makeCurrent(); QRegion repaint = m_backend->prepareRenderingFrame(); @@ -409,7 +402,7 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels) m_backend->endRenderingFrame(validRegion, updateRegion); // do cleanup - stacking_order.clear(); + clearStackingOrder(); checkGLError("PostPaint"); return m_backend->renderTime(); } @@ -487,51 +480,6 @@ void SceneOpenGL::extendPaintRegion(QRegion ®ion, bool opaqueFullscreen) } } -void SceneOpenGL::windowAdded(Toplevel* c) -{ - assert(!windows.contains(c)); - Window *w = createWindow(c); - windows[ c ] = w; - w->setScene(this); - 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*))); - c->effectWindow()->setSceneWindow(windows[ c ]); - c->getShadow(); - windows[ c ]->updateShadow(c->shadow()); -} - -void SceneOpenGL::windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted) -{ - assert(windows.contains(c)); - if (deleted != NULL) { - // 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); - c->effectWindow()->setSceneWindow(NULL); - } -} - -void SceneOpenGL::windowDeleted(Deleted* c) -{ - assert(windows.contains(c)); - delete windows.take(c); - c->effectWindow()->setSceneWindow(NULL); -} - -void SceneOpenGL::windowGeometryShapeChanged(KWin::Toplevel* c) -{ - if (!windows.contains(c)) // this is ok, shape is not valid - return; // by default - Window* w = windows[ c ]; - w->discardShape(); -} - SceneOpenGL::Texture *SceneOpenGL::createTexture() { return new Texture(m_backend); @@ -754,9 +702,11 @@ void SceneOpenGL2::doPaintBackground(const QVector< float >& vertices) vbo->render(GL_TRIANGLES); } -SceneOpenGL::Window *SceneOpenGL2::createWindow(Toplevel *t) +Scene::Window *SceneOpenGL2::createWindow(Toplevel *t) { - return new SceneOpenGL2Window(t); + SceneOpenGL2Window *w = new SceneOpenGL2Window(t); + w->setScene(this); + return w; } void SceneOpenGL2::finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data) @@ -925,9 +875,11 @@ void SceneOpenGL1::screenGeometryChanged(const QSize &size) m_resetModelViewProjectionMatrix = true; } -SceneOpenGL::Window *SceneOpenGL1::createWindow(Toplevel *t) +Scene::Window *SceneOpenGL1::createWindow(Toplevel *t) { - return new SceneOpenGL1Window(t); + SceneOpenGL1Window *w = new SceneOpenGL1Window(t); + w->setScene(this); + return w; } #endif diff --git a/scene_opengl.h b/scene_opengl.h index dfe2b11bde..c17ba2377a 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -48,8 +48,6 @@ public: virtual bool initFailed() const; virtual bool hasPendingFlush() const; virtual qint64 paint(QRegion damage, ToplevelList windows); - virtual void windowAdded(Toplevel*); - virtual void windowDeleted(Deleted*); virtual Scene::EffectFrame *createEffectFrame(EffectFrameImpl *frame); virtual Shadow *createShadow(Toplevel *toplevel); virtual void screenGeometryChanged(const QSize &size); @@ -90,20 +88,15 @@ protected: void handleGraphicsReset(GLenum status); virtual void doPaintBackground(const QVector &vertices) = 0; - virtual SceneOpenGL::Window *createWindow(Toplevel *t) = 0; Q_SIGNALS: void resetCompositing(); -public Q_SLOTS: - virtual void windowGeometryShapeChanged(KWin::Toplevel* c); - virtual void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted); protected: bool init_ok; private: bool viewportLimitsMatched(const QSize &size) const; private: - QHash< Toplevel*, Window* > windows; bool m_debug; OpenGLBackend *m_backend; }; @@ -125,7 +118,7 @@ public: protected: virtual void paintGenericScreen(int mask, ScreenPaintData data); virtual void doPaintBackground(const QVector< float >& vertices); - virtual SceneOpenGL::Window *createWindow(Toplevel *t); + virtual Scene::Window *createWindow(Toplevel *t); virtual void finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data); virtual void paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data); @@ -159,7 +152,7 @@ public: protected: virtual void paintGenericScreen(int mask, ScreenPaintData data); virtual void doPaintBackground(const QVector< float >& vertices); - virtual SceneOpenGL::Window *createWindow(Toplevel *t); + virtual Scene::Window *createWindow(Toplevel *t); private: void setupModelViewProjectionMatrix(); diff --git a/scene_xrender.cpp b/scene_xrender.cpp index d10e4ea150..e4e7edabdf 100644 --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -120,8 +120,6 @@ SceneXrender::~SceneXrender() xcb_render_free_picture(connection(), buffer); buffer = XCB_RENDER_PICTURE_NONE; m_overlayWindow->destroy(); - foreach (Window * w, windows) - delete w; delete m_overlayWindow; } @@ -185,10 +183,7 @@ qint64 SceneXrender::paint(QRegion damage, ToplevelList toplevels) QElapsedTimer renderTimer; renderTimer.start(); - foreach (Toplevel * c, toplevels) { - assert(windows.contains(c)); - stacking_order.append(windows[ c ]); - } + createStackingOrder(toplevels); int mask = 0; QRegion updateRegion, validRegion; @@ -199,7 +194,7 @@ qint64 SceneXrender::paint(QRegion damage, ToplevelList toplevels) present(mask, updateRegion); // do cleanup - stacking_order.clear(); + clearStackingOrder(); return renderTimer.nsecsElapsed(); } @@ -245,47 +240,9 @@ void SceneXrender::paintBackground(QRegion region) xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, buffer, col, rects.count(), rects.data()); } -void SceneXrender::windowGeometryShapeChanged(KWin::Toplevel* c) +Scene::Window *SceneXrender::createWindow(Toplevel *toplevel) { - if (!windows.contains(c)) // this is ok, shape is not valid by default - return; - Window* w = windows[ c ]; - w->discardShape(); -} - -void SceneXrender::windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted) -{ - assert(windows.contains(c)); - if (deleted != NULL) { - // 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); - c->effectWindow()->setSceneWindow(NULL); - } -} - -void SceneXrender::windowDeleted(Deleted* c) -{ - assert(windows.contains(c)); - delete windows.take(c); - c->effectWindow()->setSceneWindow(NULL); -} - -void SceneXrender::windowAdded(Toplevel* c) -{ - assert(!windows.contains(c)); - windows[ c ] = new Window(c); - 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*))); - c->effectWindow()->setSceneWindow(windows[ c ]); - c->getShadow(); - windows[ c ]->updateShadow(c->shadow()); + return new Window(toplevel); } Scene::EffectFrame *SceneXrender::createEffectFrame(EffectFrameImpl *frame) diff --git a/scene_xrender.h b/scene_xrender.h index b1cf8a5d41..4c4552f3be 100644 --- a/scene_xrender.h +++ b/scene_xrender.h @@ -43,8 +43,6 @@ public: return XRenderCompositing; } virtual qint64 paint(QRegion damage, ToplevelList windows); - virtual void windowAdded(Toplevel*); - virtual void windowDeleted(Deleted*); virtual Scene::EffectFrame *createEffectFrame(EffectFrameImpl *frame); virtual Shadow *createShadow(Toplevel *toplevel); virtual void screenGeometryChanged(const QSize &size); @@ -53,12 +51,10 @@ public: return m_overlayWindow; } protected: + virtual Scene::Window *createWindow(Toplevel *toplevel); virtual void paintBackground(QRegion region); virtual void paintGenericScreen(int mask, ScreenPaintData data); virtual void paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data); -public Q_SLOTS: - virtual void windowGeometryShapeChanged(KWin::Toplevel* c); - virtual void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted); private: void createBuffer(); void present(int mask, QRegion damage); @@ -68,7 +64,6 @@ private: static xcb_render_picture_t buffer; static ScreenPaintData screen_paint; class Window; - QHash< Toplevel*, Window* > windows; OverlayWindow* m_overlayWindow; bool init_ok; };