Add support for translation and add two "plugins" that
make windows transparent or shake them while moving. svn path=/branches/work/kwin_composite/; revision=559013
This commit is contained in:
parent
391bb6b28d
commit
0516e1e73b
18 changed files with 498 additions and 136 deletions
58
client.cpp
58
client.cpp
|
@ -1600,58 +1600,6 @@ bool Client::wantsInput() const
|
||||||
return rules()->checkAcceptFocus( input || Ptakefocus );
|
return rules()->checkAcceptFocus( input || Ptakefocus );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::isDesktop() const
|
|
||||||
{
|
|
||||||
return windowType() == NET::Desktop;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Client::isDock() const
|
|
||||||
{
|
|
||||||
return windowType() == NET::Dock;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Client::isTopMenu() const
|
|
||||||
{
|
|
||||||
return windowType() == NET::TopMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Client::isMenu() const
|
|
||||||
{
|
|
||||||
return windowType() == NET::Menu && !isTopMenu(); // because of backwards comp.
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Client::isToolbar() const
|
|
||||||
{
|
|
||||||
return windowType() == NET::Toolbar;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Client::isSplash() const
|
|
||||||
{
|
|
||||||
return windowType() == NET::Splash;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Client::isUtility() const
|
|
||||||
{
|
|
||||||
return windowType() == NET::Utility;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Client::isDialog() const
|
|
||||||
{
|
|
||||||
return windowType() == NET::Dialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Client::isNormalWindow() const
|
|
||||||
{
|
|
||||||
return windowType() == NET::Normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Client::isSpecialWindow() const
|
|
||||||
{
|
|
||||||
return isDesktop() || isDock() || isSplash() || isTopMenu()
|
|
||||||
|| isToolbar(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
NET::WindowType Client::windowType( bool direct, int supported_types ) const
|
NET::WindowType Client::windowType( bool direct, int supported_types ) const
|
||||||
{
|
{
|
||||||
NET::WindowType wt = info->windowType( supported_types );
|
NET::WindowType wt = info->windowType( supported_types );
|
||||||
|
@ -1683,6 +1631,12 @@ NET::WindowType Client::windowType( bool direct, int supported_types ) const
|
||||||
return wt;
|
return wt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Client::isSpecialWindow() const
|
||||||
|
{
|
||||||
|
return isDesktop() || isDock() || isSplash() || isTopMenu()
|
||||||
|
|| isToolbar(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets an appropriate cursor shape for the logical mouse position \a m
|
Sets an appropriate cursor shape for the logical mouse position \a m
|
||||||
|
|
||||||
|
|
43
client.h
43
client.h
|
@ -67,12 +67,17 @@ class Client
|
||||||
const Group* group() const;
|
const Group* group() const;
|
||||||
Group* group();
|
Group* group();
|
||||||
void checkGroup( Group* gr = NULL, bool force = false );
|
void checkGroup( Group* gr = NULL, bool force = false );
|
||||||
// prefer isXXX() instead
|
|
||||||
NET::WindowType windowType( bool direct = false, int supported_types = SUPPORTED_WINDOW_TYPES_MASK ) const;
|
|
||||||
const WindowRules* rules() const;
|
const WindowRules* rules() const;
|
||||||
void removeRule( Rules* r );
|
void removeRule( Rules* r );
|
||||||
void setupWindowRules( bool ignore_temporary );
|
void setupWindowRules( bool ignore_temporary );
|
||||||
void applyWindowRules();
|
void applyWindowRules();
|
||||||
|
virtual NET::WindowType windowType( bool direct = false, int supported_types = SUPPORTED_WINDOW_TYPES_MASK ) const;
|
||||||
|
// returns true for "special" windows and false for windows which are "normal"
|
||||||
|
// (normal=window which has a border, can be moved by the user, can be closed, etc.)
|
||||||
|
// true for Desktop, Dock, Splash, Override and TopMenu (and Toolbar??? - for now)
|
||||||
|
// false for Normal, Dialog, Utility and Menu (and Toolbar??? - not yet) TODO
|
||||||
|
bool isSpecialWindow() const;
|
||||||
|
bool hasNETSupport() const;
|
||||||
|
|
||||||
QSize minSize() const;
|
QSize minSize() const;
|
||||||
QSize maxSize() const;
|
QSize maxSize() const;
|
||||||
|
@ -158,24 +163,9 @@ class Client
|
||||||
// auxiliary functions, depend on the windowType
|
// auxiliary functions, depend on the windowType
|
||||||
bool wantsTabFocus() const;
|
bool wantsTabFocus() const;
|
||||||
bool wantsInput() const;
|
bool wantsInput() const;
|
||||||
bool hasNETSupport() const;
|
|
||||||
bool isMovable() const;
|
|
||||||
bool isDesktop() const;
|
|
||||||
bool isDock() const;
|
|
||||||
bool isToolbar() const;
|
|
||||||
bool isTopMenu() const;
|
|
||||||
bool isMenu() const;
|
|
||||||
bool isNormalWindow() const; // normal as in 'NET::Normal or NET::Unknown non-transient'
|
|
||||||
bool isDialog() const;
|
|
||||||
bool isSplash() const;
|
|
||||||
bool isUtility() const;
|
|
||||||
// returns true for "special" windows and false for windows which are "normal"
|
|
||||||
// (normal=window which has a border, can be moved by the user, can be closed, etc.)
|
|
||||||
// true for Desktop, Dock, Splash, Override and TopMenu (and Toolbar??? - for now)
|
|
||||||
// false for Normal, Dialog, Utility and Menu (and Toolbar??? - not yet) TODO
|
|
||||||
bool isSpecialWindow() const;
|
|
||||||
|
|
||||||
bool isResizable() const;
|
bool isResizable() const;
|
||||||
|
bool isMovable() const;
|
||||||
bool isCloseable() const; // may be closed by the user (may have a close button)
|
bool isCloseable() const; // may be closed by the user (may have a close button)
|
||||||
|
|
||||||
void takeActivity( int flags, bool handled, allowed_t ); // takes ActivityFlags as arg (in utils.h)
|
void takeActivity( int flags, bool handled, allowed_t ); // takes ActivityFlags as arg (in utils.h)
|
||||||
|
@ -283,6 +273,15 @@ class Client
|
||||||
void checkActiveModal();
|
void checkActiveModal();
|
||||||
bool hasStrut() const;
|
bool hasStrut() const;
|
||||||
|
|
||||||
|
bool isMove() const
|
||||||
|
{
|
||||||
|
return moveResizeMode && mode == PositionCenter;
|
||||||
|
}
|
||||||
|
bool isResize() const
|
||||||
|
{
|
||||||
|
return moveResizeMode && mode != PositionCenter;
|
||||||
|
}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void autoRaise();
|
void autoRaise();
|
||||||
void shadeHover();
|
void shadeHover();
|
||||||
|
@ -411,14 +410,6 @@ class Client
|
||||||
bool move_faked_activity;
|
bool move_faked_activity;
|
||||||
Window move_resize_grab_window;
|
Window move_resize_grab_window;
|
||||||
bool unrestrictedMoveResize;
|
bool unrestrictedMoveResize;
|
||||||
bool isMove() const
|
|
||||||
{
|
|
||||||
return moveResizeMode && mode == PositionCenter;
|
|
||||||
}
|
|
||||||
bool isResize() const
|
|
||||||
{
|
|
||||||
return moveResizeMode && mode != PositionCenter;
|
|
||||||
}
|
|
||||||
|
|
||||||
Position mode;
|
Position mode;
|
||||||
QPoint moveOffset;
|
QPoint moveOffset;
|
||||||
|
|
|
@ -74,6 +74,8 @@ void Workspace::addDamage( const QRect& r )
|
||||||
|
|
||||||
void Workspace::addDamage( int x, int y, int w, int h )
|
void Workspace::addDamage( int x, int y, int w, int h )
|
||||||
{
|
{
|
||||||
|
if( !compositing())
|
||||||
|
return;
|
||||||
XRectangle r;
|
XRectangle r;
|
||||||
r.x = x;
|
r.x = x;
|
||||||
r.y = y;
|
r.y = y;
|
||||||
|
@ -104,6 +106,44 @@ void Workspace::addDamage( XserverRegion r, bool destroy )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Workspace::addDamage( Toplevel* c, const QRect& r )
|
||||||
|
{
|
||||||
|
addDamage( c, r.x(), r.y(), r.width(), r.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Workspace::addDamage( Toplevel* c, int x, int y, int w, int h )
|
||||||
|
{
|
||||||
|
if( !compositing())
|
||||||
|
return;
|
||||||
|
XRectangle r;
|
||||||
|
r.x = x;
|
||||||
|
r.y = y;
|
||||||
|
r.width = w;
|
||||||
|
r.height = h;
|
||||||
|
addDamage( c, XFixesCreateRegion( display(), &r, 1 ), true );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Workspace::addDamage( Toplevel* c, XserverRegion r, bool destroy )
|
||||||
|
{
|
||||||
|
if( !compositing())
|
||||||
|
return;
|
||||||
|
if( !destroy )
|
||||||
|
{
|
||||||
|
XserverRegion r2 = XFixesCreateRegion( display(), NULL, 0 );
|
||||||
|
XFixesCopyRegion( display(), r2, r );
|
||||||
|
r = r2;
|
||||||
|
destroy = true;
|
||||||
|
}
|
||||||
|
scene->transformWindowDamage( c, r );
|
||||||
|
if( damage != None )
|
||||||
|
{
|
||||||
|
XFixesUnionRegion( display(), damage, damage, r );
|
||||||
|
XFixesDestroyRegion( display(), r );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
damage = r;
|
||||||
|
}
|
||||||
|
|
||||||
void Workspace::compositeTimeout()
|
void Workspace::compositeTimeout()
|
||||||
{
|
{
|
||||||
if( damage == None )
|
if( damage == None )
|
||||||
|
@ -177,7 +217,7 @@ void Toplevel::damageNotifyEvent( XDamageNotifyEvent* e )
|
||||||
{
|
{
|
||||||
XserverRegion r = XFixesCreateRegion( display(), &e->area, 1 );
|
XserverRegion r = XFixesCreateRegion( display(), &e->area, 1 );
|
||||||
XFixesTranslateRegion( display(), r, x(), y());
|
XFixesTranslateRegion( display(), r, x(), y());
|
||||||
workspace()->addDamage( r, true );
|
workspace()->addDamage( this, r, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
190
effects.cpp
190
effects.cpp
|
@ -10,6 +10,10 @@ License. See the file "COPYING" for the exact licensing terms.
|
||||||
|
|
||||||
#include "effects.h"
|
#include "effects.h"
|
||||||
|
|
||||||
|
#include "toplevel.h"
|
||||||
|
#include "client.h"
|
||||||
|
#include "scene.h"
|
||||||
|
|
||||||
namespace KWinInternal
|
namespace KWinInternal
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -37,6 +41,67 @@ Matrix::Matrix()
|
||||||
m[ 3 ][ 3 ] = 1;
|
m[ 3 ][ 3 ] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Matrix operator*( const Matrix& m1, const Matrix& m2 )
|
||||||
|
{
|
||||||
|
Matrix r;
|
||||||
|
for( int i = 0;
|
||||||
|
i < 4;
|
||||||
|
++i )
|
||||||
|
for( int j = 0;
|
||||||
|
j < 4;
|
||||||
|
++j )
|
||||||
|
{
|
||||||
|
double s = 0;
|
||||||
|
for( int k = 0;
|
||||||
|
k < 4;
|
||||||
|
++k )
|
||||||
|
s += m1.m[ i ][ k ] * m2.m[ k ][ j ];
|
||||||
|
r.m[ i ][ j ] = s;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Matrix::isIdentity() const
|
||||||
|
{
|
||||||
|
return m[ 0 ][ 0 ] == 1
|
||||||
|
&& m[ 0 ][ 1 ] == 0
|
||||||
|
&& m[ 0 ][ 2 ] == 0
|
||||||
|
&& m[ 0 ][ 3 ] == 0
|
||||||
|
&& m[ 1 ][ 0 ] == 0
|
||||||
|
&& m[ 1 ][ 1 ] == 1
|
||||||
|
&& m[ 1 ][ 2 ] == 0
|
||||||
|
&& m[ 1 ][ 3 ] == 0
|
||||||
|
&& m[ 2 ][ 0 ] == 0
|
||||||
|
&& m[ 2 ][ 1 ] == 0
|
||||||
|
&& m[ 2 ][ 2 ] == 1
|
||||||
|
&& m[ 2 ][ 3 ] == 0
|
||||||
|
&& m[ 3 ][ 0 ] == 0
|
||||||
|
&& m[ 3 ][ 1 ] == 0
|
||||||
|
&& m[ 3 ][ 2 ] == 0
|
||||||
|
&& m[ 3 ][ 3 ] == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Matrix::isOnlyTranslate() const
|
||||||
|
{
|
||||||
|
return m[ 0 ][ 0 ] == 1
|
||||||
|
&& m[ 0 ][ 1 ] == 0
|
||||||
|
&& m[ 0 ][ 2 ] == 0
|
||||||
|
// && m[ 0 ][ 3 ] ==
|
||||||
|
&& m[ 1 ][ 0 ] == 0
|
||||||
|
&& m[ 1 ][ 1 ] == 1
|
||||||
|
&& m[ 1 ][ 2 ] == 0
|
||||||
|
// && m[ 1 ][ 3 ] ==
|
||||||
|
&& m[ 2 ][ 0 ] == 0
|
||||||
|
&& m[ 2 ][ 1 ] == 0
|
||||||
|
&& m[ 2 ][ 2 ] == 1
|
||||||
|
// && m[ 2 ][ 3 ] ==
|
||||||
|
&& m[ 3 ][ 0 ] == 0
|
||||||
|
&& m[ 3 ][ 1 ] == 0
|
||||||
|
&& m[ 3 ][ 2 ] == 0
|
||||||
|
&& m[ 3 ][ 3 ] == 1;
|
||||||
|
}
|
||||||
|
|
||||||
//****************************************
|
//****************************************
|
||||||
// Effect
|
// Effect
|
||||||
//****************************************
|
//****************************************
|
||||||
|
@ -45,61 +110,142 @@ Effect::~Effect()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Effect::windowUserMoved( Toplevel* )
|
void Effect::windowUserMovedResized( Toplevel* , bool, bool )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Effect::windowUserResized( Toplevel* )
|
void Effect::transformWindow( Toplevel*, EffectData& )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Effect::paintWindow( Toplevel*, EffectData& )
|
void Effect::transformWorkspace( Workspace*, EffectData& )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Effect::paintWorkspace( Workspace*, EffectData& )
|
void Effect::windowDeleted( Toplevel* )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MakeHalfTransparent::transformWindow( Toplevel* c, EffectData& data )
|
||||||
|
{
|
||||||
|
if( c->isDialog())
|
||||||
|
data.opacity *= 0.8;
|
||||||
|
if( Client* c2 = dynamic_cast< Client* >( c ))
|
||||||
|
if( c2->isMove() || c2->isResize())
|
||||||
|
data.opacity *= 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakeHalfTransparent::windowUserMovedResized( Toplevel* c, bool first, bool last )
|
||||||
|
{
|
||||||
|
if( first || last )
|
||||||
|
c->workspace()->addDamage( c, c->geometry());
|
||||||
|
}
|
||||||
|
|
||||||
|
ShakyMove::ShakyMove()
|
||||||
|
{
|
||||||
|
connect( &timer, SIGNAL( timeout()), SLOT( tick()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int shaky_diff[] = { 0, 1, 2, 3, 2, 1, 0, -1, -2, -3, -2, -1 };
|
||||||
|
static const int SHAKY_MAX = sizeof( shaky_diff ) / sizeof( shaky_diff[ 0 ] );
|
||||||
|
|
||||||
|
void ShakyMove::transformWindow( Toplevel* c, EffectData& data )
|
||||||
|
{
|
||||||
|
if( windows.contains( c ))
|
||||||
|
{
|
||||||
|
Matrix m;
|
||||||
|
m.m[ 0 ][ 3 ] = shaky_diff[ windows[ c ]];
|
||||||
|
data.matrix *= m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShakyMove::windowUserMovedResized( Toplevel* c, bool first, bool last )
|
||||||
|
{
|
||||||
|
if( first )
|
||||||
|
{
|
||||||
|
if( windows.isEmpty())
|
||||||
|
timer.start( 50 );
|
||||||
|
windows[ c ] = 0;
|
||||||
|
}
|
||||||
|
else if( last )
|
||||||
|
{
|
||||||
|
windows.remove( c );
|
||||||
|
scene->updateTransformation( c );
|
||||||
|
c->workspace()->addDamage( c, c->geometry().adjusted( -3, 7, 0, 0 ));
|
||||||
|
if( windows.isEmpty())
|
||||||
|
timer.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShakyMove::windowDeleted( Toplevel* c )
|
||||||
|
{
|
||||||
|
windows.remove( c );
|
||||||
|
if( windows.isEmpty())
|
||||||
|
timer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShakyMove::tick()
|
||||||
|
{
|
||||||
|
for( QMap< Toplevel*, int >::Iterator it = windows.begin();
|
||||||
|
it != windows.end();
|
||||||
|
++it )
|
||||||
|
{
|
||||||
|
if( *it == SHAKY_MAX - 1 )
|
||||||
|
*it = 0;
|
||||||
|
else
|
||||||
|
++(*it);
|
||||||
|
scene->updateTransformation( it.key());
|
||||||
|
it.key()->workspace()->addDamage( it.key(), it.key()->geometry().adjusted( -1, 2, 0, 0 ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static MakeHalfTransparent* mht;
|
||||||
|
static ShakyMove* sm;
|
||||||
|
|
||||||
//****************************************
|
//****************************************
|
||||||
// EffectsHandler
|
// 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()
|
EffectsHandler::EffectsHandler()
|
||||||
{
|
{
|
||||||
mht = new MakeHalfTransparent;
|
mht = new MakeHalfTransparent;
|
||||||
|
sm = new ShakyMove;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectsHandler::windowUserMoved( Toplevel* )
|
void EffectsHandler::windowUserMovedResized( Toplevel* c, bool first, bool last )
|
||||||
{
|
{
|
||||||
|
if( mht )
|
||||||
|
mht->windowUserMovedResized( c, first, last );
|
||||||
|
if( sm )
|
||||||
|
sm->windowUserMovedResized( c, first, last );
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectsHandler::windowUserResized( Toplevel* )
|
void EffectsHandler::transformWindow( Toplevel* c, EffectData& data )
|
||||||
{
|
{
|
||||||
|
if( mht )
|
||||||
|
mht->transformWindow( c, data );
|
||||||
|
if( sm )
|
||||||
|
sm->transformWindow( c, data );
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectsHandler::paintWindow( Toplevel* c, EffectData& data )
|
void EffectsHandler::transformWorkspace( Workspace* w, EffectData& data )
|
||||||
{
|
{
|
||||||
mht->paintWindow( c, data );
|
if( mht )
|
||||||
|
mht->transformWorkspace( w, data );
|
||||||
|
if( sm )
|
||||||
|
sm->transformWorkspace( w, data );
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectsHandler::paintWorkspace( Workspace*, EffectData& )
|
void EffectsHandler::windowDeleted( Toplevel* c )
|
||||||
{
|
{
|
||||||
|
if( mht )
|
||||||
|
mht->windowDeleted( c );
|
||||||
|
if( sm )
|
||||||
|
sm->windowDeleted( c );
|
||||||
}
|
}
|
||||||
|
|
||||||
EffectsHandler* effects;
|
EffectsHandler* effects;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
#include "effects.moc"
|
||||||
|
|
73
effects.h
73
effects.h
|
@ -13,6 +13,9 @@ License. See the file "COPYING" for the exact licensing terms.
|
||||||
#ifndef KWIN_EFFECTS_H
|
#ifndef KWIN_EFFECTS_H
|
||||||
#define KWIN_EFFECTS_H
|
#define KWIN_EFFECTS_H
|
||||||
|
|
||||||
|
#include <QMap>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
namespace KWinInternal
|
namespace KWinInternal
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -23,9 +26,37 @@ class Matrix
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Matrix();
|
Matrix();
|
||||||
|
Matrix& operator*=( const Matrix& m );
|
||||||
|
bool isOnlyTranslate() const;
|
||||||
|
bool isIdentity() const;
|
||||||
|
double xTranslate() const;
|
||||||
|
double yTranslate() const;
|
||||||
|
double zTranslate() const;
|
||||||
double m[ 4 ][ 4 ];
|
double m[ 4 ][ 4 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Matrix operator*( const Matrix& m1, const Matrix& m2 );
|
||||||
|
|
||||||
|
inline Matrix& Matrix::operator*=( const Matrix& m )
|
||||||
|
{
|
||||||
|
return *this = *this * m;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double Matrix::xTranslate() const
|
||||||
|
{
|
||||||
|
return m[ 0 ][ 3 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double Matrix::yTranslate() const
|
||||||
|
{
|
||||||
|
return m[ 1 ][ 3 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double Matrix::zTranslate() const
|
||||||
|
{
|
||||||
|
return m[ 2 ][ 3 ];
|
||||||
|
}
|
||||||
|
|
||||||
class EffectData
|
class EffectData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -37,24 +68,50 @@ class Effect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Effect();
|
virtual ~Effect();
|
||||||
virtual void windowUserMoved( Toplevel* c );
|
// called when moved/resized or once after it's finished
|
||||||
virtual void windowUserResized( Toplevel* c );
|
virtual void windowUserMovedResized( Toplevel* c, bool first, bool last );
|
||||||
virtual void paintWindow( Toplevel* c, EffectData& data );
|
virtual void windowDeleted( Toplevel* c );
|
||||||
virtual void paintWorkspace( Workspace*, EffectData& data );
|
virtual void transformWindow( Toplevel* c, EffectData& data );
|
||||||
|
virtual void transformWorkspace( Workspace*, EffectData& data );
|
||||||
};
|
};
|
||||||
|
|
||||||
class EffectsHandler
|
class EffectsHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EffectsHandler();
|
EffectsHandler();
|
||||||
void windowUserMoved( Toplevel* c );
|
void windowUserMovedResized( Toplevel* c, bool first, bool last );
|
||||||
void windowUserResized( Toplevel* c );
|
void windowDeleted( Toplevel* c );
|
||||||
void paintWindow( Toplevel* c, EffectData& data );
|
void transformWindow( Toplevel* c, EffectData& data );
|
||||||
void paintWorkspace( Workspace*, EffectData& data );
|
void transformWorkspace( Workspace*, EffectData& data );
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EffectsHandler* effects;
|
extern EffectsHandler* effects;
|
||||||
|
|
||||||
|
class MakeHalfTransparent
|
||||||
|
: public Effect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void windowUserMovedResized( Toplevel* c, bool first, bool last );
|
||||||
|
virtual void transformWindow( Toplevel* c, EffectData& data );
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShakyMove
|
||||||
|
: public QObject, public Effect
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ShakyMove();
|
||||||
|
virtual void windowUserMovedResized( Toplevel* c, bool first, bool last );
|
||||||
|
virtual void transformWindow( Toplevel* c, EffectData& data );
|
||||||
|
virtual void windowDeleted( Toplevel* c );
|
||||||
|
private slots:
|
||||||
|
void tick();
|
||||||
|
private:
|
||||||
|
QMap< Toplevel*, int > windows;
|
||||||
|
QTimer timer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -577,7 +577,7 @@ bool Client::windowEvent( XEvent* e )
|
||||||
{
|
{
|
||||||
if( compositing())
|
if( compositing())
|
||||||
{
|
{
|
||||||
workspace()->addDamage( geometry());
|
workspace()->addDamage( this, geometry());
|
||||||
scene->windowOpacityChanged( this );
|
scene->windowOpacityChanged( this );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1613,7 +1613,7 @@ bool Unmanaged::windowEvent( XEvent* e )
|
||||||
if( dirty[ NETWinInfo::PROTOCOLS2 ] & NET::WM2Opacity )
|
if( dirty[ NETWinInfo::PROTOCOLS2 ] & NET::WM2Opacity )
|
||||||
{
|
{
|
||||||
scene->windowOpacityChanged( this );
|
scene->windowOpacityChanged( this );
|
||||||
workspace()->addDamage( geometry());
|
workspace()->addDamage( this, geometry());
|
||||||
}
|
}
|
||||||
switch (e->type)
|
switch (e->type)
|
||||||
{
|
{
|
||||||
|
@ -1647,9 +1647,9 @@ void Unmanaged::configureNotifyEvent( XConfigureEvent* e )
|
||||||
{
|
{
|
||||||
resetWindowPixmap();
|
resetWindowPixmap();
|
||||||
// add old and new geometry to damage
|
// add old and new geometry to damage
|
||||||
workspace()->addDamage( geometry());
|
workspace()->addDamage( this, geometry());
|
||||||
geom = QRect( e->x, e->y, e->width, e->height );
|
geom = QRect( e->x, e->y, e->width, e->height );
|
||||||
workspace()->addDamage( geometry());
|
workspace()->addDamage( this, geometry());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ****************************************
|
// ****************************************
|
||||||
|
|
22
geometry.cpp
22
geometry.cpp
|
@ -1660,7 +1660,7 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force )
|
||||||
}
|
}
|
||||||
if( force == NormalGeometrySet && geom == QRect( x, y, w, h ))
|
if( force == NormalGeometrySet && geom == QRect( x, y, w, h ))
|
||||||
return;
|
return;
|
||||||
workspace()->addDamage( geometry()); // TODO cache the previous real geometry
|
workspace()->addDamage( this, geometry()); // TODO cache the previous real geometry
|
||||||
geom = QRect( x, y, w, h );
|
geom = QRect( x, y, w, h );
|
||||||
updateWorkareaDiffs();
|
updateWorkareaDiffs();
|
||||||
if( postpone_geometry_updates != 0 )
|
if( postpone_geometry_updates != 0 )
|
||||||
|
@ -1686,7 +1686,7 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force )
|
||||||
updateWindowRules();
|
updateWindowRules();
|
||||||
checkMaximizeGeometry();
|
checkMaximizeGeometry();
|
||||||
resetWindowPixmap();
|
resetWindowPixmap();
|
||||||
workspace()->addDamage( geometry());
|
workspace()->addDamage( this, geometry());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::plainResize( int w, int h, ForceGeometry_t force )
|
void Client::plainResize( int w, int h, ForceGeometry_t force )
|
||||||
|
@ -1718,7 +1718,7 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
|
||||||
}
|
}
|
||||||
if( force == NormalGeometrySet && geom.size() == QSize( w, h ))
|
if( force == NormalGeometrySet && geom.size() == QSize( w, h ))
|
||||||
return;
|
return;
|
||||||
workspace()->addDamage( geometry()); // TODO cache the previous real geometry
|
workspace()->addDamage( this, geometry()); // TODO cache the previous real geometry
|
||||||
geom.setSize( QSize( w, h ));
|
geom.setSize( QSize( w, h ));
|
||||||
updateWorkareaDiffs();
|
updateWorkareaDiffs();
|
||||||
if( postpone_geometry_updates != 0 )
|
if( postpone_geometry_updates != 0 )
|
||||||
|
@ -1743,7 +1743,7 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
|
||||||
updateWindowRules();
|
updateWindowRules();
|
||||||
checkMaximizeGeometry();
|
checkMaximizeGeometry();
|
||||||
resetWindowPixmap();
|
resetWindowPixmap();
|
||||||
workspace()->addDamage( geometry());
|
workspace()->addDamage( this, geometry());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -1753,7 +1753,7 @@ void Client::move( int x, int y, ForceGeometry_t force )
|
||||||
{
|
{
|
||||||
if( force == NormalGeometrySet && geom.topLeft() == QPoint( x, y ))
|
if( force == NormalGeometrySet && geom.topLeft() == QPoint( x, y ))
|
||||||
return;
|
return;
|
||||||
workspace()->addDamage( geometry()); // TODO cache the previous real geometry
|
workspace()->addDamage( this, geometry()); // TODO cache the previous real geometry
|
||||||
geom.moveTopLeft( QPoint( x, y ));
|
geom.moveTopLeft( QPoint( x, y ));
|
||||||
updateWorkareaDiffs();
|
updateWorkareaDiffs();
|
||||||
if( postpone_geometry_updates != 0 )
|
if( postpone_geometry_updates != 0 )
|
||||||
|
@ -1765,7 +1765,7 @@ void Client::move( int x, int y, ForceGeometry_t force )
|
||||||
sendSyntheticConfigureNotify();
|
sendSyntheticConfigureNotify();
|
||||||
updateWindowRules();
|
updateWindowRules();
|
||||||
checkMaximizeGeometry();
|
checkMaximizeGeometry();
|
||||||
workspace()->addDamage( geometry());
|
workspace()->addDamage( this, geometry());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::postponeGeometryUpdates( bool postpone )
|
void Client::postponeGeometryUpdates( bool postpone )
|
||||||
|
@ -2265,6 +2265,8 @@ bool Client::startMoveResize()
|
||||||
// not needed anymore? kapp->installEventFilter( eater );
|
// not needed anymore? kapp->installEventFilter( eater );
|
||||||
}
|
}
|
||||||
Notify::raise( isResize() ? Notify::ResizeStart : Notify::MoveStart );
|
Notify::raise( isResize() ? Notify::ResizeStart : Notify::MoveStart );
|
||||||
|
if( effects )
|
||||||
|
effects->windowUserMovedResized( this, true, false );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2278,6 +2280,8 @@ void Client::finishMoveResize( bool cancel )
|
||||||
checkMaximizeGeometry();
|
checkMaximizeGeometry();
|
||||||
// FRAME update();
|
// FRAME update();
|
||||||
Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd );
|
Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd );
|
||||||
|
if( effects )
|
||||||
|
effects->windowUserMovedResized( this, false, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::leaveMoveResize()
|
void Client::leaveMoveResize()
|
||||||
|
@ -2541,10 +2545,8 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root )
|
||||||
}
|
}
|
||||||
if ( isMove() )
|
if ( isMove() )
|
||||||
workspace()->clientMoved(globalPos, xTime());
|
workspace()->clientMoved(globalPos, xTime());
|
||||||
if( isMove())
|
if( effects )
|
||||||
effects->windowUserMoved( this );
|
effects->windowUserMovedResized( this, false, false );
|
||||||
else
|
|
||||||
effects->windowUserResized( this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -523,7 +523,7 @@ bool Client::manage( Window w, bool isMapped )
|
||||||
delete session;
|
delete session;
|
||||||
|
|
||||||
if( isMapped ) // otherwise damage will come when the client paints it
|
if( isMapped ) // otherwise damage will come when the client paints it
|
||||||
workspace()->addDamage( geometry());
|
workspace()->addDamage( this, geometry());
|
||||||
|
|
||||||
ungrabXServer();
|
ungrabXServer();
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,14 @@ void Scene::windowDeleted( Toplevel* )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scene::transformWindowDamage( Toplevel*, XserverRegion ) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::updateTransformation( Toplevel* )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Scene* scene;
|
Scene* scene;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
2
scene.h
2
scene.h
|
@ -28,6 +28,8 @@ class Scene
|
||||||
virtual void windowGeometryShapeChanged( Toplevel* );
|
virtual void windowGeometryShapeChanged( Toplevel* );
|
||||||
virtual void windowOpacityChanged( Toplevel* );
|
virtual void windowOpacityChanged( Toplevel* );
|
||||||
virtual void windowDeleted( Toplevel* );
|
virtual void windowDeleted( Toplevel* );
|
||||||
|
virtual void transformWindowDamage( Toplevel*, XserverRegion ) const;
|
||||||
|
virtual void updateTransformation( Toplevel* );
|
||||||
protected:
|
protected:
|
||||||
Workspace* wspace;
|
Workspace* wspace;
|
||||||
ToplevelList windows;
|
ToplevelList windows;
|
||||||
|
|
|
@ -64,19 +64,26 @@ void SceneXrender::paint( XserverRegion damage )
|
||||||
{
|
{
|
||||||
Toplevel* c = windows[ i ];
|
Toplevel* c = windows[ i ];
|
||||||
checkWindowData( c );
|
checkWindowData( c );
|
||||||
effects->paintWindow( c, window_data[ c ].effect );
|
WindowData& data = window_data[ c ];
|
||||||
|
effects->transformWindow( c, data.effect ); // TODO remove, instead add initWindow() to effects
|
||||||
if( isOpaque( c ))
|
if( isOpaque( c ))
|
||||||
{
|
{
|
||||||
Picture picture = windowPicture( c );
|
Picture picture = windowPicture( c );
|
||||||
Picture shape = windowShape( c );
|
XserverRegion shape = windowShape( c );
|
||||||
if( picture != None && shape != None )
|
if( picture != None && shape != None )
|
||||||
{
|
{
|
||||||
// Set the clip region for the buffer to the damage region, and
|
// Set the clip region for the buffer to the damage region, and
|
||||||
// subtract the clients shape from the damage region
|
// subtract the clients shape from the damage region
|
||||||
XFixesSetPictureClipRegion( display(), buffer, 0, 0, damage );
|
XFixesSetPictureClipRegion( display(), buffer, 0, 0, damage );
|
||||||
|
const Matrix& matrix = data.effect.matrix;
|
||||||
|
if( !matrix.isIdentity())
|
||||||
|
{
|
||||||
|
assert( matrix.isOnlyTranslate());
|
||||||
|
XFixesTranslateRegion( display(), shape, int( matrix.xTranslate()), int( matrix.yTranslate()));
|
||||||
|
}
|
||||||
XFixesSubtractRegion( display(), damage, damage, shape );
|
XFixesSubtractRegion( display(), damage, damage, shape );
|
||||||
XRenderComposite( display(), PictOpSrc, picture, None, buffer, 0, 0, 0, 0,
|
XRenderComposite( display(), PictOpSrc, picture, None, buffer, 0, 0, 0, 0,
|
||||||
c->x(), c->y(), c->width(), c->height());
|
c->x() + int( matrix.xTranslate()), c->y() + int( matrix.yTranslate()), c->width(), c->height());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
saveWindowClipRegion( c, damage );
|
saveWindowClipRegion( c, damage );
|
||||||
|
@ -102,9 +109,10 @@ void SceneXrender::paint( XserverRegion damage )
|
||||||
Picture alpha = windowAlphaMask( c );
|
Picture alpha = windowAlphaMask( c );
|
||||||
if( picture != None )
|
if( picture != None )
|
||||||
{
|
{
|
||||||
|
const Matrix& matrix = window_data[ c ].effect.matrix;
|
||||||
// TODO clip also using shape? also above?
|
// TODO clip also using shape? also above?
|
||||||
XRenderComposite( display(), PictOpOver, picture, alpha, buffer, 0, 0, 0, 0,
|
XRenderComposite( display(), PictOpOver, picture, alpha, buffer, 0, 0, 0, 0,
|
||||||
c->x(), c->y(), c->width(), c->height());
|
c->x() + int( matrix.xTranslate()), c->y() + int( matrix.yTranslate()), c->width(), c->height());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFixesDestroyRegion( display(), r );
|
XFixesDestroyRegion( display(), r );
|
||||||
|
@ -115,6 +123,27 @@ void SceneXrender::paint( XserverRegion damage )
|
||||||
XFlush( display());
|
XFlush( display());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneXrender::transformWindowDamage( Toplevel* c, XserverRegion r ) const
|
||||||
|
{
|
||||||
|
if( !window_data.contains( c ))
|
||||||
|
return;
|
||||||
|
const Matrix& matrix = window_data[ c ].effect.matrix;
|
||||||
|
if( matrix.isIdentity())
|
||||||
|
return;
|
||||||
|
assert( matrix.isOnlyTranslate());
|
||||||
|
// TODO the matrix here is not valid after it changes but before it's first painted
|
||||||
|
// (i.e. a changes to state where it should be translated but the matrix is not yet updated)
|
||||||
|
XFixesTranslateRegion( display(), r, int( matrix.xTranslate()), int( matrix.yTranslate()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneXrender::updateTransformation( Toplevel* c )
|
||||||
|
{
|
||||||
|
// TODO maybe only mark as invalid and update on-demand
|
||||||
|
checkWindowData( c );
|
||||||
|
WindowData& data = window_data[ c ];
|
||||||
|
effects->transformWindow( c, data.effect );
|
||||||
|
}
|
||||||
|
|
||||||
void SceneXrender::checkWindowData( Toplevel* c )
|
void SceneXrender::checkWindowData( Toplevel* c )
|
||||||
{
|
{
|
||||||
if( !window_data.contains( c ))
|
if( !window_data.contains( c ))
|
||||||
|
@ -139,7 +168,7 @@ void SceneXrender::windowGeometryShapeChanged( Toplevel* c )
|
||||||
XRenderFreePicture( display(), data.alpha );
|
XRenderFreePicture( display(), data.alpha );
|
||||||
data.alpha = None;
|
data.alpha = None;
|
||||||
if( data.shape != None )
|
if( data.shape != None )
|
||||||
XRenderFreePicture( display(), data.shape );
|
XFixesDestroyRegion( display(), data.shape );
|
||||||
data.shape = None;
|
data.shape = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,8 +249,9 @@ Picture SceneXrender::windowAlphaMask( Toplevel* c )
|
||||||
return data.alpha;
|
return data.alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
Picture SceneXrender::windowShape( Toplevel* c )
|
XserverRegion SceneXrender::windowShape( Toplevel* c )
|
||||||
{
|
{
|
||||||
|
#if 0 // it probably doesn't make sense to cache this, and perhaps some others - they aren't roundtrips
|
||||||
WindowData& data = window_data[ c ];
|
WindowData& data = window_data[ c ];
|
||||||
if( data.shape == None )
|
if( data.shape == None )
|
||||||
{
|
{
|
||||||
|
@ -229,6 +259,11 @@ Picture SceneXrender::windowShape( Toplevel* c )
|
||||||
XFixesTranslateRegion( display(), data.shape, c->x(), c->y());
|
XFixesTranslateRegion( display(), data.shape, c->x(), c->y());
|
||||||
}
|
}
|
||||||
return data.shape;
|
return data.shape;
|
||||||
|
#else
|
||||||
|
XserverRegion shape = XFixesCreateRegionFromWindow( display(), c->handle(), WindowRegionBounding );
|
||||||
|
XFixesTranslateRegion( display(), shape, c->x(), c->y());
|
||||||
|
return shape;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO handle xrandr changes
|
// TODO handle xrandr changes
|
||||||
|
@ -242,6 +277,36 @@ void SceneXrender::createBuffer()
|
||||||
XFreePixmap( display(), pixmap ); // The picture owns the pixmap now
|
XFreePixmap( display(), pixmap ); // The picture owns the pixmap now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneXrender::setPictureMatrix( Picture pic, const Matrix& m )
|
||||||
|
{
|
||||||
|
if( pic == None )
|
||||||
|
return;
|
||||||
|
XTransform t;
|
||||||
|
// ignore z axis
|
||||||
|
t.matrix[ 0 ][ 0 ] = XDoubleToFixed( m.m[ 0 ][ 0 ] );
|
||||||
|
t.matrix[ 0 ][ 1 ] = XDoubleToFixed( m.m[ 0 ][ 1 ] );
|
||||||
|
t.matrix[ 0 ][ 2 ] = -XDoubleToFixed( m.m[ 0 ][ 3 ] ); // translation seems to be inverted
|
||||||
|
t.matrix[ 1 ][ 0 ] = XDoubleToFixed( m.m[ 1 ][ 0 ] );
|
||||||
|
t.matrix[ 1 ][ 1 ] = XDoubleToFixed( m.m[ 1 ][ 1 ] );
|
||||||
|
t.matrix[ 1 ][ 2 ] = -XDoubleToFixed( m.m[ 1 ][ 3 ] );
|
||||||
|
t.matrix[ 2 ][ 0 ] = XDoubleToFixed( m.m[ 3 ][ 0 ] );
|
||||||
|
t.matrix[ 2 ][ 1 ] = XDoubleToFixed( m.m[ 3 ][ 1 ] );
|
||||||
|
t.matrix[ 2 ][ 2 ] = XDoubleToFixed( m.m[ 3 ][ 3 ] );
|
||||||
|
XRenderSetPictureTransform( display(), pic, &t );
|
||||||
|
if( t.matrix[ 0 ][ 0 ] != XDoubleToFixed( 1 ) // fast filter for identity or translation
|
||||||
|
|| t.matrix[ 1 ][ 1 ] != XDoubleToFixed( 1 )
|
||||||
|
|| t.matrix[ 2 ][ 2 ] != XDoubleToFixed( 1 )
|
||||||
|
|| t.matrix[ 0 ][ 1 ] != XDoubleToFixed( 0 )
|
||||||
|
|| t.matrix[ 1 ][ 0 ] != XDoubleToFixed( 0 ))
|
||||||
|
{
|
||||||
|
XRenderSetPictureFilter( display(), pic, const_cast< char* >( FilterGood ), 0, 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XRenderSetPictureFilter( display(), pic, const_cast< char* >( FilterFast ), 0, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SceneXrender::WindowData::WindowData()
|
SceneXrender::WindowData::WindowData()
|
||||||
: picture( None )
|
: picture( None )
|
||||||
, format( NULL )
|
, format( NULL )
|
||||||
|
|
|
@ -34,6 +34,8 @@ class SceneXrender
|
||||||
virtual void windowGeometryShapeChanged( Toplevel* );
|
virtual void windowGeometryShapeChanged( Toplevel* );
|
||||||
virtual void windowOpacityChanged( Toplevel* );
|
virtual void windowOpacityChanged( Toplevel* );
|
||||||
virtual void windowDeleted( Toplevel* );
|
virtual void windowDeleted( Toplevel* );
|
||||||
|
virtual void transformWindowDamage( Toplevel*, XserverRegion ) const;
|
||||||
|
virtual void updateTransformation( Toplevel* );
|
||||||
private:
|
private:
|
||||||
void createBuffer();
|
void createBuffer();
|
||||||
void checkWindowData( Toplevel* c );
|
void checkWindowData( Toplevel* c );
|
||||||
|
@ -42,7 +44,8 @@ class SceneXrender
|
||||||
XserverRegion savedWindowClipRegion( Toplevel* c );
|
XserverRegion savedWindowClipRegion( Toplevel* c );
|
||||||
bool isOpaque( Toplevel* c ) const;
|
bool isOpaque( Toplevel* c ) const;
|
||||||
Picture windowAlphaMask( Toplevel* c );
|
Picture windowAlphaMask( Toplevel* c );
|
||||||
Picture windowShape( Toplevel* c );
|
XserverRegion windowShape( Toplevel* c );
|
||||||
|
static void setPictureMatrix( Picture pic, const Matrix& m );
|
||||||
XRenderPictFormat* format;
|
XRenderPictFormat* format;
|
||||||
Picture front;
|
Picture front;
|
||||||
Picture buffer;
|
Picture buffer;
|
||||||
|
|
59
toplevel.h
59
toplevel.h
|
@ -39,6 +39,20 @@ class Toplevel
|
||||||
int y() const;
|
int y() const;
|
||||||
int width() const;
|
int width() const;
|
||||||
int height() const;
|
int height() const;
|
||||||
|
|
||||||
|
// prefer isXXX() instead
|
||||||
|
virtual NET::WindowType windowType( bool direct = false, int supported_types = SUPPORTED_WINDOW_TYPES_MASK ) const = 0;
|
||||||
|
bool hasNETSupport() const;
|
||||||
|
bool isDesktop() const;
|
||||||
|
bool isDock() const;
|
||||||
|
bool isToolbar() const;
|
||||||
|
bool isTopMenu() const;
|
||||||
|
bool isMenu() const;
|
||||||
|
bool isNormalWindow() const; // normal as in 'NET::Normal or NET::Unknown non-transient'
|
||||||
|
bool isDialog() const;
|
||||||
|
bool isSplash() const;
|
||||||
|
bool isUtility() const;
|
||||||
|
|
||||||
Pixmap windowPixmap() const;
|
Pixmap windowPixmap() const;
|
||||||
Visual* visual() const;
|
Visual* visual() const;
|
||||||
virtual double opacity() const = 0;
|
virtual double opacity() const = 0;
|
||||||
|
@ -120,6 +134,51 @@ inline Visual* Toplevel::visual() const
|
||||||
return vis;
|
return vis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool Toplevel::isDesktop() const
|
||||||
|
{
|
||||||
|
return windowType() == NET::Desktop;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Toplevel::isDock() const
|
||||||
|
{
|
||||||
|
return windowType() == NET::Dock;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Toplevel::isTopMenu() const
|
||||||
|
{
|
||||||
|
return windowType() == NET::TopMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Toplevel::isMenu() const
|
||||||
|
{
|
||||||
|
return windowType() == NET::Menu && !isTopMenu(); // because of backwards comp.
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Toplevel::isToolbar() const
|
||||||
|
{
|
||||||
|
return windowType() == NET::Toolbar;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Toplevel::isSplash() const
|
||||||
|
{
|
||||||
|
return windowType() == NET::Splash;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Toplevel::isUtility() const
|
||||||
|
{
|
||||||
|
return windowType() == NET::Utility;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Toplevel::isDialog() const
|
||||||
|
{
|
||||||
|
return windowType() == NET::Dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Toplevel::isNormalWindow() const
|
||||||
|
{
|
||||||
|
return windowType() == NET::Normal;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
inline
|
inline
|
||||||
kndbgstream& operator<<( kndbgstream& stream, const Toplevel* ) { return stream; }
|
kndbgstream& operator<<( kndbgstream& stream, const Toplevel* ) { return stream; }
|
||||||
|
|
|
@ -47,7 +47,7 @@ bool Unmanaged::track( Window w )
|
||||||
|
|
||||||
setupCompositing();
|
setupCompositing();
|
||||||
resetWindowPixmap();
|
resetWindowPixmap();
|
||||||
workspace()->addDamage( geometry());
|
workspace()->addDamage( this, geometry());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,11 @@ void Unmanaged::deleteUnmanaged( Unmanaged* c, allowed_t )
|
||||||
delete c;
|
delete c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NET::WindowType Unmanaged::windowType( bool, int supported_types ) const
|
||||||
|
{
|
||||||
|
return info->windowType( supported_types );
|
||||||
|
}
|
||||||
|
|
||||||
double Unmanaged::opacity() const
|
double Unmanaged::opacity() const
|
||||||
{
|
{
|
||||||
if( info->opacity() == 0xffffffff )
|
if( info->opacity() == 0xffffffff )
|
||||||
|
|
|
@ -28,6 +28,7 @@ class Unmanaged
|
||||||
bool windowEvent( XEvent* e );
|
bool windowEvent( XEvent* e );
|
||||||
void release();
|
void release();
|
||||||
bool track( Window w );
|
bool track( Window w );
|
||||||
|
virtual NET::WindowType windowType( bool direct = false, int supported_types = SUPPORTED_WINDOW_TYPES_MASK ) const;
|
||||||
static void deleteUnmanaged( Unmanaged* c, allowed_t );
|
static void deleteUnmanaged( Unmanaged* c, allowed_t );
|
||||||
virtual double opacity() const;
|
virtual double opacity() const;
|
||||||
protected:
|
protected:
|
||||||
|
|
16
utils.cpp
16
utils.cpp
|
@ -315,6 +315,20 @@ bool grabbedXServer()
|
||||||
return server_grab_count > 0;
|
return server_grab_count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kdbgstream& operator<<( kdbgstream& stream, RegionDebug r )
|
||||||
|
{
|
||||||
|
if( r.rr == None )
|
||||||
|
return stream << "EMPTY";
|
||||||
|
int num;
|
||||||
|
XRectangle* rects = XFixesFetchRegion( display(), r.rr, &num );
|
||||||
|
if( rects == NULL || num == 0 )
|
||||||
|
return stream << "EMPTY";
|
||||||
|
for( int i = 0;
|
||||||
|
i < num;
|
||||||
|
++i )
|
||||||
|
stream << "[" << rects[ i ].x << "+" << rects[ i ].y << " " << rects[ i ].width << "x" << rects[ i ].height << "]";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool isLocalMachine( const QByteArray& host )
|
bool isLocalMachine( const QByteArray& host )
|
||||||
|
@ -381,8 +395,6 @@ void ShortcutDialog::accept()
|
||||||
KShortcutDialog::accept();
|
KShortcutDialog::accept();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#ifndef KCMRULES
|
#ifndef KCMRULES
|
||||||
|
|
14
utils.h
14
utils.h
|
@ -120,6 +120,20 @@ enum allowed_t { Allowed };
|
||||||
// some enums to have more readable code, instead of using bools
|
// some enums to have more readable code, instead of using bools
|
||||||
enum ForceGeometry_t { NormalGeometrySet, ForceGeometrySet };
|
enum ForceGeometry_t { NormalGeometrySet, ForceGeometrySet };
|
||||||
|
|
||||||
|
|
||||||
|
struct RegionDebug
|
||||||
|
{
|
||||||
|
RegionDebug( XserverRegion r ) : rr( r ) {}
|
||||||
|
XserverRegion rr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
inline
|
||||||
|
kndbgstream& operator<<( kndbgstream& stream, RegionDebug ) { return stream; }
|
||||||
|
#else
|
||||||
|
kdbgstream& operator<<( kdbgstream& stream, RegionDebug r );
|
||||||
|
#endif
|
||||||
|
|
||||||
// Areas, mostly related to Xinerama
|
// Areas, mostly related to Xinerama
|
||||||
enum clientAreaOption
|
enum clientAreaOption
|
||||||
{
|
{
|
||||||
|
|
|
@ -286,6 +286,9 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
void addDamage( const QRect& r );
|
void addDamage( const QRect& r );
|
||||||
void addDamage( int x, int y, int w, int h );
|
void addDamage( int x, int y, int w, int h );
|
||||||
void addDamage( XserverRegion r, bool destroy );
|
void addDamage( XserverRegion r, bool destroy );
|
||||||
|
void addDamage( Toplevel* c, const QRect& r );
|
||||||
|
void addDamage( Toplevel* c, int x, int y, int w, int h );
|
||||||
|
void addDamage( Toplevel* c, XserverRegion r, bool destroy );
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void refresh();
|
void refresh();
|
||||||
|
|
Loading…
Reference in a new issue