Merge Libkdecoration2 Git branch.
WARNING: Breaks shadow effect. I don't think it causes anything to crash anymore but it is VERY ugly visually. Contains: - New decoration API that allows decorations to change the way shadows look. - Shadows now wobble. - API example code in the Oxygen decoration. - Added buildQuads() effect plugin hook. - Work on the shadow effect to use the new decoration shadow API as well. - Added IDs to WindowQuads. - Added public accessors to texture coords in WindowVertex. Would like all this to be reviewed. CCMAIL: kwin@kde.org svn path=/trunk/KDE/kdebase/workspace/; revision=872473icc-effect-5.14.5
parent
844f815ff8
commit
899d578c49
26
bridge.cpp
26
bridge.cpp
|
@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include "client.h"
|
||||
#include "options.h"
|
||||
#include "effects.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -200,4 +201,29 @@ void Bridge::grabXServer( bool grab )
|
|||
KWin::ungrabXServer();
|
||||
}
|
||||
|
||||
void Bridge::repaintShadow()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
bool Bridge::compositingActive() const
|
||||
{
|
||||
return c->workspace()->compositingActive();
|
||||
}
|
||||
|
||||
bool Bridge::shadowsActive() const
|
||||
{
|
||||
if( !c->workspace()->compositingActive() )
|
||||
return false;
|
||||
if( effects && static_cast<EffectsHandlerImpl*>( effects )->isEffectLoaded( "kwin4_effect_shadow" ))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
double Bridge::opacity() const
|
||||
{
|
||||
return c->opacity();
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
|
7
bridge.h
7
bridge.h
|
@ -28,7 +28,7 @@ namespace KWin
|
|||
|
||||
class Client;
|
||||
|
||||
class Bridge : public KDecorationBridge
|
||||
class Bridge : public KDecorationBridge2
|
||||
{
|
||||
public:
|
||||
Bridge( Client* cl );
|
||||
|
@ -74,6 +74,11 @@ class Bridge : public KDecorationBridge
|
|||
virtual QWidget* initialParentWidget() const;
|
||||
virtual Qt::WFlags initialWFlags() const;
|
||||
virtual void grabXServer( bool grab );
|
||||
|
||||
virtual void repaintShadow();
|
||||
virtual bool compositingActive() const;
|
||||
virtual bool shadowsActive() const;
|
||||
virtual double opacity() const;
|
||||
private:
|
||||
Client* c;
|
||||
};
|
||||
|
|
34
client.h
34
client.h
|
@ -284,6 +284,12 @@ class Client
|
|||
return moveResizeMode && mode != PositionCenter;
|
||||
}
|
||||
|
||||
// Decorations <-> Effects
|
||||
QList<QRect> shadowQuads( ShadowType type ) const;
|
||||
double shadowOpacity( ShadowType type, double dataOpacity ) const;
|
||||
double shadowBrightness( ShadowType type ) const;
|
||||
double shadowSaturation( ShadowType type ) const;
|
||||
|
||||
private slots:
|
||||
void autoRaise();
|
||||
void shadeHover();
|
||||
|
@ -789,6 +795,34 @@ inline bool Client::hiddenPreview() const
|
|||
return mapping_state == Kept;
|
||||
}
|
||||
|
||||
inline QList<QRect> Client::shadowQuads( ShadowType type ) const
|
||||
{
|
||||
if( KDecoration2* decoration2 = dynamic_cast< KDecoration2* >( decoration ))
|
||||
return decoration2->shadowQuads( type );
|
||||
return QList<QRect>();
|
||||
}
|
||||
|
||||
inline double Client::shadowOpacity( ShadowType type, double dataOpacity ) const
|
||||
{
|
||||
if( KDecoration2* decoration2 = dynamic_cast< KDecoration2* >( decoration ))
|
||||
return decoration2->shadowOpacity( type, dataOpacity );
|
||||
return dataOpacity;
|
||||
}
|
||||
|
||||
inline double Client::shadowBrightness( ShadowType type ) const
|
||||
{
|
||||
if( KDecoration2* decoration2 = dynamic_cast< KDecoration2* >( decoration ))
|
||||
return decoration2->shadowBrightness( type );
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
inline double Client::shadowSaturation( ShadowType type ) const
|
||||
{
|
||||
if( KDecoration2* decoration2 = dynamic_cast< KDecoration2* >( decoration ))
|
||||
return decoration2->shadowSaturation( type );
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
KWIN_COMPARE_PREDICATE( WrapperIdMatchPredicate, Client, Window, cl->wrapperId() == value );
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
#include "oxygen.h"
|
||||
#include "oxygenclient.h"
|
||||
#include <kconfiggroup.h>
|
||||
|
@ -144,6 +146,8 @@ bool OxygenFactory::supports( Ability ability ) const
|
|||
case AbilityButtonBelowOthers:
|
||||
case AbilityButtonSpacer:
|
||||
case AbilityButtonShade:
|
||||
// compositing
|
||||
case AbilityCompositingShadow: // TODO: UI option to use default shadows instead
|
||||
return true;
|
||||
// no colors supported at this time
|
||||
default:
|
||||
|
@ -151,4 +155,128 @@ bool OxygenFactory::supports( Ability ability ) const
|
|||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Shadows
|
||||
|
||||
QList< QList<QImage> > OxygenFactory::shadowTextures()
|
||||
{
|
||||
// TODO: THIS IS ALL VERY UGLY! Not recommended to do it this way.
|
||||
// Copied from the shadow effect's XRender picture generator
|
||||
|
||||
// TODO: You can add fake anti-aliasing here :)
|
||||
|
||||
QList< QList<QImage> > textureLists;
|
||||
QList<QImage> textures;
|
||||
|
||||
#define shadowFuzzyness 10
|
||||
#define shadowSize 10
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Active shadow texture
|
||||
|
||||
qreal size = 2 * ( shadowFuzzyness + shadowSize ) + 1;
|
||||
QPixmap *shadow = new QPixmap( size, size );
|
||||
shadow->fill( Qt::transparent );
|
||||
size /= 2.0;
|
||||
QRadialGradient rg( size, size, size );
|
||||
QColor c( 150, 234, 255, 255 );
|
||||
rg.setColorAt( 0, c );
|
||||
c.setAlpha( 0.3 * c.alpha() );
|
||||
if( shadowSize > 0 )
|
||||
rg.setColorAt( float( shadowSize ) / ( shadowFuzzyness + shadowSize ), c );
|
||||
c.setAlpha( 0 );
|
||||
rg.setColorAt( 0.8, c );
|
||||
QPainter p( shadow );
|
||||
p.setRenderHint( QPainter::Antialiasing );
|
||||
p.setPen( Qt::NoPen );
|
||||
p.setBrush( rg );
|
||||
p.drawRect( shadow->rect() );
|
||||
p.end();
|
||||
|
||||
int w = shadow->width() / 2;
|
||||
int h = shadow->height() / 2;
|
||||
QPixmap dump;
|
||||
|
||||
#define MAKE_TEX( _W_, _H_, _XOFF_, _YOFF_ ) \
|
||||
dump = QPixmap( _W_, _H_ ); \
|
||||
dump.fill( Qt::transparent ); \
|
||||
p.begin( &dump ); \
|
||||
p.drawPixmap( 0, 0, *shadow, _XOFF_, _YOFF_, _W_, _H_ ); \
|
||||
p.end(); \
|
||||
textures.append( dump.toImage() );
|
||||
|
||||
MAKE_TEX( w, h, 0, h );
|
||||
MAKE_TEX( 1, h, w, h );
|
||||
MAKE_TEX( w, h, w, h );
|
||||
MAKE_TEX( w, 1, 0, h );
|
||||
//MAKE_TEX( 1, 1, w, h );
|
||||
MAKE_TEX( w, 1, w, h );
|
||||
MAKE_TEX( w, h, 0, 0 );
|
||||
MAKE_TEX( 1, h, w, 0 );
|
||||
MAKE_TEX( w, h, w, 0 );
|
||||
delete shadow;
|
||||
|
||||
textureLists.append( textures );
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Inactive shadow texture
|
||||
|
||||
for( int i = 0; i < 8; i++ )
|
||||
{
|
||||
QPainter pi( &textures[i] );
|
||||
pi.fillRect( textures[i].rect(), QColor( 0, 0, 0, 255 ));
|
||||
pi.end();
|
||||
textures[i].setAlphaChannel( textureLists[0][i].alphaChannel() );
|
||||
}
|
||||
|
||||
textureLists.append( textures );
|
||||
|
||||
return textureLists;
|
||||
}
|
||||
|
||||
int OxygenFactory::shadowTextureList( ShadowType type ) const
|
||||
{
|
||||
switch( type ) {
|
||||
case ShadowBorderedActive:
|
||||
case ShadowBorderlessActive:
|
||||
return 0;
|
||||
case ShadowBorderedInactive:
|
||||
case ShadowBorderlessInactive:
|
||||
case ShadowOther:
|
||||
return 1;
|
||||
}
|
||||
abort(); // Should never be reached
|
||||
}
|
||||
|
||||
QList<QRect> OxygenFactory::shadowQuads( ShadowType type, QSize size ) const
|
||||
{
|
||||
#define shadowFuzzyness 15
|
||||
|
||||
// These are slightly under the decoration so the corners look nicer
|
||||
QList<QRect> quads;
|
||||
quads.append( QRect( -shadowFuzzyness+5, -shadowFuzzyness+5, shadowFuzzyness, shadowFuzzyness ));
|
||||
quads.append( QRect( 0+5, -shadowFuzzyness+5, size.width()-10, shadowFuzzyness ));
|
||||
quads.append( QRect( size.width()-5, -shadowFuzzyness+5, shadowFuzzyness, shadowFuzzyness ));
|
||||
quads.append( QRect( -shadowFuzzyness+5, 0+5, shadowFuzzyness, size.height()-10 ));
|
||||
//quads.append( QRect( 0+5, 0+5, size.width()-10, size.height()-10 ));
|
||||
quads.append( QRect( size.width()-5, 0+5, shadowFuzzyness, size.height()-10 ));
|
||||
quads.append( QRect( -shadowFuzzyness+5, size.height()-5, shadowFuzzyness, shadowFuzzyness ));
|
||||
quads.append( QRect( 0+5, size.height()-5, size.width()-10, shadowFuzzyness ));
|
||||
quads.append( QRect( size.width()-5, size.height()-5, shadowFuzzyness, shadowFuzzyness ));
|
||||
|
||||
return quads;
|
||||
}
|
||||
|
||||
double OxygenFactory::shadowOpacity( ShadowType type, double dataOpacity ) const
|
||||
{
|
||||
switch( type ) {
|
||||
case ShadowBorderlessActive:
|
||||
return dataOpacity;
|
||||
case ShadowBorderlessInactive:
|
||||
case ShadowOther:
|
||||
return dataOpacity * 0.25;
|
||||
}
|
||||
abort(); // Should never be reached
|
||||
}
|
||||
|
||||
} //namespace Oxygen
|
||||
|
|
|
@ -53,7 +53,7 @@ enum ButtonType {
|
|||
};
|
||||
Q_DECLARE_FLAGS(ButtonTypes, ButtonType)
|
||||
|
||||
class OxygenFactory: public KDecorationFactory
|
||||
class OxygenFactory: public KDecorationFactory2
|
||||
{
|
||||
public:
|
||||
OxygenFactory();
|
||||
|
@ -62,6 +62,11 @@ public:
|
|||
virtual bool reset(unsigned long changed);
|
||||
virtual bool supports( Ability ability ) const;
|
||||
|
||||
virtual QList< QList<QImage> > shadowTextures();
|
||||
virtual int shadowTextureList( ShadowType type ) const;
|
||||
virtual QList<QRect> shadowQuads( ShadowType type, QSize size ) const;
|
||||
virtual double shadowOpacity( ShadowType type, double dataOpacity ) const;
|
||||
|
||||
static bool initialized();
|
||||
static Qt::Alignment titleAlignment();
|
||||
static bool showStripes();
|
||||
|
|
|
@ -70,7 +70,7 @@ void renderDot(QPainter *p, const QPointF &point, qreal diameter)
|
|||
|
||||
|
||||
OxygenClient::OxygenClient(KDecorationBridge *b, KDecorationFactory *f)
|
||||
: KCommonDecoration(b, f)
|
||||
: KCommonDecoration2(b, f)
|
||||
, colorCacheInvalid_(true)
|
||||
, helper_(*globalHelper)
|
||||
{
|
||||
|
@ -415,6 +415,41 @@ void OxygenClient::updateWindowShape()
|
|||
setMask(mask);
|
||||
}
|
||||
|
||||
QList<QRect> OxygenClient::shadowQuads( ShadowType type ) const
|
||||
{
|
||||
QSize size = widget()->size();
|
||||
#define shadowFuzzyness 15
|
||||
|
||||
// These are slightly under the decoration so the corners look nicer
|
||||
QList<QRect> quads;
|
||||
quads.append( QRect( -shadowFuzzyness+5, -shadowFuzzyness+5, shadowFuzzyness, shadowFuzzyness ));
|
||||
quads.append( QRect( 0+5, -shadowFuzzyness+5, size.width()-10, shadowFuzzyness ));
|
||||
quads.append( QRect( size.width()-5, -shadowFuzzyness+5, shadowFuzzyness, shadowFuzzyness ));
|
||||
quads.append( QRect( -shadowFuzzyness+5, 0+5, shadowFuzzyness, size.height()-10 ));
|
||||
//quads.append( QRect( 0+5, 0+5, size.width()-10, size.height()-10 ));
|
||||
quads.append( QRect( size.width()-5, 0+5, shadowFuzzyness, size.height()-10 ));
|
||||
quads.append( QRect( -shadowFuzzyness+5, size.height()-5, shadowFuzzyness, shadowFuzzyness ));
|
||||
quads.append( QRect( 0+5, size.height()-5, size.width()-10, shadowFuzzyness ));
|
||||
quads.append( QRect( size.width()-5, size.height()-5, shadowFuzzyness, shadowFuzzyness ));
|
||||
|
||||
return quads;
|
||||
}
|
||||
|
||||
double OxygenClient::shadowOpacity( ShadowType type, double dataOpacity ) const
|
||||
{
|
||||
switch( type ) {
|
||||
case ShadowBorderedActive:
|
||||
if( isActive() )
|
||||
return dataOpacity;
|
||||
return 0.0;
|
||||
case ShadowBorderedInactive:
|
||||
if( isActive() )
|
||||
return 0.0;
|
||||
return dataOpacity * 0.25;
|
||||
}
|
||||
abort(); // Should never be reached
|
||||
}
|
||||
|
||||
} //namespace Oxygen
|
||||
|
||||
//#include "oxygenclient.moc"
|
||||
|
|
|
@ -37,7 +37,7 @@ class QPoint;
|
|||
|
||||
namespace Oxygen {
|
||||
|
||||
class OxygenClient : public KCommonDecoration
|
||||
class OxygenClient : public KCommonDecoration2
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -51,6 +51,9 @@ public:
|
|||
virtual void updateWindowShape();
|
||||
virtual void init();
|
||||
|
||||
virtual QList<QRect> shadowQuads( ShadowType type ) const;
|
||||
virtual double shadowOpacity( ShadowType type, double dataOpacity ) const;
|
||||
|
||||
private:
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void drawScratch(QPainter *p, QPalette &palette, const int start, const int end, const int topMargin);
|
||||
|
|
78
effects.cpp
78
effects.cpp
|
@ -51,6 +51,7 @@ EffectsHandlerImpl::EffectsHandlerImpl(CompositingType type)
|
|||
: EffectsHandler(type)
|
||||
, keyboard_grab_effect( NULL )
|
||||
, fullscreen_effect( 0 )
|
||||
, next_window_quad_type( EFFECT_QUAD_TYPE_START )
|
||||
{
|
||||
reconfigure();
|
||||
}
|
||||
|
@ -176,12 +177,37 @@ void EffectsHandlerImpl::drawWindow( EffectWindow* w, int mask, QRegion region,
|
|||
scene->finalDrawWindow( static_cast<EffectWindowImpl*>( w ), mask, region, data );
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::buildQuads( EffectWindow* w, WindowQuadList& quadList )
|
||||
{
|
||||
if( current_build_quads < loaded_effects.size())
|
||||
{
|
||||
loaded_effects[current_build_quads++].second->buildQuads( w, quadList );
|
||||
--current_build_quads;
|
||||
}
|
||||
}
|
||||
|
||||
bool EffectsHandlerImpl::hasDecorationShadows() const
|
||||
{
|
||||
return Workspace::self()->hasDecorationShadows();
|
||||
}
|
||||
|
||||
QList< QList<QImage> > EffectsHandlerImpl::shadowTextures()
|
||||
{
|
||||
return Workspace::self()->decorationShadowTextures();
|
||||
}
|
||||
|
||||
int EffectsHandlerImpl::shadowTextureList( ShadowType type ) const
|
||||
{
|
||||
return Workspace::self()->decorationShadowTextureList( type );
|
||||
}
|
||||
|
||||
// start another painting pass
|
||||
void EffectsHandlerImpl::startPaint()
|
||||
{
|
||||
assert( current_paint_screen == 0 );
|
||||
assert( current_paint_window == 0 );
|
||||
assert( current_draw_window == 0 );
|
||||
assert( current_build_quads == 0 );
|
||||
assert( current_transform == 0 );
|
||||
}
|
||||
|
||||
|
@ -431,6 +457,11 @@ double EffectsHandlerImpl::animationTimeFactor() const
|
|||
return options->animationTimeFactor();
|
||||
}
|
||||
|
||||
WindowQuadType EffectsHandlerImpl::newWindowQuadType()
|
||||
{
|
||||
return WindowQuadType( next_window_quad_type++ );
|
||||
}
|
||||
|
||||
int EffectsHandlerImpl::displayWidth() const
|
||||
{
|
||||
return KWin::displayWidth();
|
||||
|
@ -767,6 +798,7 @@ bool EffectsHandlerImpl::loadEffect( const QString& name )
|
|||
assert( current_paint_screen == 0 );
|
||||
assert( current_paint_window == 0 );
|
||||
assert( current_draw_window == 0 );
|
||||
assert( current_build_quads == 0 );
|
||||
assert( current_transform == 0 );
|
||||
|
||||
if( !name.startsWith("kwin4_effect_") )
|
||||
|
@ -872,6 +904,7 @@ void EffectsHandlerImpl::unloadEffect( const QString& name )
|
|||
assert( current_paint_screen == 0 );
|
||||
assert( current_paint_window == 0 );
|
||||
assert( current_draw_window == 0 );
|
||||
assert( current_build_quads == 0 );
|
||||
assert( current_transform == 0 );
|
||||
|
||||
for( QMap< int, EffectPair >::iterator it = effect_order.begin(); it != effect_order.end(); ++it)
|
||||
|
@ -1303,6 +1336,51 @@ EffectWindowList EffectWindowImpl::mainWindows() const
|
|||
return EffectWindowList();
|
||||
}
|
||||
|
||||
QList<QRect> EffectWindowImpl::shadowQuads( ShadowType type ) const
|
||||
{
|
||||
if( type == ShadowBorderedActive || type == ShadowBorderedInactive )
|
||||
{
|
||||
if( Client* c = dynamic_cast< Client* >( toplevel ))
|
||||
return c->shadowQuads( type );
|
||||
return QList<QRect>();
|
||||
}
|
||||
return toplevel->workspace()->decorationShadowQuads( type, toplevel->size() );
|
||||
}
|
||||
|
||||
double EffectWindowImpl::shadowOpacity( ShadowType type, double dataOpacity ) const
|
||||
{
|
||||
dataOpacity *= opacity();
|
||||
if( type == ShadowBorderedActive || type == ShadowBorderedInactive )
|
||||
{
|
||||
if( Client* c = dynamic_cast< Client* >( toplevel ))
|
||||
return c->shadowOpacity( type, dataOpacity );
|
||||
return dataOpacity;
|
||||
}
|
||||
return toplevel->workspace()->decorationShadowOpacity( type, dataOpacity );
|
||||
}
|
||||
|
||||
double EffectWindowImpl::shadowBrightness( ShadowType type ) const
|
||||
{
|
||||
if( type == ShadowBorderedActive || type == ShadowBorderedInactive )
|
||||
{
|
||||
if( Client* c = dynamic_cast< Client* >( toplevel ))
|
||||
return c->shadowBrightness( type );
|
||||
return 1.0;
|
||||
}
|
||||
return toplevel->workspace()->decorationShadowBrightness( type );
|
||||
}
|
||||
|
||||
double EffectWindowImpl::shadowSaturation( ShadowType type ) const
|
||||
{
|
||||
if( type == ShadowBorderedActive || type == ShadowBorderedInactive )
|
||||
{
|
||||
if( Client* c = dynamic_cast< Client* >( toplevel ))
|
||||
return c->shadowSaturation( type );
|
||||
return 1.0;
|
||||
}
|
||||
return toplevel->workspace()->decorationShadowSaturation( type );
|
||||
}
|
||||
|
||||
WindowQuadList EffectWindowImpl::buildQuads() const
|
||||
{
|
||||
return sceneWindow()->buildQuads();
|
||||
|
|
13
effects.h
13
effects.h
|
@ -49,6 +49,8 @@ class EffectsHandlerImpl : public EffectsHandler
|
|||
|
||||
virtual void drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
|
||||
virtual void buildQuads( EffectWindow* w, WindowQuadList& quadList );
|
||||
|
||||
virtual void activateWindow( EffectWindow* c );
|
||||
virtual EffectWindow* activeWindow() const;
|
||||
virtual void moveWindow( EffectWindow* w, const QPoint& pos );
|
||||
|
@ -100,6 +102,7 @@ class EffectsHandlerImpl : public EffectsHandler
|
|||
virtual int desktopUp( int desktop, bool wrap ) const;
|
||||
virtual int desktopDown( int desktop, bool wrap ) const;
|
||||
virtual double animationTimeFactor() const;
|
||||
virtual WindowQuadType newWindowQuadType();
|
||||
|
||||
virtual Window createInputWindow( Effect* e, int x, int y, int w, int h, const QCursor& cursor );
|
||||
using EffectsHandler::createInputWindow;
|
||||
|
@ -116,6 +119,10 @@ class EffectsHandlerImpl : public EffectsHandler
|
|||
virtual void reconfigure();
|
||||
virtual void registerPropertyType( long atom, bool reg );
|
||||
|
||||
virtual bool hasDecorationShadows() const;
|
||||
virtual QList< QList<QImage> > shadowTextures();
|
||||
virtual int shadowTextureList( ShadowType type ) const;
|
||||
|
||||
// internal (used by kwin core or compositing code)
|
||||
void startPaint();
|
||||
void windowUserMovedResized( EffectWindow* c, bool first, bool last );
|
||||
|
@ -160,6 +167,7 @@ class EffectsHandlerImpl : public EffectsHandler
|
|||
QList<EffectWindow*> elevated_windows;
|
||||
QMultiMap< int, EffectPair > effect_order;
|
||||
QHash< long, int > registered_atoms;
|
||||
int next_window_quad_type;
|
||||
};
|
||||
|
||||
class EffectWindowImpl : public EffectWindow
|
||||
|
@ -230,6 +238,11 @@ class EffectWindowImpl : public EffectWindow
|
|||
virtual EffectWindow* findModal();
|
||||
virtual EffectWindowList mainWindows() const;
|
||||
|
||||
virtual QList<QRect> shadowQuads( ShadowType type ) const;
|
||||
virtual double shadowOpacity( ShadowType type, double dataOpacity ) const;
|
||||
virtual double shadowBrightness( ShadowType type ) const;
|
||||
virtual double shadowSaturation( ShadowType type ) const;
|
||||
|
||||
virtual WindowQuadList buildQuads() const;
|
||||
|
||||
const Toplevel* window() const;
|
||||
|
|
|
@ -78,9 +78,6 @@ ShadowTiles::ShadowTiles(const QPixmap& shadow)
|
|||
|
||||
ShadowEffect::ShadowEffect()
|
||||
: shadowSize( 0 )
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
, mShadowTexture( NULL )
|
||||
#endif
|
||||
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||
, mShadowPics( NULL )
|
||||
#endif
|
||||
|
@ -93,7 +90,9 @@ ShadowEffect::ShadowEffect()
|
|||
ShadowEffect::~ShadowEffect()
|
||||
{
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
delete mShadowTexture;
|
||||
for( int i = 0; i < mShadowTextures.size(); i++ )
|
||||
for( int j = 0; j < mShadowTextures.at( i ).size(); j++ )
|
||||
delete mShadowTextures.at( i ).at( j );
|
||||
#endif
|
||||
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||
delete mShadowPics;
|
||||
|
@ -109,15 +108,6 @@ void ShadowEffect::reconfigure( ReconfigureFlags )
|
|||
shadowFuzzyness = conf.readEntry( "Fuzzyness", 10 );
|
||||
shadowSize = conf.readEntry( "Size", 5 );
|
||||
intensifyActiveShadow = conf.readEntry( "IntensifyActiveShadow", true );
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
delete mShadowTexture;
|
||||
mShadowTexture = NULL;
|
||||
if ( effects->compositingType() == OpenGLCompositing)
|
||||
{
|
||||
QString shadowtexture = KGlobal::dirs()->findResource("data", "kwin/shadow-texture.png");
|
||||
mShadowTexture = new GLTexture(shadowtexture);
|
||||
}
|
||||
#endif
|
||||
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||
delete mShadowPics;
|
||||
mShadowPics = NULL;
|
||||
|
@ -144,6 +134,48 @@ void ShadowEffect::reconfigure( ReconfigureFlags )
|
|||
}
|
||||
#endif
|
||||
updateShadowColor();
|
||||
|
||||
// Load decoration shadow related things
|
||||
mShadowQuadTypes.clear(); // Changed decoration? TODO: Unregister?
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
if( effects->compositingType() == OpenGLCompositing )
|
||||
{
|
||||
for( int i = 0; i < mShadowTextures.size(); i++ )
|
||||
for( int j = 0; j < mShadowTextures.at( i ).size(); j++ )
|
||||
delete mShadowTextures.at( i ).at( j );
|
||||
mShadowTextures.clear();
|
||||
if( effects->hasDecorationShadows() )
|
||||
{
|
||||
QList< QList<QImage> > shadowTextures = effects->shadowTextures();
|
||||
for( int i = 0; i < shadowTextures.size(); i++ )
|
||||
{
|
||||
mShadowQuadTypes.append( effects->newWindowQuadType() );
|
||||
QList<GLTexture*> textures;
|
||||
for( int j = 0; j < shadowTextures.at( i ).size(); j++ )
|
||||
textures.append( new GLTexture( shadowTextures.at( i ).at( j )));
|
||||
mShadowTextures.append( textures );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mShadowQuadTypes.append( effects->newWindowQuadType() );
|
||||
QImage shadowTexture( KGlobal::dirs()->findResource( "data", "kwin/shadow-texture.png" ));
|
||||
int hw = shadowTexture.width() / 2;
|
||||
int hh = shadowTexture.height() / 2;
|
||||
QList<GLTexture*> textures;
|
||||
textures.append( new GLTexture( shadowTexture.copy( 0, hh, hw, hh )));
|
||||
textures.append( new GLTexture( shadowTexture.copy( hw, hh, 1, hh )));
|
||||
textures.append( new GLTexture( shadowTexture.copy( hw, hh, hw, hh )));
|
||||
textures.append( new GLTexture( shadowTexture.copy( 0, hh, hw, 1 )));
|
||||
textures.append( new GLTexture( shadowTexture.copy( hw, hh, 1, 1 )));
|
||||
textures.append( new GLTexture( shadowTexture.copy( hw, hh, hw, 1 )));
|
||||
textures.append( new GLTexture( shadowTexture.copy( 0, 0, hw, hh )));
|
||||
textures.append( new GLTexture( shadowTexture.copy( hw, 0, 1, hh )));
|
||||
textures.append( new GLTexture( shadowTexture.copy( hw, 0, hw, hh )));
|
||||
mShadowTextures.append( textures );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ShadowEffect::updateShadowColor()
|
||||
|
@ -185,7 +217,7 @@ void ShadowEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data
|
|||
|
||||
void ShadowEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time )
|
||||
{
|
||||
if( useShadow( w ) && !data.quads.isTransformed())
|
||||
if( useShadow( w ))
|
||||
{
|
||||
data.paint |= shadowRectangle( data.paint.boundingRect() );
|
||||
}
|
||||
|
@ -203,7 +235,7 @@ void ShadowEffect::drawWindow( EffectWindow* w, int mask, QRegion region, Window
|
|||
// first we need to draw all queued shadows.
|
||||
drawQueuedShadows( w );
|
||||
}
|
||||
if( useShadow( w ) && !data.quads.isTransformed())
|
||||
if( useShadow( w ))
|
||||
{
|
||||
if( !optimize )
|
||||
{
|
||||
|
@ -229,6 +261,165 @@ void ShadowEffect::drawWindow( EffectWindow* w, int mask, QRegion region, Window
|
|||
effects->drawWindow( w, mask, region, data );
|
||||
}
|
||||
|
||||
void ShadowEffect::buildQuads( EffectWindow* w, WindowQuadList& quadList )
|
||||
{
|
||||
if( effects->hasDecorationShadows() )
|
||||
{
|
||||
// TODO: shadowQuads() is allowed to return different quads for
|
||||
// active and inactive shadows. Is implementing it worth
|
||||
// the performance drop?
|
||||
int id = 0;
|
||||
if( w->hasDecoration() )
|
||||
{ // Decorated windows must be normal windows
|
||||
foreach( const QRect &r, w->shadowQuads( ShadowBorderedActive ))
|
||||
{
|
||||
WindowQuad quad( mShadowQuadTypes.at( effects->shadowTextureList( ShadowBorderedActive )), id++ );
|
||||
quad[ 0 ] = WindowVertex( r.x(), r.y(), 0, 0 );
|
||||
quad[ 1 ] = WindowVertex( r.x() + r.width(), r.y(), 1, 0 );
|
||||
quad[ 2 ] = WindowVertex( r.x() + r.width(), r.y() + r.height(), 1, 1 );
|
||||
quad[ 3 ] = WindowVertex( r.x(), r.y() + r.height(), 0, 1 );
|
||||
quadList.append( quad );
|
||||
}
|
||||
}
|
||||
else if( w->isNormalWindow() )
|
||||
{ // No decoration on a normal window
|
||||
foreach( const QRect &r, w->shadowQuads( ShadowBorderlessActive ))
|
||||
{
|
||||
WindowQuad quad( mShadowQuadTypes.at( effects->shadowTextureList( ShadowBorderlessActive )), id++ );
|
||||
quad[ 0 ] = WindowVertex( r.x(), r.y(), 0, 0 );
|
||||
quad[ 1 ] = WindowVertex( r.x() + r.width(), r.y(), 1, 0 );
|
||||
quad[ 2 ] = WindowVertex( r.x() + r.width(), r.y() + r.height(), 1, 1 );
|
||||
quad[ 3 ] = WindowVertex( r.x(), r.y() + r.height(), 0, 1 );
|
||||
quadList.append( quad );
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // All other undecorated windows
|
||||
foreach( const QRect &r, w->shadowQuads( ShadowOther ))
|
||||
{
|
||||
WindowQuad quad( mShadowQuadTypes.at( effects->shadowTextureList( ShadowOther )), id++ );
|
||||
quad[ 0 ] = WindowVertex( r.x(), r.y(), 0, 0 );
|
||||
quad[ 1 ] = WindowVertex( r.x() + r.width(), r.y(), 1, 0 );
|
||||
quad[ 2 ] = WindowVertex( r.x() + r.width(), r.y() + r.height(), 1, 1 );
|
||||
quad[ 3 ] = WindowVertex( r.x(), r.y() + r.height(), 0, 1 );
|
||||
quadList.append( quad );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: add config option to not have shadows for menus, etc.
|
||||
// Make our own shadow as the decoration doesn't support it
|
||||
int fuzzy = shadowFuzzyness;
|
||||
// Shadow's size must be a least 2*fuzzy in both directions (or the corners will be broken)
|
||||
int width = qMax(fuzzy*2, w->width());
|
||||
int height = qMax(fuzzy*2, w->height());
|
||||
double x1, y1, x2, y2;
|
||||
int id = 0;
|
||||
// top-left
|
||||
x1 = 0 - fuzzy;
|
||||
y1 = 0 - fuzzy;
|
||||
x2 = 0;
|
||||
y2 = 0;
|
||||
WindowQuad topLeftQuad( mShadowQuadTypes.at( 0 ), id++ );
|
||||
topLeftQuad[ 0 ] = WindowVertex( x1, y1, 0, 0 );
|
||||
topLeftQuad[ 1 ] = WindowVertex( x2, y1, 1, 0 );
|
||||
topLeftQuad[ 2 ] = WindowVertex( x2, y2, 1, 1 );
|
||||
topLeftQuad[ 3 ] = WindowVertex( x1, y2, 0, 1 );
|
||||
quadList.append( topLeftQuad );
|
||||
// top
|
||||
x1 = 0;
|
||||
y1 = 0 - fuzzy;
|
||||
x2 = width;
|
||||
y2 = 0;
|
||||
WindowQuad topQuad( mShadowQuadTypes.at( 0 ), id++ );
|
||||
topQuad[ 0 ] = WindowVertex( x1, y1, 0, 0 );
|
||||
topQuad[ 1 ] = WindowVertex( x2, y1, 1, 0 );
|
||||
topQuad[ 2 ] = WindowVertex( x2, y2, 1, 1 );
|
||||
topQuad[ 3 ] = WindowVertex( x1, y2, 0, 1 );
|
||||
quadList.append( topQuad );
|
||||
// top-right
|
||||
x1 = width;
|
||||
y1 = 0 - fuzzy;
|
||||
x2 = width + fuzzy;
|
||||
y2 = 0;
|
||||
WindowQuad topRightQuad( mShadowQuadTypes.at( 0 ), id++ );
|
||||
topRightQuad[ 0 ] = WindowVertex( x1, y1, 0, 0 );
|
||||
topRightQuad[ 1 ] = WindowVertex( x2, y1, 1, 0 );
|
||||
topRightQuad[ 2 ] = WindowVertex( x2, y2, 1, 1 );
|
||||
topRightQuad[ 3 ] = WindowVertex( x1, y2, 0, 1 );
|
||||
quadList.append( topRightQuad );
|
||||
// left
|
||||
x1 = 0 - fuzzy;
|
||||
y1 = 0;
|
||||
x2 = 0;
|
||||
y2 = height;
|
||||
WindowQuad leftQuad( mShadowQuadTypes.at( 0 ), id++ );
|
||||
leftQuad[ 0 ] = WindowVertex( x1, y1, 0, 0 );
|
||||
leftQuad[ 1 ] = WindowVertex( x2, y1, 1, 0 );
|
||||
leftQuad[ 2 ] = WindowVertex( x2, y2, 1, 1 );
|
||||
leftQuad[ 3 ] = WindowVertex( x1, y2, 0, 1 );
|
||||
quadList.append( leftQuad );
|
||||
// center
|
||||
x1 = 0;
|
||||
y1 = 0;
|
||||
x2 = width;
|
||||
y2 = height;
|
||||
WindowQuad contentsQuad( mShadowQuadTypes.at( 0 ), id++ );
|
||||
contentsQuad[ 0 ] = WindowVertex( x1, y1, 0, 0 );
|
||||
contentsQuad[ 1 ] = WindowVertex( x2, y1, 1, 0 );
|
||||
contentsQuad[ 2 ] = WindowVertex( x2, y2, 1, 1 );
|
||||
contentsQuad[ 3 ] = WindowVertex( x1, y2, 0, 1 );
|
||||
quadList.append( contentsQuad );
|
||||
// right
|
||||
x1 = width;
|
||||
y1 = 0;
|
||||
x2 = width + fuzzy;
|
||||
y2 = height;
|
||||
WindowQuad rightQuad( mShadowQuadTypes.at( 0 ), id++ );
|
||||
rightQuad[ 0 ] = WindowVertex( x1, y1, 0, 0 );
|
||||
rightQuad[ 1 ] = WindowVertex( x2, y1, 1, 0 );
|
||||
rightQuad[ 2 ] = WindowVertex( x2, y2, 1, 1 );
|
||||
rightQuad[ 3 ] = WindowVertex( x1, y2, 0, 1 );
|
||||
quadList.append( rightQuad );
|
||||
// bottom-left
|
||||
x1 = 0 - fuzzy;
|
||||
y1 = height;
|
||||
x2 = 0;
|
||||
y2 = height + fuzzy;
|
||||
WindowQuad bottomLeftQuad( mShadowQuadTypes.at( 0 ), id++ );
|
||||
bottomLeftQuad[ 0 ] = WindowVertex( x1, y1, 0, 0 );
|
||||
bottomLeftQuad[ 1 ] = WindowVertex( x2, y1, 1, 0 );
|
||||
bottomLeftQuad[ 2 ] = WindowVertex( x2, y2, 1, 1 );
|
||||
bottomLeftQuad[ 3 ] = WindowVertex( x1, y2, 0, 1 );
|
||||
quadList.append( bottomLeftQuad );
|
||||
// bottom
|
||||
x1 = 0;
|
||||
y1 = height;
|
||||
x2 = width;
|
||||
y2 = height + fuzzy;
|
||||
WindowQuad bottomQuad( mShadowQuadTypes.at( 0 ), id++ );
|
||||
bottomQuad[ 0 ] = WindowVertex( x1, y1, 0, 0 );
|
||||
bottomQuad[ 1 ] = WindowVertex( x2, y1, 1, 0 );
|
||||
bottomQuad[ 2 ] = WindowVertex( x2, y2, 1, 1 );
|
||||
bottomQuad[ 3 ] = WindowVertex( x1, y2, 0, 1 );
|
||||
quadList.append( bottomQuad );
|
||||
// bottom-right
|
||||
x1 = width;
|
||||
y1 = height;
|
||||
x2 = width + fuzzy;
|
||||
y2 = height + fuzzy;
|
||||
WindowQuad bottomRightQuad( mShadowQuadTypes.at( 0 ), id++ );
|
||||
bottomRightQuad[ 0 ] = WindowVertex( x1, y1, 0, 0 );
|
||||
bottomRightQuad[ 1 ] = WindowVertex( x2, y1, 1, 0 );
|
||||
bottomRightQuad[ 2 ] = WindowVertex( x2, y2, 1, 1 );
|
||||
bottomRightQuad[ 3 ] = WindowVertex( x1, y2, 0, 1 );
|
||||
quadList.append( bottomRightQuad );
|
||||
} // This is called for menus, tooltips, windows where the user has disabled borders and shaped windows
|
||||
|
||||
effects->buildQuads( w, quadList );
|
||||
}
|
||||
|
||||
QRect ShadowEffect::transformWindowDamage( EffectWindow* w, const QRect& r )
|
||||
{
|
||||
if( !useShadow( w ))
|
||||
|
@ -286,6 +477,94 @@ void ShadowEffect::drawShadow( EffectWindow* window, int mask, QRegion region, c
|
|||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
foreach( const WindowQuad &quad, data.quads )
|
||||
{
|
||||
if( !mShadowQuadTypes.contains( quad.type() ))
|
||||
continue; // Not a shadow quad
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
// Use the window's top-left as the origin
|
||||
glTranslatef( window->x(), window->y(), 0 );
|
||||
if( mask & PAINT_WINDOW_TRANSFORMED )
|
||||
glTranslatef( data.xTranslate, data.yTranslate, 0 );
|
||||
if(( mask & PAINT_WINDOW_TRANSFORMED ) && ( data.xScale != 1 || data.yScale != 1 ))
|
||||
glScalef( data.xScale, data.yScale, 1 );
|
||||
|
||||
// Create our polygon
|
||||
QVector<float> verts, texcoords;
|
||||
verts.reserve(8);
|
||||
texcoords.reserve(8);
|
||||
verts << quad[0].x() << quad[0].y();
|
||||
verts << quad[1].x() << quad[1].y();
|
||||
verts << quad[2].x() << quad[2].y();
|
||||
verts << quad[3].x() << quad[3].y();
|
||||
texcoords << quad[0].textureX() << quad[0].textureY();
|
||||
texcoords << quad[1].textureX() << quad[1].textureY();
|
||||
texcoords << quad[2].textureX() << quad[2].textureY();
|
||||
texcoords << quad[3].textureX() << quad[3].textureY();
|
||||
|
||||
// Work out which texture to use
|
||||
int texture = mShadowQuadTypes.indexOf( quad.type() );
|
||||
if( texture != -1 && texture < mShadowTextures.size() ) // TODO: Needed?
|
||||
{
|
||||
// Render it!
|
||||
// Cheat a little, assume the active and inactive shadows have identical quads
|
||||
// TODO: Opacity, saturation, brightness, etc.
|
||||
if( window->hasDecoration() &&
|
||||
effects->shadowTextureList( ShadowBorderedActive ) == texture )
|
||||
{ // Decorated windows
|
||||
// Active shadow
|
||||
mShadowTextures.at( texture ).at( quad.id() )->bind();
|
||||
glColor4f( 1.0, 1.0, 1.0, window->shadowOpacity( ShadowBorderedActive, data.opacity ));
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
mShadowTextures.at( texture ).at( quad.id() )->enableNormalizedTexCoords();
|
||||
renderGLGeometry( region, 4, verts.data(), texcoords.data() );
|
||||
mShadowTextures.at( texture ).at( quad.id() )->disableNormalizedTexCoords();
|
||||
mShadowTextures.at( texture ).at( quad.id() )->unbind();
|
||||
|
||||
// Inactive shadow
|
||||
texture = effects->shadowTextureList( ShadowBorderedInactive );
|
||||
mShadowTextures.at( texture ).at( quad.id() )->bind();
|
||||
glColor4f( 1.0, 1.0, 1.0, window->shadowOpacity( ShadowBorderedInactive, data.opacity ));
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
mShadowTextures.at( texture ).at( quad.id() )->enableNormalizedTexCoords();
|
||||
renderGLGeometry( region, 4, verts.data(), texcoords.data() );
|
||||
mShadowTextures.at( texture ).at( quad.id() )->disableNormalizedTexCoords();
|
||||
mShadowTextures.at( texture ).at( quad.id() )->unbind();
|
||||
}
|
||||
else if( effects->shadowTextureList( ShadowBorderlessActive ) == texture )
|
||||
{ // Decoration-less normal windows
|
||||
if( effects->activeWindow() == window )
|
||||
glColor4f( 1.0, 1.0, 1.0, window->shadowOpacity( ShadowBorderlessActive, data.opacity ));
|
||||
else
|
||||
{
|
||||
texture = effects->shadowTextureList( ShadowBorderlessInactive );
|
||||
glColor4f( 1.0, 1.0, 1.0, window->shadowOpacity( ShadowBorderlessInactive, data.opacity ));
|
||||
}
|
||||
mShadowTextures.at( texture ).at( quad.id() )->bind();
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
mShadowTextures.at( texture ).at( quad.id() )->enableNormalizedTexCoords();
|
||||
renderGLGeometry( region, 4, verts.data(), texcoords.data() );
|
||||
mShadowTextures.at( texture ).at( quad.id() )->disableNormalizedTexCoords();
|
||||
mShadowTextures.at( texture ).at( quad.id() )->unbind();
|
||||
}
|
||||
else
|
||||
{ // Other windows
|
||||
mShadowTextures.at( texture ).at( quad.id() )->bind();
|
||||
glColor4f( 1.0, 1.0, 1.0, window->shadowOpacity( ShadowOther, data.opacity ));
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
mShadowTextures.at( texture ).at( quad.id() )->enableNormalizedTexCoords();
|
||||
renderGLGeometry( region, 4, verts.data(), texcoords.data() );
|
||||
mShadowTextures.at( texture ).at( quad.id() )->disableNormalizedTexCoords();
|
||||
mShadowTextures.at( texture ).at( quad.id() )->unbind();
|
||||
}
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
/*
|
||||
int fuzzy = shadowFuzzyness;
|
||||
// Shadow's size must be a least 2*fuzzy in both directions (or the corners will be broken)
|
||||
int w = qMax(fuzzy*2, window->width() + 2*shadowSize);
|
||||
|
@ -348,8 +627,7 @@ void ShadowEffect::drawShadow( EffectWindow* window, int mask, QRegion region, c
|
|||
renderGLGeometry( region, verticesCount, verts.data(), texcoords.data() );
|
||||
mShadowTexture->disableNormalizedTexCoords();
|
||||
mShadowTexture->unbind();
|
||||
|
||||
glPopMatrix();
|
||||
*/
|
||||
glPopAttrib();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -53,6 +53,7 @@ class ShadowEffect
|
|||
virtual void drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data );
|
||||
virtual void windowClosed( EffectWindow* c );
|
||||
virtual void buildQuads( EffectWindow* w, WindowQuadList& quadList );
|
||||
virtual QRect transformWindowDamage( EffectWindow* w, const QRect& r );
|
||||
|
||||
private slots:
|
||||
|
@ -73,12 +74,14 @@ class ShadowEffect
|
|||
bool intensifyActiveShadow;
|
||||
QColor shadowColor;
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
GLTexture* mShadowTexture;
|
||||
QList< QList<GLTexture*> > mShadowTextures;
|
||||
#endif
|
||||
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||
ShadowTiles *mShadowPics;
|
||||
#endif
|
||||
|
||||
QList<WindowQuadType> mShadowQuadTypes;
|
||||
|
||||
struct ShadowData
|
||||
{
|
||||
ShadowData(EffectWindow* _w, WindowPaintData& _data) : w(_w), data(_data) {}
|
||||
|
|
|
@ -429,6 +429,25 @@ void KDecorationPreviewBridge::grabXServer( bool )
|
|||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::repaintShadow()
|
||||
{
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::compositingActive() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KDecorationPreviewBridge::shadowsActive() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
double KDecorationPreviewBridge::opacity() const
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
KDecorationPreviewOptions::KDecorationPreviewOptions()
|
||||
{
|
||||
customBorderSize = BordersCount; // invalid
|
||||
|
|
|
@ -66,7 +66,7 @@ class KDecorationPreview
|
|||
};
|
||||
|
||||
class KDecorationPreviewBridge
|
||||
: public KDecorationBridge
|
||||
: public KDecorationBridge2
|
||||
{
|
||||
public:
|
||||
KDecorationPreviewBridge( KDecorationPreview* preview, bool active );
|
||||
|
@ -112,6 +112,11 @@ class KDecorationPreviewBridge
|
|||
virtual QWidget* initialParentWidget() const;
|
||||
virtual Qt::WFlags initialWFlags() const;
|
||||
virtual void grabXServer( bool grab );
|
||||
|
||||
virtual void repaintShadow();
|
||||
virtual bool compositingActive() const;
|
||||
virtual bool shadowsActive() const;
|
||||
virtual double opacity() const;
|
||||
private:
|
||||
KDecorationPreview* preview;
|
||||
bool active;
|
||||
|
|
|
@ -1221,5 +1221,58 @@ KDecoration* KCommonDecoration::decoration()
|
|||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
KCommonDecoration2::KCommonDecoration2(KDecorationBridge* bridge, KDecorationFactory* factory)
|
||||
: KCommonDecoration( bridge, factory )
|
||||
{
|
||||
Q_ASSERT( dynamic_cast<const KDecoration2*>( decoration() ));
|
||||
}
|
||||
|
||||
KCommonDecoration2::~KCommonDecoration2()
|
||||
{
|
||||
}
|
||||
|
||||
// All copied from kdecoration.cpp
|
||||
QList<QRect> KCommonDecoration2::shadowQuads( ShadowType type ) const
|
||||
{
|
||||
Q_UNUSED( type );
|
||||
return QList<QRect>();
|
||||
}
|
||||
double KCommonDecoration2::shadowOpacity( ShadowType type, double dataOpacity ) const
|
||||
{
|
||||
if( isActive() && type == ShadowBorderedActive )
|
||||
return dataOpacity;
|
||||
else if( !isActive() && type == ShadowBorderedInactive )
|
||||
return dataOpacity;
|
||||
return 0.0;
|
||||
}
|
||||
double KCommonDecoration2::shadowBrightness( ShadowType type ) const
|
||||
{
|
||||
Q_UNUSED( type );
|
||||
return 1.0;
|
||||
}
|
||||
double KCommonDecoration2::shadowSaturation( ShadowType type ) const
|
||||
{
|
||||
Q_UNUSED( type );
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
void KCommonDecoration2::repaintShadow()
|
||||
{
|
||||
return static_cast<const KDecoration2*>( decoration() )->repaintShadow();
|
||||
}
|
||||
bool KCommonDecoration2::compositingActive() const
|
||||
{
|
||||
return static_cast<const KDecoration2*>( decoration() )->compositingActive();
|
||||
}
|
||||
bool KCommonDecoration2::shadowsActive() const
|
||||
{
|
||||
return static_cast<const KDecoration2*>( decoration() )->shadowsActive();
|
||||
}
|
||||
double KCommonDecoration2::opacity() const
|
||||
{
|
||||
return static_cast<const KDecoration2*>( decoration() )->opacity();
|
||||
}
|
||||
|
||||
// kate: space-indent on; indent-width 4; mixedindent off; indent-mode cstyle;
|
||||
|
||||
|
|
|
@ -362,6 +362,23 @@ class KWIN_EXPORT KCommonDecoration : public QObject, public KDecorationDefines
|
|||
KCommonDecorationPrivate *d;
|
||||
};
|
||||
|
||||
class KWIN_EXPORT KCommonDecoration2
|
||||
: public KCommonDecoration
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KCommonDecoration2(KDecorationBridge* bridge, KDecorationFactory* factory);
|
||||
virtual ~KCommonDecoration2();
|
||||
virtual QList<QRect> shadowQuads( ShadowType type ) const;
|
||||
virtual double shadowOpacity( ShadowType type, double dataOpacity ) const;
|
||||
virtual double shadowBrightness( ShadowType type ) const;
|
||||
virtual double shadowSaturation( ShadowType type ) const;
|
||||
void repaintShadow();
|
||||
bool compositingActive() const;
|
||||
bool shadowsActive() const;
|
||||
double opacity() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Title bar buttons of KCommonDecoration need to inherit this class.
|
||||
*/
|
||||
|
|
|
@ -25,11 +25,14 @@
|
|||
#include "kcommondecoration_p.h"
|
||||
|
||||
#include "kcommondecoration.h"
|
||||
#include "kdecorationbridge.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "kcommondecoration_p.moc"
|
||||
|
||||
KCommonDecorationWrapper::KCommonDecorationWrapper( KCommonDecoration* deco, KDecorationBridge* bridge, KDecorationFactory* factory )
|
||||
: KDecoration( bridge, factory )
|
||||
: KDecoration2( bridge, factory )
|
||||
, decoration( deco )
|
||||
{
|
||||
}
|
||||
|
@ -109,3 +112,31 @@ void KCommonDecorationWrapper::reset( unsigned long changed )
|
|||
{
|
||||
return decoration->reset( changed );
|
||||
}
|
||||
|
||||
QList<QRect> KCommonDecorationWrapper::shadowQuads( ShadowType type ) const
|
||||
{
|
||||
if( KCommonDecoration2 *decoration2 = dynamic_cast<KCommonDecoration2*>( decoration ))
|
||||
return decoration2->shadowQuads( type );
|
||||
return QList<QRect>();
|
||||
}
|
||||
|
||||
double KCommonDecorationWrapper::shadowOpacity( ShadowType type, double dataOpacity ) const
|
||||
{
|
||||
if( KCommonDecoration2 *decoration2 = dynamic_cast<KCommonDecoration2*>( decoration ))
|
||||
return decoration2->shadowOpacity( type, dataOpacity );
|
||||
return dataOpacity;
|
||||
}
|
||||
|
||||
double KCommonDecorationWrapper::shadowBrightness( ShadowType type ) const
|
||||
{
|
||||
if( KCommonDecoration2 *decoration2 = dynamic_cast<KCommonDecoration2*>( decoration ))
|
||||
return decoration2->shadowBrightness( type );
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
double KCommonDecorationWrapper::shadowSaturation( ShadowType type ) const
|
||||
{
|
||||
if( KCommonDecoration2 *decoration2 = dynamic_cast<KCommonDecoration2*>( decoration ))
|
||||
return decoration2->shadowSaturation( type );
|
||||
return 1.0;
|
||||
}
|
||||
|
|
|
@ -32,12 +32,13 @@
|
|||
//
|
||||
|
||||
class KCommonDecoration;
|
||||
class KCommonDecoration2;
|
||||
class KDecorationBridge;
|
||||
class KDecorationFactory;
|
||||
|
||||
// wrapper all functionality that needs reimplementing in KDecoration and forward it to KCommonDecoration
|
||||
class KCommonDecorationWrapper
|
||||
: public KDecoration
|
||||
: public KDecoration2
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -57,6 +58,11 @@ class KCommonDecorationWrapper
|
|||
virtual bool drawbound( const QRect& geom, bool clear );
|
||||
virtual bool windowDocked( Position side );
|
||||
virtual void reset( unsigned long changed );
|
||||
|
||||
virtual QList<QRect> shadowQuads( ShadowType type ) const;
|
||||
virtual double shadowOpacity( ShadowType type, double dataOpacity ) const;
|
||||
virtual double shadowBrightness( ShadowType type ) const;
|
||||
virtual double shadowSaturation( ShadowType type ) const;
|
||||
private:
|
||||
KCommonDecoration* decoration;
|
||||
};
|
||||
|
|
|
@ -382,6 +382,65 @@ KDecoration::Position KDecoration::mousePosition( const QPoint& p ) const
|
|||
return m;
|
||||
}
|
||||
|
||||
|
||||
KDecoration2::KDecoration2( KDecorationBridge* bridge, KDecorationFactory* factory )
|
||||
: KDecoration( bridge, factory )
|
||||
{
|
||||
Q_ASSERT( dynamic_cast< KDecorationBridge2* >( bridge ));
|
||||
}
|
||||
|
||||
KDecoration2::~KDecoration2()
|
||||
{
|
||||
}
|
||||
|
||||
QList<QRect> KDecoration2::shadowQuads( ShadowType type ) const
|
||||
{
|
||||
Q_UNUSED( type );
|
||||
return QList<QRect>();
|
||||
}
|
||||
|
||||
double KDecoration2::shadowOpacity( ShadowType type, double dataOpacity ) const
|
||||
{
|
||||
if( isActive() && type == ShadowBorderedActive )
|
||||
return dataOpacity;
|
||||
else if( !isActive() && type == ShadowBorderedInactive )
|
||||
return dataOpacity;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double KDecoration2::shadowBrightness( ShadowType type ) const
|
||||
{
|
||||
Q_UNUSED( type );
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
double KDecoration2::shadowSaturation( ShadowType type ) const
|
||||
{
|
||||
Q_UNUSED( type );
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
void KDecoration2::repaintShadow()
|
||||
{
|
||||
static_cast< KDecorationBridge2* >( bridge_ )->repaintShadow();
|
||||
}
|
||||
|
||||
bool KDecoration2::compositingActive() const
|
||||
{
|
||||
return static_cast< KDecorationBridge2* >( bridge_ )->compositingActive();
|
||||
}
|
||||
|
||||
bool KDecoration2::shadowsActive() const
|
||||
{
|
||||
return static_cast< KDecorationBridge2* >( bridge_ )->shadowsActive();
|
||||
}
|
||||
|
||||
double KDecoration2::opacity() const
|
||||
{
|
||||
return static_cast< KDecorationBridge2* >( bridge_ )->opacity();
|
||||
}
|
||||
|
||||
|
||||
KDecorationOptions::KDecorationOptions()
|
||||
: d( new KDecorationOptionsPrivate )
|
||||
{
|
||||
|
|
|
@ -184,6 +184,8 @@ public:
|
|||
AbilityColorButtonBack = 2020, ///< decoration supports button background color
|
||||
AbilityColorButtonFore = 2021, ///< decoration supports button foreground color
|
||||
ABILITYCOLOR_END, ///< @internal
|
||||
// compositing
|
||||
AbilityCompositingShadow = 3000, ///< decoration supports window shadows
|
||||
// TODO colors for individual button types
|
||||
ABILITY_DUMMY = 10000000
|
||||
};
|
||||
|
@ -191,6 +193,18 @@ public:
|
|||
enum Requirement { REQUIREMENT_DUMMY = 1000000 };
|
||||
};
|
||||
|
||||
/**
|
||||
* Decoration shadow type.
|
||||
*/
|
||||
enum ShadowType
|
||||
{
|
||||
ShadowBorderedActive = 0, ///< Active shadow of decorated windows
|
||||
ShadowBorderedInactive, ///< Inctive shadow of decorated windows
|
||||
ShadowBorderlessActive, ///< Active shadow of undecorated windows
|
||||
ShadowBorderlessInactive, ///< Inctive shadow of undecorated windows
|
||||
ShadowOther ///< Shadow of all other windows (Menus, comboboxes, tooltips, etc.)
|
||||
};
|
||||
|
||||
class KDecorationProvides
|
||||
: public KDecorationDefines
|
||||
{
|
||||
|
@ -845,10 +859,59 @@ class KWIN_EXPORT KDecoration
|
|||
QWidget* w_;
|
||||
KDecorationFactory* factory_;
|
||||
friend class KDecorationOptions; // for options_
|
||||
friend class KDecoration2; // for bridge_
|
||||
static KDecorationOptions* options_;
|
||||
KDecorationPrivate* d;
|
||||
};
|
||||
|
||||
class KWIN_EXPORT KDecoration2
|
||||
: public KDecoration
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KDecoration2( KDecorationBridge* bridge, KDecorationFactory* factory );
|
||||
virtual ~KDecoration2();
|
||||
|
||||
/**
|
||||
* This function should return the positions of the shadow quads to be rendered.
|
||||
* All positions are relative to the window's top-left corner. Only "bordered"
|
||||
* windows will call this method.
|
||||
*/
|
||||
virtual QList<QRect> shadowQuads( ShadowType type ) const;
|
||||
/**
|
||||
* This function should return the opacity of the shadow. This is not multiplied
|
||||
* with the opacity of the window afterwards but is instead provided as \a dataOpacity
|
||||
*/
|
||||
virtual double shadowOpacity( ShadowType type, double dataOpacity ) const;
|
||||
/**
|
||||
* This function should return the desired brightness of the shadow.
|
||||
*/
|
||||
virtual double shadowBrightness( ShadowType type ) const;
|
||||
/**
|
||||
* This function should return the desired saturation of the shadow.
|
||||
*/
|
||||
virtual double shadowSaturation( ShadowType type ) const;
|
||||
|
||||
/**
|
||||
* Force a repaint of the shadow. Automatically called when the window changes states.
|
||||
*/
|
||||
void repaintShadow();
|
||||
/**
|
||||
* Returns @a true if compositing is enabled (Currently useless to decorations,
|
||||
* use \a shadowsActive() instead).
|
||||
*/
|
||||
bool compositingActive() const;
|
||||
/**
|
||||
* Returns @a true if compositing is enabled and the shadow effect is activated
|
||||
* by the current user.
|
||||
*/
|
||||
bool shadowsActive() const;
|
||||
/**
|
||||
* Returns the opacity that the decoration will be rendered at.
|
||||
*/
|
||||
double opacity() const;
|
||||
};
|
||||
|
||||
inline
|
||||
KDecorationDefines::MaximizeMode operator^( KDecorationDefines::MaximizeMode m1, KDecorationDefines::MaximizeMode m2 )
|
||||
{
|
||||
|
|
|
@ -89,6 +89,16 @@ class KDecorationBridge : public KDecorationDefines
|
|||
virtual void grabXServer( bool grab ) = 0;
|
||||
};
|
||||
|
||||
class KWIN_EXPORT KDecorationBridge2
|
||||
: public KDecorationBridge
|
||||
{
|
||||
public:
|
||||
virtual void repaintShadow() = 0;
|
||||
virtual bool compositingActive() const = 0;
|
||||
virtual bool shadowsActive() const = 0;
|
||||
virtual double opacity() const = 0;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -78,3 +78,39 @@ NET::WindowType KDecorationFactory::windowType( unsigned long supported_types, K
|
|||
{
|
||||
return bridge->windowType( supported_types );
|
||||
}
|
||||
|
||||
QList< QList<QImage> > KDecorationFactory2::shadowTextures()
|
||||
{
|
||||
return QList< QList<QImage> >();
|
||||
}
|
||||
|
||||
int KDecorationFactory2::shadowTextureList( ShadowType type ) const
|
||||
{
|
||||
Q_UNUSED( type );
|
||||
return -1;
|
||||
}
|
||||
|
||||
QList<QRect> KDecorationFactory2::shadowQuads( ShadowType type, QSize size ) const
|
||||
{
|
||||
Q_UNUSED( type );
|
||||
Q_UNUSED( size );
|
||||
return QList<QRect>();
|
||||
}
|
||||
|
||||
double KDecorationFactory2::shadowOpacity( ShadowType type, double dataOpacity ) const
|
||||
{
|
||||
Q_UNUSED( type );
|
||||
return dataOpacity;
|
||||
}
|
||||
|
||||
double KDecorationFactory2::shadowBrightness( ShadowType type ) const
|
||||
{
|
||||
Q_UNUSED( type );
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
double KDecorationFactory2::shadowSaturation( ShadowType type ) const
|
||||
{
|
||||
Q_UNUSED( type );
|
||||
return 1.0;
|
||||
}
|
||||
|
|
|
@ -114,7 +114,44 @@ class KWIN_EXPORT KDecorationFactory
|
|||
QList< KDecoration* > _decorations;
|
||||
KDecorationFactoryPrivate* d;
|
||||
};
|
||||
|
||||
|
||||
class KWIN_EXPORT KDecorationFactory2
|
||||
: public KDecorationFactory
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This function should return the texture lists that contain the textures of the
|
||||
* shadow quads. Textures are mapped to the quad that has the same list offset.
|
||||
* E.g. texture[0][2] is rendered where the third QRect that shadowQuads()
|
||||
* returns is if using the first texture list.
|
||||
*/
|
||||
virtual QList< QList<QImage> > shadowTextures();
|
||||
/**
|
||||
* This function should return the texture list offset for the requested type.
|
||||
*/
|
||||
virtual int shadowTextureList( ShadowType type ) const;
|
||||
/**
|
||||
* This function should return the positions of the shadow quads to be rendered.
|
||||
* All positions are relative to the window's top-left corner. Only "borderless"
|
||||
* and "other" types will call this method.
|
||||
* @param size The size of the window.
|
||||
*/
|
||||
virtual QList<QRect> shadowQuads( ShadowType type, QSize size ) const;
|
||||
/**
|
||||
* This function should return the opacity of the shadow. This is not multiplied
|
||||
* with the opacity of the window afterwards but is instead provided as \a dataOpacity
|
||||
*/
|
||||
virtual double shadowOpacity( ShadowType type, double dataOpacity ) const;
|
||||
/**
|
||||
* This function should return the desired brightness of the shadow.
|
||||
*/
|
||||
virtual double shadowBrightness( ShadowType type ) const;
|
||||
/**
|
||||
* This function should return the desired saturation of the shadow.
|
||||
*/
|
||||
virtual double shadowSaturation( ShadowType type ) const;
|
||||
};
|
||||
|
||||
inline const KDecorationOptions* KDecorationFactory::options()
|
||||
{
|
||||
return KDecoration::options();
|
||||
|
|
|
@ -224,6 +224,11 @@ void Effect::drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintD
|
|||
effects->drawWindow( w, mask, region, data );
|
||||
}
|
||||
|
||||
void Effect::buildQuads( EffectWindow* w, WindowQuadList& quadList )
|
||||
{
|
||||
effects->buildQuads( w, quadList );
|
||||
}
|
||||
|
||||
QRect Effect::transformWindowDamage( EffectWindow* w, const QRect& r )
|
||||
{
|
||||
return effects->transformWindowDamage( w, r );
|
||||
|
@ -279,6 +284,7 @@ EffectsHandler::EffectsHandler(CompositingType type)
|
|||
: current_paint_screen( 0 )
|
||||
, current_paint_window( 0 )
|
||||
, current_draw_window( 0 )
|
||||
, current_build_quads( 0 )
|
||||
, current_transform( 0 )
|
||||
, compositing_type( type )
|
||||
{
|
||||
|
@ -741,12 +747,12 @@ WindowQuadList WindowQuadList::select( WindowQuadType type ) const
|
|||
{
|
||||
foreach( const WindowQuad &q, *this )
|
||||
{
|
||||
if( q.type != type ) // something else than ones to select, make a copy and filter
|
||||
if( q.type() != type ) // something else than ones to select, make a copy and filter
|
||||
{
|
||||
WindowQuadList ret;
|
||||
foreach( const WindowQuad &q, *this )
|
||||
{
|
||||
if( q.type == type )
|
||||
if( q.type() == type )
|
||||
ret.append( q );
|
||||
}
|
||||
return ret;
|
||||
|
@ -759,12 +765,12 @@ WindowQuadList WindowQuadList::filterOut( WindowQuadType type ) const
|
|||
{
|
||||
foreach( const WindowQuad &q, *this )
|
||||
{
|
||||
if( q.type == type ) // something to filter out, make a copy and filter
|
||||
if( q.type() == type ) // something to filter out, make a copy and filter
|
||||
{
|
||||
WindowQuadList ret;
|
||||
foreach( const WindowQuad &q, *this )
|
||||
{
|
||||
if( q.type != type )
|
||||
if( q.type() != type )
|
||||
ret.append( q );
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <kwinconfig.h>
|
||||
#include <kwinglobals.h>
|
||||
#include "kdecoration.h"
|
||||
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QRect>
|
||||
|
@ -167,6 +168,14 @@ X-KDE-Library=kwin4_effect_cooleffect
|
|||
#define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
|
||||
KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR )
|
||||
|
||||
enum WindowQuadType
|
||||
{
|
||||
WindowQuadError, // for the stupid default ctor
|
||||
WindowQuadContents,
|
||||
WindowQuadDecoration,
|
||||
EFFECT_QUAD_TYPE_START = 100 ///< @internal
|
||||
};
|
||||
|
||||
/**
|
||||
* Infinite region (i.e. a special region type saying that everything needs to be painted).
|
||||
*/
|
||||
|
@ -343,6 +352,13 @@ class KWIN_EXPORT Effect
|
|||
* do any transformations
|
||||
**/
|
||||
virtual void drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
|
||||
/**
|
||||
* Define new window quads so that they can be transformed by other effects.
|
||||
* It's up to the effect to keep track of them.
|
||||
**/
|
||||
virtual void buildQuads( EffectWindow* w, WindowQuadList& quadList );
|
||||
|
||||
/**
|
||||
* This function is used e.g. by the shadow effect which adds area around windows
|
||||
* that needs to be painted as well - e.g. when a window is hidden and the workspace needs
|
||||
|
@ -479,6 +495,7 @@ class KWIN_EXPORT EffectsHandler
|
|||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) = 0;
|
||||
virtual void postPaintWindow( EffectWindow* w ) = 0;
|
||||
virtual void drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) = 0;
|
||||
virtual void buildQuads( EffectWindow* w, WindowQuadList& quadList ) = 0;
|
||||
virtual QRect transformWindowDamage( EffectWindow* w, const QRect& r );
|
||||
// Functions for handling input - e.g. when an Expose-like effect is shown, an input window
|
||||
// covering the whole screen is created and all mouse events will be intercepted by it.
|
||||
|
@ -526,6 +543,7 @@ class KWIN_EXPORT EffectsHandler
|
|||
* if used manually.
|
||||
*/
|
||||
virtual double animationTimeFactor() const = 0;
|
||||
virtual WindowQuadType newWindowQuadType() = 0;
|
||||
|
||||
virtual EffectWindow* findWindow( WId id ) const = 0;
|
||||
virtual EffectWindowList stackingOrder() const = 0;
|
||||
|
@ -571,6 +589,22 @@ class KWIN_EXPORT EffectsHandler
|
|||
*/
|
||||
virtual void registerPropertyType( long atom, bool reg ) = 0;
|
||||
|
||||
/**
|
||||
* Returns @a true if the active window decoration has shadow API hooks.
|
||||
*/
|
||||
virtual bool hasDecorationShadows() const = 0;
|
||||
/**
|
||||
* Returns the textures to be used in the shadow. Textures are mapped
|
||||
* to the quad that has the same list offset. E.g. texture[2] is
|
||||
* rendered where the third QRect that EffectWindow::shadowQuads()
|
||||
* returns is.
|
||||
*/
|
||||
virtual QList< QList<QImage> > shadowTextures() = 0;
|
||||
/**
|
||||
* Returns the texture list offset for the requested type.
|
||||
*/
|
||||
virtual int shadowTextureList( ShadowType type ) const = 0;
|
||||
|
||||
/**
|
||||
* Paints given text onto screen, possibly in elided form
|
||||
* @param text
|
||||
|
@ -611,6 +645,7 @@ class KWIN_EXPORT EffectsHandler
|
|||
int current_paint_screen;
|
||||
int current_paint_window;
|
||||
int current_draw_window;
|
||||
int current_build_quads;
|
||||
int current_transform;
|
||||
CompositingType compositing_type;
|
||||
};
|
||||
|
@ -784,6 +819,25 @@ class KWIN_EXPORT EffectWindow
|
|||
virtual EffectWindow* findModal() = 0;
|
||||
virtual EffectWindowList mainWindows() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the positions of the shadow quads to be rendered. All positions
|
||||
* are relative to the window's top-left corner.
|
||||
*/
|
||||
virtual QList<QRect> shadowQuads( ShadowType type ) const = 0;
|
||||
/**
|
||||
* Returns the opacity of the shadow. This has already been pre-multiplied by
|
||||
* the window's opacity if the decoration desires so.
|
||||
*/
|
||||
virtual double shadowOpacity( ShadowType type, double dataOpacity ) const = 0;
|
||||
/**
|
||||
* Returns the desired brightness of the shadow.
|
||||
*/
|
||||
virtual double shadowBrightness( ShadowType type ) const = 0;
|
||||
/**
|
||||
* Returns the desired saturation of the shadow.
|
||||
*/
|
||||
virtual double shadowSaturation( ShadowType type ) const = 0;
|
||||
|
||||
// TODO internal?
|
||||
virtual WindowQuadList buildQuads() const = 0;
|
||||
};
|
||||
|
@ -817,6 +871,8 @@ class KWIN_EXPORT WindowVertex
|
|||
void setY( double y );
|
||||
double originalX() const;
|
||||
double originalY() const;
|
||||
double textureX() const;
|
||||
double textureY() const;
|
||||
WindowVertex();
|
||||
WindowVertex( double x, double y, double tx, double ty );
|
||||
private:
|
||||
|
@ -827,13 +883,6 @@ class KWIN_EXPORT WindowVertex
|
|||
double tx, ty; // texture coords
|
||||
};
|
||||
|
||||
enum WindowQuadType
|
||||
{
|
||||
WindowQuadError, // for the stupid default ctor
|
||||
WindowQuadContents,
|
||||
WindowQuadDecoration
|
||||
};
|
||||
|
||||
/**
|
||||
* @short Class representing one area of a window.
|
||||
*
|
||||
|
@ -843,11 +892,14 @@ enum WindowQuadType
|
|||
class KWIN_EXPORT WindowQuad
|
||||
{
|
||||
public:
|
||||
explicit WindowQuad( WindowQuadType type );
|
||||
explicit WindowQuad( WindowQuadType type, int id = -1 );
|
||||
WindowQuad makeSubQuad( double x1, double y1, double x2, double y2 ) const;
|
||||
WindowVertex& operator[]( int index );
|
||||
const WindowVertex& operator[]( int index ) const;
|
||||
WindowQuadType type() const;
|
||||
int id() const;
|
||||
bool decoration() const;
|
||||
bool effect() const;
|
||||
double left() const;
|
||||
double right() const;
|
||||
double top() const;
|
||||
|
@ -861,7 +913,8 @@ class KWIN_EXPORT WindowQuad
|
|||
private:
|
||||
friend class WindowQuadList;
|
||||
WindowVertex verts[ 4 ];
|
||||
WindowQuadType type; // 0 - contents, 1 - decoration
|
||||
WindowQuadType quadType; // 0 - contents, 1 - decoration
|
||||
int quadID;
|
||||
};
|
||||
|
||||
class KWIN_EXPORT WindowQuadList
|
||||
|
@ -1472,6 +1525,18 @@ double WindowVertex::originalY() const
|
|||
return oy;
|
||||
}
|
||||
|
||||
inline
|
||||
double WindowVertex::textureX() const
|
||||
{
|
||||
return tx;
|
||||
}
|
||||
|
||||
inline
|
||||
double WindowVertex::textureY() const
|
||||
{
|
||||
return ty;
|
||||
}
|
||||
|
||||
inline
|
||||
void WindowVertex::move( double x, double y )
|
||||
{
|
||||
|
@ -1496,8 +1561,9 @@ void WindowVertex::setY( double y )
|
|||
***************************************************************/
|
||||
|
||||
inline
|
||||
WindowQuad::WindowQuad( WindowQuadType t )
|
||||
: type( t )
|
||||
WindowQuad::WindowQuad( WindowQuadType t, int id )
|
||||
: quadType( t )
|
||||
, quadID( id )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1515,11 +1581,31 @@ const WindowVertex& WindowQuad::operator[]( int index ) const
|
|||
return verts[ index ];
|
||||
}
|
||||
|
||||
inline
|
||||
WindowQuadType WindowQuad::type() const
|
||||
{
|
||||
assert( quadType != WindowQuadError );
|
||||
return quadType;
|
||||
}
|
||||
|
||||
inline
|
||||
int WindowQuad::id() const
|
||||
{
|
||||
return quadID;
|
||||
}
|
||||
|
||||
inline
|
||||
bool WindowQuad::decoration() const
|
||||
{
|
||||
assert( type != WindowQuadError );
|
||||
return type == WindowQuadDecoration;
|
||||
assert( quadType != WindowQuadError );
|
||||
return quadType == WindowQuadDecoration;
|
||||
}
|
||||
|
||||
inline
|
||||
bool WindowQuad::effect() const
|
||||
{
|
||||
assert( quadType != WindowQuadError );
|
||||
return quadType >= EFFECT_QUAD_TYPE_START;
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
|
@ -461,6 +461,7 @@ WindowQuadList Scene::Window::buildQuads() const
|
|||
ret = makeQuads( WindowQuadContents, contents );
|
||||
ret += makeQuads( WindowQuadDecoration, decoration );
|
||||
}
|
||||
effects->buildQuads( static_cast<Client*>( toplevel )->effectWindow(), ret );
|
||||
cached_quad_list = new WindowQuadList( ret );
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <kconfiggroup.h>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
#include "plugins.h"
|
||||
#include "client.h"
|
||||
#include "popupinfo.h"
|
||||
#include "tabbox.h"
|
||||
|
@ -57,7 +56,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "scene.h"
|
||||
#include "deleted.h"
|
||||
#include "effects.h"
|
||||
#include "kdecorationfactory.h"
|
||||
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/keysym.h>
|
||||
|
|
64
workspace.h
64
workspace.h
|
@ -31,8 +31,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <QDateTime>
|
||||
#include <kmanagerselection.h>
|
||||
|
||||
#include "plugins.h"
|
||||
#include "utils.h"
|
||||
#include "kdecoration.h"
|
||||
#include "kdecorationfactory.h"
|
||||
#include "sm.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
@ -242,6 +244,14 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
void disableRulesUpdates( bool disable );
|
||||
bool rulesUpdatesDisabled() const;
|
||||
|
||||
bool hasDecorationShadows() const;
|
||||
QList< QList<QImage> > decorationShadowTextures();
|
||||
int decorationShadowTextureList( ShadowType type ) const;
|
||||
QList<QRect> decorationShadowQuads( ShadowType type, QSize size ) const;
|
||||
double decorationShadowOpacity( ShadowType type, double dataOpacity ) const;
|
||||
double decorationShadowBrightness( ShadowType type ) const;
|
||||
double decorationShadowSaturation( ShadowType type ) const;
|
||||
|
||||
// dcop interface
|
||||
void cascadeDesktop();
|
||||
void unclutterDesktop();
|
||||
|
@ -981,6 +991,60 @@ void Workspace::checkCompositeTimer()
|
|||
setCompositeTimer();
|
||||
}
|
||||
|
||||
inline
|
||||
bool Workspace::hasDecorationShadows() const
|
||||
{
|
||||
return mgr->factory()->supports( AbilityCompositingShadow );
|
||||
}
|
||||
|
||||
inline
|
||||
QList< QList<QImage> > Workspace::decorationShadowTextures()
|
||||
{
|
||||
if( KDecorationFactory2* factory = dynamic_cast< KDecorationFactory2* >( mgr->factory() ))
|
||||
return factory->shadowTextures();
|
||||
return QList< QList<QImage> >();
|
||||
}
|
||||
|
||||
inline
|
||||
int Workspace::decorationShadowTextureList( ShadowType type ) const
|
||||
{
|
||||
if( KDecorationFactory2* factory = dynamic_cast< KDecorationFactory2* >( mgr->factory() ))
|
||||
return factory->shadowTextureList( type );
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline
|
||||
QList<QRect> Workspace::decorationShadowQuads( ShadowType type, QSize size ) const
|
||||
{
|
||||
if( KDecorationFactory2* factory = dynamic_cast< KDecorationFactory2* >( mgr->factory() ))
|
||||
return factory->shadowQuads( type, size );
|
||||
return QList<QRect>();
|
||||
}
|
||||
|
||||
inline
|
||||
double Workspace::decorationShadowOpacity( ShadowType type, double dataOpacity ) const
|
||||
{
|
||||
if( KDecorationFactory2* factory = dynamic_cast< KDecorationFactory2* >( mgr->factory() ))
|
||||
return factory->shadowOpacity( type, dataOpacity );
|
||||
return dataOpacity;
|
||||
}
|
||||
|
||||
inline
|
||||
double Workspace::decorationShadowBrightness( ShadowType type ) const
|
||||
{
|
||||
if( KDecorationFactory2* factory = dynamic_cast< KDecorationFactory2* >( mgr->factory() ))
|
||||
return factory->shadowBrightness( type );
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
inline
|
||||
double Workspace::decorationShadowSaturation( ShadowType type ) const
|
||||
{
|
||||
if( KDecorationFactory2* factory = dynamic_cast< KDecorationFactory2* >( mgr->factory() ))
|
||||
return factory->shadowSaturation( type );
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue