Support for effects that affect opacity.
svn path=/branches/work/kwin_composite/; revision=558921
This commit is contained in:
parent
a67e2c7f07
commit
391bb6b28d
4 changed files with 50 additions and 3 deletions
21
effects.cpp
21
effects.cpp
|
@ -65,6 +65,24 @@ void Effect::paintWorkspace( Workspace*, EffectData& )
|
|||
// EffectsHandler
|
||||
//****************************************
|
||||
|
||||
class MakeHalfTransparent
|
||||
: public Effect
|
||||
{
|
||||
public:
|
||||
virtual void paintWindow( Toplevel* c, EffectData& data );
|
||||
};
|
||||
|
||||
void MakeHalfTransparent::paintWindow( Toplevel*, EffectData& data )
|
||||
{
|
||||
data.opacity *= 0.8;
|
||||
}
|
||||
|
||||
static MakeHalfTransparent* mht;
|
||||
EffectsHandler::EffectsHandler()
|
||||
{
|
||||
mht = new MakeHalfTransparent;
|
||||
}
|
||||
|
||||
void EffectsHandler::windowUserMoved( Toplevel* )
|
||||
{
|
||||
}
|
||||
|
@ -73,8 +91,9 @@ void EffectsHandler::windowUserResized( Toplevel* )
|
|||
{
|
||||
}
|
||||
|
||||
void EffectsHandler::paintWindow( Toplevel*, EffectData& )
|
||||
void EffectsHandler::paintWindow( Toplevel* c, EffectData& data )
|
||||
{
|
||||
mht->paintWindow( c, data );
|
||||
}
|
||||
|
||||
void EffectsHandler::paintWorkspace( Workspace*, EffectData& )
|
||||
|
|
|
@ -46,6 +46,7 @@ class Effect
|
|||
class EffectsHandler
|
||||
{
|
||||
public:
|
||||
EffectsHandler();
|
||||
void windowUserMoved( Toplevel* c );
|
||||
void windowUserResized( Toplevel* c );
|
||||
void paintWindow( Toplevel* c, EffectData& data );
|
||||
|
|
|
@ -13,6 +13,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#ifdef HAVE_XRENDER
|
||||
|
||||
#include "toplevel.h"
|
||||
#include "effects.h"
|
||||
|
||||
namespace KWinInternal
|
||||
{
|
||||
|
@ -43,6 +44,14 @@ SceneXrender::~SceneXrender()
|
|||
|
||||
void SceneXrender::paint( XserverRegion damage )
|
||||
{
|
||||
#if 0
|
||||
XRectangle r;
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
r.width = displayWidth();
|
||||
r.height = displayHeight();
|
||||
XFixesSetRegion( display(), damage, &r, 1 );
|
||||
#endif
|
||||
// Use the damage region as the clip region for the root window
|
||||
XFixesSetPictureClipRegion( display(), front, 0, 0, damage );
|
||||
// Client list for clients that are either translucent or have a shadow
|
||||
|
@ -55,6 +64,7 @@ void SceneXrender::paint( XserverRegion damage )
|
|||
{
|
||||
Toplevel* c = windows[ i ];
|
||||
checkWindowData( c );
|
||||
effects->paintWindow( c, window_data[ c ].effect );
|
||||
if( isOpaque( c ))
|
||||
{
|
||||
Picture picture = windowPicture( c );
|
||||
|
@ -91,9 +101,11 @@ void SceneXrender::paint( XserverRegion damage )
|
|||
Picture picture = windowPicture( c );
|
||||
Picture alpha = windowAlphaMask( c );
|
||||
if( picture != None )
|
||||
{
|
||||
// TODO clip also using shape? also above?
|
||||
XRenderComposite( display(), PictOpOver, picture, alpha, buffer, 0, 0, 0, 0,
|
||||
c->x(), c->y(), c->width(), c->height());
|
||||
}
|
||||
}
|
||||
XFixesDestroyRegion( display(), r );
|
||||
}
|
||||
|
@ -110,6 +122,9 @@ void SceneXrender::checkWindowData( Toplevel* c )
|
|||
window_data[ c ] = WindowData();
|
||||
window_data[ c ].format = XRenderFindVisualFormat( display(), c->visual());
|
||||
}
|
||||
WindowData& data = window_data[ c ];
|
||||
data.effect.matrix = Matrix();
|
||||
data.effect.opacity = c->opacity();
|
||||
}
|
||||
|
||||
void SceneXrender::windowGeometryShapeChanged( Toplevel* c )
|
||||
|
@ -174,7 +189,7 @@ bool SceneXrender::isOpaque( Toplevel* c ) const
|
|||
const WindowData& data = window_data[ c ];
|
||||
if( data.format->type == PictTypeDirect && data.format->direct.alphaMask )
|
||||
return false;
|
||||
if( c->opacity() != 1.0 )
|
||||
if( data.effect.opacity != 1.0 )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -184,6 +199,12 @@ Picture SceneXrender::windowAlphaMask( Toplevel* c )
|
|||
if( isOpaque( c ))
|
||||
return None;
|
||||
WindowData& data = window_data[ c ];
|
||||
if( data.alpha != None && data.alpha_cached_opacity != data.effect.opacity )
|
||||
{
|
||||
if( data.alpha != None )
|
||||
XRenderFreePicture( display(), data.alpha );
|
||||
data.alpha = None;
|
||||
}
|
||||
if( data.alpha != None )
|
||||
return data.alpha;
|
||||
Pixmap pixmap = XCreatePixmap( display(), rootWindow(), 1, 1, 8 );
|
||||
|
@ -193,7 +214,8 @@ Picture SceneXrender::windowAlphaMask( Toplevel* c )
|
|||
data.alpha = XRenderCreatePicture( display(), pixmap, format, CPRepeat, &pa );
|
||||
XFreePixmap( display(), pixmap );
|
||||
XRenderColor col;
|
||||
col.alpha = int( c->opacity() * 0xffff );
|
||||
col.alpha = int( data.effect.opacity * 0xffff );
|
||||
data.alpha_cached_opacity = data.effect.opacity;
|
||||
XRenderFillRectangle( display(), PictOpSrc, data.alpha, &col, 0, 0, 1, 1 );
|
||||
return data.alpha;
|
||||
}
|
||||
|
|
|
@ -17,10 +17,13 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
#include "scene.h"
|
||||
#include "effects.h"
|
||||
|
||||
namespace KWinInternal
|
||||
{
|
||||
|
||||
class Matrix;
|
||||
|
||||
class SceneXrender
|
||||
: public Scene
|
||||
{
|
||||
|
@ -51,7 +54,9 @@ class SceneXrender
|
|||
XRenderPictFormat* format;
|
||||
XserverRegion saved_clip_region;
|
||||
Picture alpha;
|
||||
double alpha_cached_opacity;
|
||||
XserverRegion shape;
|
||||
EffectData effect;
|
||||
};
|
||||
QMap< Toplevel*, WindowData > window_data;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue