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
This commit is contained in:
Martin Gräßlin 2009-07-29 11:07:28 +00:00
parent 102b3c791b
commit ba27d2ebb0
7 changed files with 138 additions and 26 deletions

View file

@ -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();

View file

@ -997,4 +997,10 @@ bool Deleted::shouldUnredirect() const
return false;
}
void Deleted::addRepaintFull()
{
repaints_region = decorationRect();
workspace()->checkCompositeTimer();
}
} // namespace

View file

@ -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<Client*>(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"

View file

@ -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()

View file

@ -1452,22 +1452,43 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat
texture.unbind();
// decorations
if( Client *client = dynamic_cast<Client*>(toplevel) )
Client *client = dynamic_cast<Client*>(toplevel);
Deleted *deleted = dynamic_cast<Deleted*>(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() ) ) )

View file

@ -664,8 +664,11 @@ void SceneXrender::Window::performPaint( int mask, QRegion region, WindowPaintDa
bool scaled = false;
Client *client = dynamic_cast<Client*>( toplevel );
Deleted *deleted = dynamic_cast<Deleted*>( 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,

View file

@ -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;