From ba27d2ebb00fb5dd64be8a6fc99cba72c0392c66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 29 Jul 2009 11:07:28 +0000 Subject: [PATCH] Copy decoration pixmaps to Deleted. By that we see the decoration also when having a fade out animation. As this is a bigger commit I will wait with backporting to 4.3 for something about two or three weeks and will only backport if nobody yells. BUG: 201780 svn path=/trunk/KDE/kdebase/workspace/; revision=1004096 --- client.h | 5 +++++ composite.cpp | 6 ++++++ deleted.cpp | 39 ++++++++++++++++++++++++++++++++++++ deleted.h | 19 ++++++++++++++++++ scene_opengl.cpp | 41 ++++++++++++++++++++++++++++---------- scene_xrender.cpp | 50 ++++++++++++++++++++++++++++++++++------------- toplevel.h | 4 ++-- 7 files changed, 138 insertions(+), 26 deletions(-) diff --git a/client.h b/client.h index a729aa9004..1fe5a81f02 100644 --- a/client.h +++ b/client.h @@ -306,6 +306,11 @@ class Client const QPixmap *bottomDecoPixmap() const { return &decorationPixmapBottom; } const QPixmap *rightDecoPixmap() const { return &decorationPixmapRight; } + int paddingLeft() const { return padding_left; } + int paddingRight() const { return padding_right; } + int paddingTop() const { return padding_top; } + int paddingBottom() const { return padding_bottom; } + bool decorationPixmapRequiresRepaint(); void ensureDecorationPixmapsPainted(); diff --git a/composite.cpp b/composite.cpp index c71c707927..00b281039b 100644 --- a/composite.cpp +++ b/composite.cpp @@ -997,4 +997,10 @@ bool Deleted::shouldUnredirect() const return false; } +void Deleted::addRepaintFull() + { + repaints_region = decorationRect(); + workspace()->checkCompositeTimer(); + } + } // namespace diff --git a/deleted.cpp b/deleted.cpp index 4e97a76d20..2a29013b89 100644 --- a/deleted.cpp +++ b/deleted.cpp @@ -30,6 +30,11 @@ namespace KWin Deleted::Deleted( Workspace* ws ) : Toplevel( ws ) , delete_refcount( 1 ) + , no_border( true ) + , padding_left( 0 ) + , padding_top( 0 ) + , padding_right( 0 ) + , padding_bottom( 0 ) { } @@ -63,6 +68,27 @@ void Deleted::copyToDeleted( Toplevel* c ) contentsRect = QRect( c->clientPos(), c->clientSize()); if( WinInfo* cinfo = dynamic_cast< WinInfo* >( info )) cinfo->disable(); + Client* client = dynamic_cast(c); + if( client ) + { + no_border = client->noBorder(); + padding_left = client->paddingLeft(); + padding_right = client->paddingRight(); + padding_bottom = client->paddingBottom(); + padding_top = client->paddingTop(); + if( !no_border ) + { + client->layoutDecorationRects(decoration_left, + decoration_top, + decoration_right, + decoration_bottom, + Client::WindowRelative); + decorationPixmapLeft = *client->leftDecoPixmap(); + decorationPixmapRight = *client->rightDecoPixmap(); + decorationPixmapTop = *client->topDecoPixmap(); + decorationPixmapBottom = *client->bottomDecoPixmap(); + } + } } void Deleted::unrefWindow( bool delay ) @@ -97,6 +123,19 @@ void Deleted::debug( kdbgstream& stream ) const stream << "\'ID:" << window() << "\' (deleted)"; } +void Deleted::layoutDecorationRects(QRect& left, QRect& top, QRect& right, QRect& bottom) const + { + left = decoration_left; + top = decoration_top; + right = decoration_right; + bottom = decoration_bottom; + } + +QRect Deleted::decorationRect() const + { + return rect().adjusted(-padding_left, -padding_top, padding_top, padding_bottom); + } + } // namespace #include "deleted.moc" diff --git a/deleted.h b/deleted.h index a8192662c6..d3aedb880d 100644 --- a/deleted.h +++ b/deleted.h @@ -39,6 +39,14 @@ class Deleted virtual int desktop() const; virtual QPoint clientPos() const; virtual QSize clientSize() const; + const QPixmap *topDecoPixmap() const { return &decorationPixmapTop; } + const QPixmap *leftDecoPixmap() const { return &decorationPixmapLeft; } + const QPixmap *bottomDecoPixmap() const { return &decorationPixmapBottom; } + const QPixmap *rightDecoPixmap() const { return &decorationPixmapRight; } + bool noBorder() const { return no_border; } + void layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom) const; + virtual void addRepaintFull(); // in composite.cpp + QRect decorationRect() const; protected: virtual void debug( kdbgstream& stream ) const; virtual bool shouldUnredirect() const; @@ -50,6 +58,17 @@ class Deleted double window_opacity; int desk; QRect contentsRect; // for clientPos()/clientSize() + + QPixmap decorationPixmapLeft; + QPixmap decorationPixmapRight; + QPixmap decorationPixmapTop; + QPixmap decorationPixmapBottom; + bool no_border; + QRect decoration_left; + QRect decoration_right; + QRect decoration_top; + QRect decoration_bottom; + int padding_left, padding_top, padding_right, padding_bottom; }; inline void Deleted::refWindow() diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 266b63a043..1417f2d582 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -1452,22 +1452,43 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat texture.unbind(); // decorations - if( Client *client = dynamic_cast(toplevel) ) + Client *client = dynamic_cast(toplevel); + Deleted *deleted = dynamic_cast(toplevel); + if( client || deleted ) { - if (!client->noBorder()) + bool noBorder = true; + bool updateDeco = false; + const QPixmap *left; + const QPixmap *top; + const QPixmap *right; + const QPixmap *bottom; + QRect topRect, leftRect, rightRect, bottomRect; + if( client && !client->noBorder() ) { - bool updateDeco = client->decorationPixmapRequiresRepaint(); + noBorder = false; + updateDeco = client->decorationPixmapRequiresRepaint(); client->ensureDecorationPixmapsPainted(); - const QPixmap *left = client->leftDecoPixmap(); - const QPixmap *top = client->topDecoPixmap(); - const QPixmap *right = client->rightDecoPixmap(); - const QPixmap *bottom = client->bottomDecoPixmap(); - - WindowQuadList topList, leftList, rightList, bottomList; - QRect topRect, leftRect, rightRect, bottomRect; client->layoutDecorationRects(leftRect, topRect, rightRect, bottomRect, Client::WindowRelative); + left = client->leftDecoPixmap(); + top = client->topDecoPixmap(); + right = client->rightDecoPixmap(); + bottom = client->bottomDecoPixmap(); + } + if( deleted && !deleted->noBorder() ) + { + noBorder = false; + left = deleted->leftDecoPixmap(); + top = deleted->topDecoPixmap(); + right = deleted->rightDecoPixmap(); + bottom = deleted->bottomDecoPixmap(); + deleted->layoutDecorationRects(leftRect, topRect, rightRect, bottomRect); + } + if( !noBorder ) + { + WindowQuadList topList, leftList, rightList, bottomList; + foreach( WindowQuad quad, decoration ) { if( topRect.contains( QPoint( quad.originalLeft(), quad.originalTop() ) ) ) diff --git a/scene_xrender.cpp b/scene_xrender.cpp index ddb005d12b..b515379e5d 100644 --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -663,9 +663,12 @@ void SceneXrender::Window::performPaint( int mask, QRegion region, WindowPaintDa double yscale = 1; bool scaled = false; - Client *client = dynamic_cast( toplevel ); + Client *client = dynamic_cast( toplevel ); + Deleted *deleted = dynamic_cast( toplevel ); if ( client && Workspace::self()->decorationHasAlpha() ) transformed_shape = QRegion( client->decorationRect() ); + else if( deleted && Workspace::self()->decorationHasAlpha() ) + transformed_shape = QRegion( deleted->decorationRect() ); else transformed_shape = shape(); @@ -737,26 +740,45 @@ void SceneXrender::Window::performPaint( int mask, QRegion region, WindowPaintDa transformed_shape = QRegion(); } } - if( client ) + if( client || deleted ) { - if( !client->noBorder() ) + bool noBorder = true; + const QPixmap *left; + const QPixmap *top; + const QPixmap *right; + const QPixmap *bottom; + QRect tr, lr, rr, br; + QRect decorationRect; + if( client && !client->noBorder() ) + { + noBorder = client->noBorder(); + client->ensureDecorationPixmapsPainted(); + + left = client->leftDecoPixmap(); + top = client->topDecoPixmap(); + right = client->rightDecoPixmap(); + bottom = client->bottomDecoPixmap(); + client->layoutDecorationRects( lr, tr, rr, br, Client::WindowRelative ); + decorationRect = client->decorationRect(); + } + if( deleted && !deleted->noBorder() ) + { + noBorder = deleted->noBorder(); + left = deleted->leftDecoPixmap(); + top = deleted->topDecoPixmap(); + right = deleted->rightDecoPixmap(); + bottom = deleted->bottomDecoPixmap(); + deleted->layoutDecorationRects( lr, tr, rr, br ); + decorationRect = deleted->decorationRect(); + } + if( !noBorder ) { // Paint the decoration Picture alpha = alphaMask( data.opacity * data.decoration_opacity ); Display *dpy = display(); - client->ensureDecorationPixmapsPainted(); - - const QPixmap *left = client->leftDecoPixmap(); - const QPixmap *top = client->topDecoPixmap(); - const QPixmap *right = client->rightDecoPixmap(); - const QPixmap *bottom = client->bottomDecoPixmap(); - if( !scaled ) { - QRect tr, lr, rr, br; - client->layoutDecorationRects( lr, tr, rr, br, Client::WindowRelative ); - tr = mapToScreen( mask, data, tr ); lr = mapToScreen( mask, data, lr ); rr = mapToScreen( mask, data, rr ); @@ -773,7 +795,7 @@ void SceneXrender::Window::performPaint( int mask, QRegion region, WindowPaintDa } else { - const QRect r = mapToScreen( mask, data, client->decorationRect() ); + const QRect r = mapToScreen( mask, data, decorationRect ); prepareTempPixmap( left, top, right, bottom ); XRenderSetPictureTransform( dpy, temp_pixmap->x11PictureHandle(), &xform ); XRenderComposite( dpy, PictOpOver, temp_pixmap->x11PictureHandle(), alpha, buffer, diff --git a/toplevel.h b/toplevel.h index b075f7bd88..62160f7508 100644 --- a/toplevel.h +++ b/toplevel.h @@ -116,7 +116,7 @@ class Toplevel void suspendUnredirect( bool suspend ); void addRepaint( const QRect& r ); void addRepaint( int x, int y, int w, int h ); - void addRepaintFull(); + virtual void addRepaintFull(); // these call workspace->addRepaint(), but first transform the damage if needed void addWorkspaceRepaint( const QRect& r ); void addWorkspaceRepaint( int x, int y, int w, int h ); @@ -154,6 +154,7 @@ class Toplevel int bit_depth; NETWinInfo2* info; bool ready_for_painting; + QRegion repaints_region; // updating, repaint just requires repaint of that area private: static QByteArray staticWindowRole(WId); static QByteArray staticSessionId(WId); @@ -169,7 +170,6 @@ class Toplevel Damage damage_handle; #endif QRegion damage_region; // damage is really damaged window (XDamage) and texture needs - QRegion repaints_region; // updating, repaint just requires repaint of that area bool is_shape; EffectWindowImpl* effect_window; QByteArray resource_name;