Shadows. Right not it's only flat black rectangle, but otherwise
everything should work. svn path=/branches/work/kwin_composite/; revision=646315
This commit is contained in:
parent
9da3b593ad
commit
8b5b40e4e8
47 changed files with 379 additions and 119 deletions
|
@ -78,6 +78,7 @@ set(kwin_KDEINIT_SRCS
|
|||
effects/fallapart.cpp
|
||||
effects/drunken.cpp
|
||||
effects/flame.cpp
|
||||
effects/shadow.cpp
|
||||
effects/test_input.cpp
|
||||
effects/test_thumbnail.cpp
|
||||
)
|
||||
|
|
|
@ -137,6 +137,9 @@ XRender TODO
|
|||
+ SceneXrender::Window::performPaint() doesn't use saturation
|
||||
+ SceneXrender::Window::performPaint() doesn't use brightness
|
||||
|
||||
+ SceneXrender::paintTransformedScreen() doesn't handle properly extending of painted area
|
||||
in window's pre-paint - see the transformedShape() comment
|
||||
|
||||
|
||||
Effects framework TODO
|
||||
==============================
|
||||
|
@ -146,7 +149,9 @@ Effects framework TODO
|
|||
! - window state changes
|
||||
? more
|
||||
|
||||
* shadows
|
||||
/ shadows
|
||||
+ - right now is only a rectangle, probably needs some shape support
|
||||
+ - right now is only a flat black color, probably should be improved
|
||||
|
||||
/ support for grabbing input
|
||||
- during some more complicated effects, input (at least mouse) should be disabled,
|
||||
|
@ -178,7 +183,7 @@ Effects TODO
|
|||
? - I don't think these effects should be plugins or anything like that,
|
||||
probably simply write to kwinrc and use the Option class in KWin
|
||||
|
||||
+ implements all effects Kompmgr could do
|
||||
/ implements all effects Kompmgr could do
|
||||
+ - all effects from the Opacity tab should be already doable
|
||||
! - applying translucency only to the decoration
|
||||
- use clientSize() and clientPos() from Client
|
||||
|
@ -187,15 +192,12 @@ Effects TODO
|
|||
- just clear the alpha channel in the alpha clear hack
|
||||
- or do it while painting (see also the alpha clear hack todo entry)
|
||||
! - the rest - should be simple
|
||||
* - shadows
|
||||
- framework is not ready for them yet (see the todo entry)
|
||||
/ - shadows
|
||||
+ - tab Effects
|
||||
! - fade-in should be simple
|
||||
+ - fade between changes
|
||||
- will need notification about opacity changes
|
||||
- not sure if this is doable for other opacity changes then the ones
|
||||
initiated by the user or by the application
|
||||
* - fade-out needs framework for disappearing windows (see the todo entry)
|
||||
|
||||
+ minimize/shade effects
|
||||
- to replace the ones from KWin core
|
||||
|
|
|
@ -191,7 +191,7 @@ void Client::releaseWindow( bool on_shutdown )
|
|||
finishWindowRules();
|
||||
++block_geometry_updates;
|
||||
if( isOnCurrentDesktop() && isShown( true ))
|
||||
workspace()->addRepaint( geometry());
|
||||
addWorkspaceRepaint( geometry());
|
||||
setMappingState( WithdrawnState );
|
||||
setModal( false ); // otherwise its mainwindow wouldn't get focus
|
||||
hidden = true; // so that it's not considered visible anymore (can't use hideClient(), it would set flags)
|
||||
|
@ -257,7 +257,7 @@ void Client::destroyClient()
|
|||
finishWindowRules();
|
||||
++block_geometry_updates;
|
||||
if( isOnCurrentDesktop() && isShown( true ))
|
||||
workspace()->addRepaint( geometry());
|
||||
addWorkspaceRepaint( geometry());
|
||||
setModal( false );
|
||||
hidden = true; // so that it's not considered visible anymore
|
||||
workspace()->clientHidden( this );
|
||||
|
@ -655,7 +655,7 @@ void Client::setShade( ShadeMode mode )
|
|||
// TODO all this unmapping, resizing etc. feels too much duplicated from elsewhere
|
||||
if ( isShade())
|
||||
{ // shade_mode == ShadeNormal
|
||||
workspace()->addRepaint( geometry());
|
||||
addWorkspaceRepaint( geometry());
|
||||
// shade
|
||||
shade_geometry_change = true;
|
||||
QSize s( sizeForClientSize( QSize( clientSize())));
|
||||
|
@ -826,7 +826,7 @@ void Client::rawShow()
|
|||
*/
|
||||
void Client::rawHide()
|
||||
{
|
||||
workspace()->addRepaint( geometry());
|
||||
addWorkspaceRepaint( geometry());
|
||||
// Here it may look like a race condition, as some other client might try to unmap
|
||||
// the window between these two XSelectInput() calls. However, they're supposed to
|
||||
// use XWithdrawWindow(), which also sends a synthetic event to the root window,
|
||||
|
|
|
@ -246,8 +246,10 @@ void Workspace::performCompositing()
|
|||
if( children != NULL )
|
||||
XFree( children );
|
||||
foreach( Toplevel* c, windows )
|
||||
{ // this could be possibly optimized WRT obscuring, but that'd need being already
|
||||
// past prePaint() phase - probably not worth it
|
||||
{ // This could be possibly optimized WRT obscuring, but that'd need being already
|
||||
// past prePaint() phase - probably not worth it.
|
||||
// TODO I think effects->transformWindowDamage() doesn't need to be called here,
|
||||
// pre-paint will extend painted window areas as necessary.
|
||||
repaints_region |= c->repaints().translated( c->pos());
|
||||
c->resetRepaints( c->rect());
|
||||
}
|
||||
|
@ -470,4 +472,17 @@ void Toplevel::resetRepaints( const QRect& r )
|
|||
repaints_region -= r;
|
||||
}
|
||||
|
||||
void Toplevel::addWorkspaceRepaint( int x, int y, int w, int h )
|
||||
{
|
||||
addWorkspaceRepaint( QRect( x, y, w, h ));
|
||||
}
|
||||
|
||||
void Toplevel::addWorkspaceRepaint( const QRect& r2 )
|
||||
{
|
||||
if( !compositing())
|
||||
return;
|
||||
QRect r = effects->transformWindowDamage( effectWindow(), r2 );
|
||||
workspace()->addRepaint( r );
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
31
effects.cpp
31
effects.cpp
|
@ -26,6 +26,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include "effects/minimizeanimation.h"
|
||||
#include "effects/presentwindows.h"
|
||||
#include "effects/scalein.h"
|
||||
#include "effects/shadow.h"
|
||||
#include "effects/shakymove.h"
|
||||
#include "effects/shiftworkspaceup.h"
|
||||
#include "effects/showfps.h"
|
||||
|
@ -128,9 +129,9 @@ void Effect::postPaintScreen()
|
|||
effects->postPaintScreen();
|
||||
}
|
||||
|
||||
void Effect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void Effect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void Effect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
|
@ -148,6 +149,11 @@ void Effect::drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintD
|
|||
effects->drawWindow( w, mask, region, data );
|
||||
}
|
||||
|
||||
QRect Effect::transformWindowDamage( EffectWindow* w, const QRect& r )
|
||||
{
|
||||
return effects->transformWindowDamage( w, r );
|
||||
}
|
||||
|
||||
void Effect::setPositionTransformations( WindowPaintData& data, QRect& region, EffectWindow* w,
|
||||
const QRect& r, Qt::AspectRatioMode aspect )
|
||||
{
|
||||
|
@ -172,6 +178,7 @@ EffectsHandler::EffectsHandler()
|
|||
: current_paint_screen( 0 )
|
||||
, current_paint_window( 0 )
|
||||
, current_draw_window( 0 )
|
||||
, current_transform( 0 )
|
||||
{
|
||||
if( !compositing())
|
||||
return;
|
||||
|
@ -200,6 +207,7 @@ EffectsHandler::EffectsHandler()
|
|||
registerEffect("DesktopChangeSlide", new GenericEffectFactory<DesktopChangeSlideEffect>);
|
||||
registerEffect("BoxSwitch", new GenericEffectFactory<BoxSwitchEffect>);
|
||||
registerEffect("Drunken", new GenericEffectFactory<DrunkenEffect>);
|
||||
registerEffect("Shadow", new GenericEffectFactory<ShadowEffect>);
|
||||
|
||||
registerEffect("TestInput", new GenericEffectFactory<TestInputEffect>);
|
||||
registerEffect("TestThumbnail", new GenericEffectFactory<TestThumbnailEffect>);
|
||||
|
@ -319,6 +327,7 @@ void EffectsHandler::startPaint()
|
|||
assert( current_paint_screen == 0 );
|
||||
assert( current_paint_window == 0 );
|
||||
assert( current_draw_window == 0 );
|
||||
assert( current_transform == 0 );
|
||||
}
|
||||
|
||||
// the idea is that effects call this function again which calls the next one
|
||||
|
@ -353,11 +362,11 @@ void EffectsHandler::postPaintScreen()
|
|||
// no special final code
|
||||
}
|
||||
|
||||
void EffectsHandler::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void EffectsHandler::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
if( current_paint_window < loaded_effects.size())
|
||||
{
|
||||
loaded_effects[current_paint_window++].second->prePaintWindow( w, mask, region, time );
|
||||
loaded_effects[current_paint_window++].second->prePaintWindow( w, mask, paint, clip, time );
|
||||
--current_paint_window;
|
||||
}
|
||||
// no special final code
|
||||
|
@ -395,6 +404,18 @@ void EffectsHandler::drawWindow( EffectWindow* w, int mask, QRegion region, Wind
|
|||
scene->finalDrawWindow( w, mask, region, data );
|
||||
}
|
||||
|
||||
QRect EffectsHandler::transformWindowDamage( EffectWindow* w, const QRect& r )
|
||||
{
|
||||
if( current_transform < loaded_effects.size())
|
||||
{
|
||||
QRect rr = loaded_effects[current_transform++].second->transformWindowDamage( w, r );
|
||||
--current_transform;
|
||||
return rr;
|
||||
}
|
||||
else
|
||||
return r;
|
||||
}
|
||||
|
||||
Window EffectsHandler::createInputWindow( Effect* e, int x, int y, int w, int h, const QCursor& cursor )
|
||||
{
|
||||
XSetWindowAttributes attrs;
|
||||
|
@ -502,6 +523,7 @@ void EffectsHandler::loadEffect( const QString& name )
|
|||
assert( current_paint_screen == 0 );
|
||||
assert( current_paint_window == 0 );
|
||||
assert( current_draw_window == 0 );
|
||||
assert( current_transform == 0 );
|
||||
|
||||
for(QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); it++)
|
||||
{
|
||||
|
@ -529,6 +551,7 @@ void EffectsHandler::unloadEffect( const QString& name )
|
|||
assert( current_paint_screen == 0 );
|
||||
assert( current_paint_window == 0 );
|
||||
assert( current_draw_window == 0 );
|
||||
assert( current_transform == 0 );
|
||||
|
||||
for( QVector< EffectPair >::iterator it = loaded_effects.begin(); it != loaded_effects.end(); it++)
|
||||
{
|
||||
|
|
11
effects.h
11
effects.h
|
@ -68,13 +68,18 @@ class Effect
|
|||
virtual void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data );
|
||||
virtual void postPaintScreen();
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
// paintWindow() can do various transformations
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintWindow( EffectWindow* w );
|
||||
// drawWindow() is used even for thumbnails etc. - it can alter the window itself where it
|
||||
// makes sense (e.g.darkening out unresponsive windows), but it cannot do transformations
|
||||
virtual void drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
// 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
|
||||
// to be repainted at that area, shadow's transformWindowDamage() adds the shadow area
|
||||
// to it, so that it is repainted as well.
|
||||
virtual QRect transformWindowDamage( EffectWindow* w, const QRect& r );
|
||||
// called when moved/resized or once after it's finished
|
||||
virtual void windowUserMovedResized( EffectWindow* c, bool first, bool last );
|
||||
virtual void windowOpacityChanged( EffectWindow* c, double old_opacity );
|
||||
|
@ -135,10 +140,11 @@ class EffectsHandler
|
|||
void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
void paintScreen( int mask, QRegion region, ScreenPaintData& data );
|
||||
void postPaintScreen();
|
||||
void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
void postPaintWindow( EffectWindow* w );
|
||||
void drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
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.
|
||||
// The effect's windowInputMouseEvent() will get called with such events.
|
||||
|
@ -181,6 +187,7 @@ class EffectsHandler
|
|||
int current_paint_screen;
|
||||
int current_paint_window;
|
||||
int current_draw_window;
|
||||
int current_transform;
|
||||
};
|
||||
|
||||
// This class is a representation of a window used by/for Effect classes.
|
||||
|
|
|
@ -44,7 +44,7 @@ void BoxSwitchEffect::prePaintScreen( int* mask, QRegion* region, int time )
|
|||
effects->prePaintScreen( mask, region, time );
|
||||
}
|
||||
|
||||
void BoxSwitchEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void BoxSwitchEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
if( mActivated )
|
||||
{
|
||||
|
@ -67,7 +67,7 @@ void BoxSwitchEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* regio
|
|||
}
|
||||
}
|
||||
}
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void BoxSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
||||
|
|
|
@ -33,7 +33,7 @@ class BoxSwitchEffect
|
|||
|
||||
virtual void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
|
||||
virtual void windowInputMouseEvent( Window w, QEvent* e );
|
||||
|
|
|
@ -33,7 +33,7 @@ void DesktopChangeSlideEffect::prePaintScreen( int* mask, QRegion* region, int t
|
|||
effects->prePaintScreen( mask, region, time );
|
||||
}
|
||||
|
||||
void DesktopChangeSlideEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void DesktopChangeSlideEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
if( progress != MAX_PROGRESS )
|
||||
{
|
||||
|
@ -50,7 +50,7 @@ void DesktopChangeSlideEffect::prePaintWindow( EffectWindow* w, int* mask, QRegi
|
|||
*mask |= Scene::PAINT_WINDOW_TRANSFORMED;
|
||||
}
|
||||
}
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void DesktopChangeSlideEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
||||
|
|
|
@ -24,7 +24,7 @@ class DesktopChangeSlideEffect
|
|||
virtual void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data );
|
||||
virtual void postPaintScreen();
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void desktopChanged( int old );
|
||||
private:
|
||||
|
|
|
@ -19,7 +19,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
namespace KWinInternal
|
||||
{
|
||||
|
||||
void DialogParentEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void DialogParentEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
// How long does it take for the effect to get it's full strength (in ms)
|
||||
const float changeTime = 200;
|
||||
|
@ -38,7 +38,7 @@ void DialogParentEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* re
|
|||
}
|
||||
|
||||
// Call the next effect
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void DialogParentEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
|
|
|
@ -28,7 +28,7 @@ class DialogParentEffect
|
|||
: public Effect
|
||||
{
|
||||
public:
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintWindow( EffectWindow* w );
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ void DrunkenEffect::prePaintScreen( int* mask, QRegion* region, int time )
|
|||
effects->prePaintScreen( mask, region, time );
|
||||
}
|
||||
|
||||
void DrunkenEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void DrunkenEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
if( windows.contains( w ))
|
||||
{
|
||||
|
@ -32,7 +32,7 @@ void DrunkenEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region,
|
|||
else
|
||||
windows.remove( w );
|
||||
}
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void DrunkenEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
|
|
|
@ -21,7 +21,7 @@ class DrunkenEffect
|
|||
{
|
||||
public:
|
||||
virtual void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintWindow( EffectWindow* w );
|
||||
virtual void windowAdded( EffectWindow* w );
|
||||
|
|
|
@ -93,7 +93,7 @@ void ExplosionEffect::prePaintScreen( int* mask, QRegion* region, int time )
|
|||
effects->prePaintScreen(mask, region, time);
|
||||
}
|
||||
|
||||
void ExplosionEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void ExplosionEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
if( mWindows.contains( w ))
|
||||
{
|
||||
|
@ -112,7 +112,7 @@ void ExplosionEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* regio
|
|||
}
|
||||
}
|
||||
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void ExplosionEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
|
|
|
@ -30,7 +30,7 @@ class ExplosionEffect
|
|||
ExplosionEffect();
|
||||
|
||||
virtual void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintScreen();
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ FadeEffect::FadeEffect()
|
|||
{
|
||||
}
|
||||
|
||||
void FadeEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void FadeEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
if( windows.contains( w ))
|
||||
{
|
||||
|
@ -55,7 +55,7 @@ void FadeEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, in
|
|||
w->enablePainting( Scene::Window::PAINT_DISABLED_BY_DELETE );
|
||||
}
|
||||
}
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void FadeEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
|
|
|
@ -21,7 +21,7 @@ class FadeEffect
|
|||
{
|
||||
public:
|
||||
FadeEffect();
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintWindow( EffectWindow* w );
|
||||
// TODO react also on virtual desktop changes
|
||||
|
|
|
@ -25,7 +25,7 @@ void FallApartEffect::prePaintScreen( int* mask, QRegion* region, int time )
|
|||
effects->prePaintScreen(mask, region, time);
|
||||
}
|
||||
|
||||
void FallApartEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void FallApartEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
if( windows.contains( w ))
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ void FallApartEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* regio
|
|||
}
|
||||
}
|
||||
}
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void FallApartEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
|
|
|
@ -21,7 +21,7 @@ class FallApartEffect
|
|||
{
|
||||
public:
|
||||
virtual void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintScreen();
|
||||
virtual void windowClosed( EffectWindow* c );
|
||||
|
|
|
@ -23,7 +23,7 @@ void FlameEffect::prePaintScreen( int* mask, QRegion* region, int time )
|
|||
effects->prePaintScreen(mask, region, time);
|
||||
}
|
||||
|
||||
void FlameEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void FlameEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
if( windows.contains( w ))
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ void FlameEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, i
|
|||
}
|
||||
}
|
||||
}
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void FlameEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
|
|
|
@ -21,7 +21,7 @@ class FlameEffect
|
|||
{
|
||||
public:
|
||||
virtual void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintWindow( EffectWindow* w );
|
||||
virtual void windowClosed( EffectWindow* c );
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace KWinInternal
|
|||
// region - the region of the screen that needs to be painted, support for modifying it
|
||||
// is not fully implemented yet, do not use
|
||||
// time - time in milliseconds since the last paint, useful for animations
|
||||
void HowtoEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void HowtoEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
// Is this window the one that is going to be faded out and in again?
|
||||
if( w == fade_window )
|
||||
|
@ -63,7 +63,7 @@ void HowtoEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, i
|
|||
}
|
||||
// Call the next effect (or the actual window painting code if this is the last effect).
|
||||
// Effects are chained and they all modify something if needed and then call the next one.
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
// The function that handles the actual painting. Some simple modifications are possible
|
||||
|
|
|
@ -38,7 +38,7 @@ class HowtoEffect
|
|||
|
||||
// A pre-paint function. It tells the compositing code how the painting will
|
||||
// be affected by this effect.
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
|
||||
// A paint function. It actually performs the modifications to the painting.
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
|
|
|
@ -15,7 +15,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
namespace KWinInternal
|
||||
{
|
||||
|
||||
void MakeTransparentEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void MakeTransparentEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
const Client* c = dynamic_cast< const Client* >( w->window());
|
||||
if(( c != NULL && ( c->isMove() || c->isResize())) || w->window()->isDialog())
|
||||
|
@ -23,7 +23,7 @@ void MakeTransparentEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion*
|
|||
*mask |= Scene::PAINT_WINDOW_TRANSLUCENT;
|
||||
*mask &= ~Scene::PAINT_WINDOW_OPAQUE;
|
||||
}
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void MakeTransparentEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
|
|
|
@ -21,7 +21,7 @@ class MakeTransparentEffect
|
|||
{
|
||||
public:
|
||||
virtual void windowUserMovedResized( EffectWindow* c, bool first, bool last );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
};
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ void MinimizeAnimationEffect::prePaintScreen( int* mask, QRegion* region, int ti
|
|||
effects->prePaintScreen(mask, region, time);
|
||||
}
|
||||
|
||||
void MinimizeAnimationEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void MinimizeAnimationEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
const float changeTime = 500;
|
||||
if( mAnimationProgress.contains( w ))
|
||||
|
@ -69,7 +69,7 @@ void MinimizeAnimationEffect::prePaintWindow( EffectWindow* w, int* mask, QRegio
|
|||
mActiveAnimations--;
|
||||
}
|
||||
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void MinimizeAnimationEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
|
|
|
@ -28,7 +28,7 @@ class MinimizeAnimationEffect
|
|||
MinimizeAnimationEffect();
|
||||
|
||||
virtual void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintScreen();
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ void PresentWindowsEffect::prePaintScreen( int* mask, QRegion* region, int time
|
|||
effects->prePaintScreen(mask, region, time);
|
||||
}
|
||||
|
||||
void PresentWindowsEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void PresentWindowsEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
if( mActiveness > 0.0f && mWindowData.contains(w->window()) )
|
||||
{
|
||||
|
@ -83,7 +83,7 @@ void PresentWindowsEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion*
|
|||
*mask |= Scene::PAINT_WINDOW_TRANSLUCENT;
|
||||
}
|
||||
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void PresentWindowsEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
|
|
|
@ -31,7 +31,7 @@ class PresentWindowsEffect
|
|||
|
||||
|
||||
virtual void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintScreen();
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ void ScaleInEffect::prePaintScreen( int* mask, QRegion* region, int time )
|
|||
effects->prePaintScreen( mask, region, time );
|
||||
}
|
||||
|
||||
void ScaleInEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void ScaleInEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
if( windows.contains( w ))
|
||||
{
|
||||
|
@ -32,7 +32,7 @@ void ScaleInEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region,
|
|||
else
|
||||
windows.remove( w );
|
||||
}
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void ScaleInEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
|
|
|
@ -21,7 +21,7 @@ class ScaleInEffect
|
|||
{
|
||||
public:
|
||||
virtual void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintWindow( EffectWindow* w );
|
||||
// TODO react also on virtual desktop changes
|
||||
|
|
86
effects/shadow.cpp
Normal file
86
effects/shadow.cpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*****************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2007 Lubos Lunak <l.lunak@kde.org>
|
||||
|
||||
You can Freely distribute this program under the GNU General Public
|
||||
License. See the file "COPYING" for the exact licensing terms.
|
||||
******************************************************************/
|
||||
|
||||
#include "shadow.h"
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
namespace KWinInternal
|
||||
{
|
||||
|
||||
ShadowEffect::ShadowEffect()
|
||||
: shadowXOffset( 10 )
|
||||
, shadowYOffset( 10 )
|
||||
{
|
||||
}
|
||||
|
||||
void ShadowEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
*mask |= Scene::PAINT_WINDOW_TRANSLUCENT;
|
||||
*paint |= ( QRegion( w->geometry()) & *paint ).translated( shadowXOffset, shadowYOffset );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void ShadowEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
{
|
||||
drawShadow( w, mask, region, data.opacity );
|
||||
effects->paintWindow( w, mask, region, data );
|
||||
}
|
||||
|
||||
void ShadowEffect::postPaintWindow( EffectWindow* w )
|
||||
{
|
||||
effects->postPaintWindow( w );
|
||||
}
|
||||
|
||||
QRect ShadowEffect::transformWindowDamage( EffectWindow* w, const QRect& r )
|
||||
{
|
||||
QRect r2 = r | r.translated( shadowXOffset, shadowYOffset );
|
||||
return effects->transformWindowDamage( w, r2 );
|
||||
}
|
||||
|
||||
void ShadowEffect::drawShadow( EffectWindow* w, int mask, QRegion region, double opacity )
|
||||
{
|
||||
if(( mask & Scene::PAINT_WINDOW_TRANSLUCENT ) == 0 )
|
||||
return;
|
||||
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glColor4f( 0, 0, 0, 0.2 * opacity ); // black
|
||||
QRect r( w->geometry());
|
||||
r.moveBy( shadowXOffset, shadowYOffset );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
int verts[ 4 * 2 ] =
|
||||
{
|
||||
r.x(), r.y(),
|
||||
r.x(), r.y() + r.height(),
|
||||
r.x() + r.width(), r.y() + r.height(),
|
||||
r.x() + r.width(), r.y()
|
||||
};
|
||||
glVertexPointer( 2, GL_INT, 0, verts );
|
||||
if( mask & ( Scene::PAINT_WINDOW_TRANSFORMED | Scene::PAINT_SCREEN_TRANSFORMED ))
|
||||
glDrawArrays( GL_QUADS, 0, 4 );
|
||||
else
|
||||
{ // clip by region
|
||||
glEnable( GL_SCISSOR_TEST );
|
||||
int dh = displayHeight();
|
||||
foreach( QRect r, region.rects())
|
||||
{
|
||||
// Scissor rect has to be given in OpenGL coords
|
||||
glScissor(r.x(), dh - r.y() - r.height(), r.width(), r.height());
|
||||
glDrawArrays( GL_QUADS, 0, 4 );
|
||||
}
|
||||
}
|
||||
glDisableClientState( GL_VERTEX_ARRAY );
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
} // namespace
|
35
effects/shadow.h
Normal file
35
effects/shadow.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*****************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2007 Lubos Lunak <l.lunak@kde.org>
|
||||
|
||||
You can Freely distribute this program under the GNU General Public
|
||||
License. See the file "COPYING" for the exact licensing terms.
|
||||
******************************************************************/
|
||||
|
||||
#ifndef KWIN_SHADOW_H
|
||||
#define KWIN_SHADOW_H
|
||||
|
||||
#include <effects.h>
|
||||
|
||||
namespace KWinInternal
|
||||
{
|
||||
|
||||
class ShadowEffect
|
||||
: public Effect
|
||||
{
|
||||
public:
|
||||
ShadowEffect();
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintWindow( EffectWindow* w );
|
||||
virtual QRect transformWindowDamage( EffectWindow* w, const QRect& r );
|
||||
private:
|
||||
void drawShadow( EffectWindow* w, int mask, QRegion region, double opacity );
|
||||
int shadowXOffset, shadowYOffset;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
|
@ -30,11 +30,11 @@ void ShakyMoveEffect::prePaintScreen( int* mask, QRegion* region, int time )
|
|||
effects->prePaintScreen( mask, region, time );
|
||||
}
|
||||
|
||||
void ShakyMoveEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void ShakyMoveEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
if( windows.contains( w ))
|
||||
*mask |= Scene::PAINT_WINDOW_TRANSFORMED;
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void ShakyMoveEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
|
|
|
@ -25,7 +25,7 @@ class ShakyMoveEffect
|
|||
public:
|
||||
ShakyMoveEffect();
|
||||
virtual void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void windowUserMovedResized( EffectWindow* c, bool first, bool last );
|
||||
virtual void windowClosed( EffectWindow* c );
|
||||
|
|
|
@ -41,7 +41,7 @@ void WavyWindowsEffect::prePaintScreen( int* mask, QRegion* region, int time )
|
|||
effects->prePaintScreen(mask, region, time);
|
||||
}
|
||||
|
||||
void WavyWindowsEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
|
||||
void WavyWindowsEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
|
||||
{
|
||||
// This window will be transformed by the effect
|
||||
*mask |= Scene::PAINT_WINDOW_TRANSFORMED;
|
||||
|
@ -52,7 +52,7 @@ void WavyWindowsEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* reg
|
|||
// pixels big
|
||||
glwin->requestVertexGrid(30);
|
||||
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
effects->prePaintWindow( w, mask, paint, clip, time );
|
||||
}
|
||||
|
||||
void WavyWindowsEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
|
|
|
@ -28,7 +28,7 @@ class WavyWindowsEffect
|
|||
WavyWindowsEffect();
|
||||
|
||||
virtual void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintScreen();
|
||||
|
||||
|
|
|
@ -1665,7 +1665,7 @@ void Unmanaged::configureNotifyEvent( XConfigureEvent* e )
|
|||
QRect newgeom( e->x, e->y, e->width, e->height );
|
||||
if( newgeom == geom )
|
||||
return;
|
||||
workspace()->addRepaint( geometry()); // damage old area
|
||||
addWorkspaceRepaint( geometry()); // damage old area
|
||||
QRect old = geom;
|
||||
geom = newgeom;
|
||||
discardWindowPixmap();
|
||||
|
|
|
@ -1707,7 +1707,7 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force )
|
|||
if( effects != NULL )
|
||||
effects->windowGeometryShapeChanged( effectWindow(), geom_before_block );
|
||||
}
|
||||
workspace()->addRepaint( geom_before_block );
|
||||
addWorkspaceRepaint( geom_before_block );
|
||||
geom_before_block = geom;
|
||||
}
|
||||
|
||||
|
@ -1768,7 +1768,7 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
|
|||
scene->windowGeometryShapeChanged( this );
|
||||
if( effects != NULL )
|
||||
effects->windowGeometryShapeChanged( effectWindow(), geom_before_block );
|
||||
workspace()->addRepaint( geom_before_block );
|
||||
addWorkspaceRepaint( geom_before_block );
|
||||
geom_before_block = geom;
|
||||
}
|
||||
|
||||
|
@ -1791,8 +1791,8 @@ void Client::move( int x, int y, ForceGeometry_t force )
|
|||
updateWindowRules();
|
||||
checkMaximizeGeometry();
|
||||
// client itself is not damaged
|
||||
workspace()->addRepaint( geom_before_block );
|
||||
workspace()->addRepaint( geom ); // trigger repaint of window's new location
|
||||
addWorkspaceRepaint( geom_before_block );
|
||||
addWorkspaceRepaint( geom ); // trigger repaint of window's new location
|
||||
geom_before_block = geom;
|
||||
}
|
||||
|
||||
|
|
43
scene.cpp
43
scene.cpp
|
@ -109,6 +109,7 @@ void Scene::paintScreen( int* mask, QRegion* region )
|
|||
{ // whole screen, not transformed, force region to be full
|
||||
*region = QRegion( 0, 0, displayWidth(), displayHeight());
|
||||
}
|
||||
painted_region = *region;
|
||||
if( *mask & PAINT_SCREEN_BACKGROUND_FIRST )
|
||||
paintBackground( *region );
|
||||
ScreenPaintData data;
|
||||
|
@ -116,6 +117,9 @@ void Scene::paintScreen( int* mask, QRegion* region )
|
|||
effects->postPaintScreen();
|
||||
foreach( Window* w, stacking_order )
|
||||
effects->postPaintWindow( effectWindow( w ));
|
||||
*region |= painted_region;
|
||||
// make sure not to go outside of the screen area
|
||||
*region &= QRegion( 0, 0, displayWidth(), displayHeight());
|
||||
}
|
||||
|
||||
// Compute time since the last painting pass.
|
||||
|
@ -161,12 +165,13 @@ void Scene::paintGenericScreen( int orig_mask, ScreenPaintData )
|
|||
{
|
||||
int mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT );
|
||||
w->resetPaintingEnabled();
|
||||
QRegion damage = infiniteRegion();
|
||||
QRegion paint = infiniteRegion(); // no clipping, so doesn't really matter
|
||||
QRegion clip = QRegion();
|
||||
// preparation step
|
||||
effects->prePaintWindow( effectWindow( w ), &mask, &damage, time_diff );
|
||||
effects->prePaintWindow( effectWindow( w ), &mask, &paint, &clip, time_diff );
|
||||
if( !w->isPaintingEnabled())
|
||||
continue;
|
||||
paintWindow( w, mask, damage );
|
||||
paintWindow( w, mask, infiniteRegion());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,6 +185,7 @@ void Scene::paintSimpleScreen( int orig_mask, QRegion region )
|
|||
assert(( orig_mask & ( PAINT_WINDOW_TRANSFORMED | PAINT_SCREEN_TRANSFORMED
|
||||
| PAINT_WINDOW_TRANSLUCENT | PAINT_WINDOW_OPAQUE )) == 0 );
|
||||
QList< Phase2Data > phase2;
|
||||
QRegion allclips;
|
||||
// Draw each opaque window top to bottom, subtracting the bounding rect of
|
||||
// each window from the clip region after it's been drawn.
|
||||
for( int i = stacking_order.count() - 1; // top to bottom
|
||||
|
@ -187,25 +193,32 @@ void Scene::paintSimpleScreen( int orig_mask, QRegion region )
|
|||
--i )
|
||||
{
|
||||
Window* w = stacking_order[ i ];
|
||||
if( region.isEmpty()) // completely clipped
|
||||
continue;
|
||||
int mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT );
|
||||
w->resetPaintingEnabled();
|
||||
QRegion damage = region;
|
||||
QRegion paint = region;
|
||||
QRegion clip = w->isOpaque() ? w->shape().translated( w->x(), w->y()) : QRegion();
|
||||
// preparation step
|
||||
effects->prePaintWindow( effectWindow( w ), &mask, &damage, time_diff );
|
||||
effects->prePaintWindow( effectWindow( w ), &mask, &paint, &clip, time_diff );
|
||||
if( !w->isPaintingEnabled())
|
||||
continue;
|
||||
paint -= allclips; // make sure to avoid already clipped areas
|
||||
if( paint.isEmpty()) // completely clipped
|
||||
continue;
|
||||
if( paint != region ) // prepaint added area to draw
|
||||
{
|
||||
region |= paint; // make sure other windows in that area get painted too
|
||||
painted_region |= paint; // make sure it makes it to the screen
|
||||
}
|
||||
// If the window is transparent, the transparent part will be done
|
||||
// in the 2nd pass.
|
||||
if( mask & PAINT_WINDOW_TRANSLUCENT )
|
||||
phase2.prepend( Phase2Data( w, region, mask ));
|
||||
phase2.prepend( Phase2Data( w, paint, mask ));
|
||||
if( mask & PAINT_WINDOW_OPAQUE )
|
||||
{
|
||||
paintWindow( w, mask, region );
|
||||
// If the window is not transparent at all, it can clip windows below.
|
||||
if( ( mask & PAINT_WINDOW_TRANSLUCENT ) == 0 )
|
||||
region -= w->shape().translated( w->x(), w->y());
|
||||
paintWindow( w, mask, paint );
|
||||
// The window can clip by its opaque parts the windows below.
|
||||
region -= clip;
|
||||
allclips |= clip;
|
||||
}
|
||||
}
|
||||
if( !( orig_mask & PAINT_SCREEN_BACKGROUND_FIRST ))
|
||||
|
@ -213,10 +226,14 @@ void Scene::paintSimpleScreen( int orig_mask, QRegion region )
|
|||
// Now walk the list bottom to top, drawing translucent windows.
|
||||
// That we draw bottom to top is important now since we're drawing translucent objects
|
||||
// and also are clipping only by opaque windows.
|
||||
QRegion add_paint;
|
||||
foreach( Phase2Data d, phase2 )
|
||||
{
|
||||
Window* w = d.window;
|
||||
paintWindow( w, d.mask, d.region );
|
||||
paintWindow( w, d.mask, d.region | add_paint );
|
||||
// It is necessary to also add paint regions of windows below, because their
|
||||
// pre-paint's might have extended the paint area, so those areas need to be painted too.
|
||||
add_paint |= d.region;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
6
scene.h
6
scene.h
|
@ -106,6 +106,12 @@ class Scene
|
|||
};
|
||||
// windows in their stacking order
|
||||
QVector< Window* > stacking_order;
|
||||
// The region which actually has been painted by paintScreen() and should be
|
||||
// copied from the buffer to the screen. I.e. the region returned from Scene::paintScreen().
|
||||
// Since prePaintWindow() can extend areas to paint, these changes would have to propagate
|
||||
// up all the way from paintSimpleScreen() up to paintScreen(), so save them here rather
|
||||
// than propagate them up in arguments.
|
||||
QRegion painted_region;
|
||||
// time since last repaint
|
||||
int time_diff;
|
||||
QTime last_time;
|
||||
|
|
|
@ -557,8 +557,6 @@ void SceneOpenGL::waitSync()
|
|||
// actually paint to the screen (double-buffer swap or copy from pixmap buffer)
|
||||
void SceneOpenGL::flushBuffer( int mask, QRegion damage )
|
||||
{
|
||||
if( mask & PAINT_SCREEN_REGION )// make sure not to go outside visible screen
|
||||
damage &= QRegion( 0, 0, displayWidth(), displayHeight());
|
||||
if( db )
|
||||
{
|
||||
if( mask & PAINT_SCREEN_REGION )
|
||||
|
|
|
@ -157,6 +157,7 @@ void SceneXrender::paintTransformedScreen( int orig_mask )
|
|||
{
|
||||
QRegion region( 0, 0, displayWidth(), displayHeight());
|
||||
QList< Phase2Data > phase2;
|
||||
QRegion allclips;
|
||||
// Draw each opaque window top to bottom, subtracting the bounding rect of
|
||||
// each window from the clip region after it's been drawn.
|
||||
for( int i = stacking_order.count() - 1; // top to bottom
|
||||
|
@ -164,26 +165,33 @@ void SceneXrender::paintTransformedScreen( int orig_mask )
|
|||
--i )
|
||||
{
|
||||
Window* w = static_cast< Window* >( stacking_order[ i ] );
|
||||
if( region.isEmpty()) // completely clipped
|
||||
continue;
|
||||
int mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT );
|
||||
w->resetPaintingEnabled();
|
||||
QRegion damage = region;
|
||||
QRegion paint = region;
|
||||
// TODO this is wrong, transformedShape() should be used here, but is not known yet
|
||||
QRegion clip = w->isOpaque() ? region : QRegion();
|
||||
// preparation step
|
||||
effects->prePaintWindow( effectWindow( w ), &mask, &damage, time_diff );
|
||||
effects->prePaintWindow( effectWindow( w ), &mask, &paint, &clip, time_diff );
|
||||
if( !w->isPaintingEnabled())
|
||||
continue;
|
||||
paint -= allclips; // make sure to avoid already clipped areas
|
||||
if( paint.isEmpty()) // completely clipped
|
||||
continue;
|
||||
if( paint != region ) // prepaint added area to draw
|
||||
{
|
||||
region |= paint; // make sure other windows in that area get painted too
|
||||
painted_region |= paint; // make sure it makes it to the screen
|
||||
}
|
||||
// If the window is transparent, the transparent part will be done
|
||||
// in the 2nd pass.
|
||||
if( mask & PAINT_WINDOW_TRANSLUCENT )
|
||||
phase2.prepend( Phase2Data( w, region, mask ));
|
||||
phase2.prepend( Phase2Data( w, paint, mask ));
|
||||
if( mask & PAINT_WINDOW_OPAQUE )
|
||||
{
|
||||
w->setTransformedShape( QRegion());
|
||||
paintWindow( w, mask, region );
|
||||
// If the window is not transparent at all, it can clip windows below.
|
||||
if( ( mask & PAINT_WINDOW_TRANSLUCENT ) == 0 )
|
||||
region -= w->transformedShape();
|
||||
paintWindow( w, mask, paint );
|
||||
// The window can clip by its opaque parts the windows below.
|
||||
region -= w->transformedShape();
|
||||
}
|
||||
}
|
||||
if( !( orig_mask & PAINT_SCREEN_BACKGROUND_FIRST ))
|
||||
|
@ -191,10 +199,14 @@ void SceneXrender::paintTransformedScreen( int orig_mask )
|
|||
// Now walk the list bottom to top, drawing translucent windows.
|
||||
// That we draw bottom to top is important now since we're drawing translucent objects
|
||||
// and also are clipping only by opaque windows.
|
||||
QRegion add_paint;
|
||||
foreach( Phase2Data d, phase2 )
|
||||
{
|
||||
Scene::Window* w = d.window;
|
||||
paintWindow( w, d.mask, d.region );
|
||||
paintWindow( w, d.mask, d.region | add_paint );
|
||||
// It is necessary to also add paint regions of windows below, because their
|
||||
// pre-paint's might have extended the paint area, so those areas need to be painted too.
|
||||
add_paint |= d.region;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,6 +90,9 @@ class Toplevel
|
|||
void addRepaint( const QRect& r );
|
||||
void addRepaint( int x, int y, int w, int h );
|
||||
void addRepaintFull();
|
||||
// these call workspace->addRepaint(), but first transform the damage if needed
|
||||
void addWorkspaceRepaint( const QRect& r );
|
||||
void addWorkspaceRepaint( int x, int y, int w, int h );
|
||||
QRegion repaints() const;
|
||||
void resetRepaints( const QRect& r );
|
||||
QRegion damage() const;
|
||||
|
|
|
@ -80,7 +80,7 @@ void Unmanaged::release()
|
|||
if( Extensions::shapeAvailable())
|
||||
XShapeSelectInput( display(), window(), NoEventMask );
|
||||
XSelectInput( display(), window(), NoEventMask );
|
||||
workspace()->addRepaint( geometry());
|
||||
addWorkspaceRepaint( geometry());
|
||||
disownDataPassedToDeleted();
|
||||
del->unrefWindow();
|
||||
deleteUnmanaged( this, Allowed );
|
||||
|
|
105
workspace.h
105
workspace.h
|
@ -18,6 +18,8 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include <QCursor>
|
||||
#include <netwm.h>
|
||||
#include <kxmessages.h>
|
||||
#include <qdatetime.h>
|
||||
#include <kmanagerselection.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "kdecoration.h"
|
||||
|
@ -77,7 +79,7 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
virtual ~Workspace();
|
||||
|
||||
static Workspace * self() { return _self; }
|
||||
|
||||
|
||||
bool workspaceEvent( XEvent * );
|
||||
|
||||
KDecoration* createDecoration( KDecorationBridge* bridge );
|
||||
|
@ -87,6 +89,9 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
template< typename T > Client* findClient( T predicate );
|
||||
template< typename T1, typename T2 > void forEachClient( T1 procedure, T2 predicate );
|
||||
template< typename T > void forEachClient( T procedure );
|
||||
template< typename T > Unmanaged* findUnmanaged( T predicate );
|
||||
template< typename T1, typename T2 > void forEachUnmanaged( T1 procedure, T2 predicate );
|
||||
template< typename T > void forEachUnmanaged( T procedure );
|
||||
|
||||
QRect clientArea( clientAreaOption, const QPoint& p, int desktop ) const;
|
||||
QRect clientArea( clientAreaOption, const Client* c ) const;
|
||||
|
@ -165,12 +170,17 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
QWidget* desktopWidget();
|
||||
|
||||
// for TabBox
|
||||
Client* currentTabBoxClient() const;
|
||||
ClientList currentTabBoxClientList() const;
|
||||
int currentTabBoxDesktop() const;
|
||||
Client* nextFocusChainClient(Client*) const;
|
||||
Client* previousFocusChainClient(Client*) const;
|
||||
Client* nextStaticClient(Client*) const;
|
||||
Client* previousStaticClient(Client*) const;
|
||||
int nextDesktopFocusChain( int iDesktop ) const;
|
||||
int previousDesktopFocusChain( int iDesktop ) const;
|
||||
void refTabBox();
|
||||
void unrefTabBox();
|
||||
void closeTabBox();
|
||||
|
||||
/**
|
||||
|
@ -181,7 +191,7 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
|
||||
ClientList ensureStackingOrder( const ClientList& clients ) const;
|
||||
|
||||
Client* topClientOnDesktop( int desktop, bool unconstrained = false, bool only_normal = true ) const;
|
||||
Client* topClientOnDesktop( int desktop, bool unconstrained = false ) const;
|
||||
Client* findDesktop( bool topmost, int desktop ) const;
|
||||
void sendClientToDesktop( Client* c, int desktop, bool dont_activate );
|
||||
void windowToPreviousDesktop( Client* c );
|
||||
|
@ -190,6 +200,10 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
// KDE4 remove me - and it's also in the DCOP interface :(
|
||||
void showWindowMenuAt( unsigned long id, int x, int y );
|
||||
|
||||
void loadEffect( const QString& name );
|
||||
|
||||
void unloadEffect( const QString& name );
|
||||
|
||||
/**
|
||||
* Shows the menu operations menu for the client and makes it active if
|
||||
* it's not already.
|
||||
|
@ -213,8 +227,6 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
WindowRules findWindowRules( const Client*, bool );
|
||||
void rulesUpdated();
|
||||
void discardUsedWindowRules( Client* c, bool withdraw );
|
||||
void disableRulesUpdates( bool disable );
|
||||
bool rulesUpdatesDisabled() const;
|
||||
|
||||
// dcop interface
|
||||
void cascadeDesktop();
|
||||
|
@ -226,7 +238,7 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
void circulateDesktopApplications();
|
||||
|
||||
QString desktopName( int desk ) const;
|
||||
void setDesktopLayout(NET::Orientation o, int x, int y, NET::DesktopLayoutCorner c);
|
||||
void setDesktopLayout(int o, int x, int y);
|
||||
void setShowingDesktop( bool showing );
|
||||
void resetShowingDesktop( bool keep_hidden );
|
||||
bool showingDesktop() const;
|
||||
|
@ -236,14 +248,17 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
void sendPingToWindow( Window w, Time timestamp ); // called from Client::pingWindow()
|
||||
void sendTakeActivity( Client* c, Time timestamp, long flags ); // called from Client::takeActivity()
|
||||
|
||||
// only called from Client::destroyClient() or Client::releaseWindow()
|
||||
void removeClient( Client*, allowed_t );
|
||||
void removeClient( Client*, allowed_t ); // only called from Client::destroyClient() or Client::releaseWindow()
|
||||
void setActiveClient( Client*, allowed_t );
|
||||
Group* findGroup( Window leader ) const;
|
||||
void addGroup( Group* group, allowed_t );
|
||||
void removeGroup( Group* group, allowed_t );
|
||||
Group* findClientLeaderGroup( const Client* c ) const;
|
||||
|
||||
void removeUnmanaged( Unmanaged*, allowed_t ); // only called from Unmanaged::release()
|
||||
void removeDeleted( Deleted*, allowed_t );
|
||||
void addDeleted( Deleted*, allowed_t );
|
||||
|
||||
bool checkStartupNotification( Window w, KStartupInfoId& id, KStartupInfoData& data );
|
||||
|
||||
void focusToNull(); // SELI public?
|
||||
|
@ -279,6 +294,19 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
|
||||
void toggleTopDockShadows(bool on);
|
||||
|
||||
// when adding repaints caused by a window, you probably want to use
|
||||
// either Toplevel::addRepaint() or Toplevel::addWorkspaceRepaint()
|
||||
void addRepaint( const QRect& r );
|
||||
void addRepaint( int x, int y, int w, int h );
|
||||
void addRepaintFull();
|
||||
// creates XComposite overlay window, call initOverlay() afterwards
|
||||
bool createOverlay();
|
||||
// init overlay and the destination window in it
|
||||
void setupOverlay( Window window );
|
||||
// destroys XComposite overlay window
|
||||
void destroyOverlay();
|
||||
Window overlayWindow();
|
||||
|
||||
public slots:
|
||||
void refresh();
|
||||
// keybindings
|
||||
|
@ -408,15 +436,14 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
void cleanupTemporaryRules();
|
||||
void writeWindowRules();
|
||||
void slotBlockShortcuts(int data);
|
||||
void slotReloadConfig();
|
||||
// kompmgr
|
||||
void setPopupClientOpacity(int v);
|
||||
void resetClientOpacity();
|
||||
void setTransButtonText(int value);
|
||||
// end
|
||||
void setPopupClientOpacity( QAction* action );
|
||||
void setupCompositing();
|
||||
void performCompositing();
|
||||
void lostCMSelection();
|
||||
|
||||
protected:
|
||||
bool keyPressMouseEmulation( XKeyEvent& ev );
|
||||
bool netCheck( XEvent* e );
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
@ -460,6 +487,8 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
// this is the right way to create a new client
|
||||
Client* createClient( Window w, bool is_mapped );
|
||||
void addClient( Client* c, allowed_t );
|
||||
Unmanaged* createUnmanaged( Window w );
|
||||
void addUnmanaged( Unmanaged* c, allowed_t );
|
||||
|
||||
Window findSpecialEventWindow( XEvent* e );
|
||||
|
||||
|
@ -501,6 +530,9 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
void closeActivePopup();
|
||||
|
||||
void updateClientArea( bool force );
|
||||
|
||||
void finishCompositing();
|
||||
bool windowRepaintsPending() const;
|
||||
|
||||
SystemTrayWindowList systemTrayWins;
|
||||
|
||||
|
@ -521,7 +553,6 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
QList<Rules*> rules;
|
||||
KXMessages temporaryRulesMessages;
|
||||
QTimer rulesUpdatedTimer;
|
||||
bool rules_updates_disabled;
|
||||
static const char* windowTypeToTxt( NET::WindowType type );
|
||||
static NET::WindowType txtToWindowType( const char* txt );
|
||||
static bool sessionInfoWindowTypeMatch( Client* c, SessionInfo* info );
|
||||
|
@ -538,10 +569,12 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
|
||||
ClientList clients;
|
||||
ClientList desktops;
|
||||
UnmanagedList unmanaged;
|
||||
DeletedList deleted;
|
||||
|
||||
ClientList unconstrained_stacking_order; // topmost last
|
||||
ClientList stacking_order; // topmost last
|
||||
QVector< ClientList > focus_chain; // currently ative last
|
||||
ClientList unconstrained_stacking_order;
|
||||
ClientList stacking_order;
|
||||
QVector< ClientList > focus_chain;
|
||||
ClientList global_focus_chain; // this one is only for things like tabbox's MRU
|
||||
ClientList should_get_focus; // last is most recent
|
||||
ClientList attention_chain;
|
||||
|
@ -575,6 +608,7 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
|
||||
QMenu *popup;
|
||||
QMenu *advanced_popup;
|
||||
QMenu *trans_popup;
|
||||
QMenu *desk_popup;
|
||||
int desk_popup_index;
|
||||
|
||||
|
@ -658,12 +692,14 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
bool forced_global_mouse_grab;
|
||||
friend class StackingUpdatesBlocker;
|
||||
|
||||
//kompmgr
|
||||
KSelectionOwner* cm_selection;
|
||||
QTimer compositeTimer;
|
||||
QTime lastCompositePaint;
|
||||
int compositeRate;
|
||||
QRegion repaints_region;
|
||||
Window overlay; // XComposite overlay window
|
||||
QSlider *transSlider;
|
||||
QPushButton *transButton;
|
||||
|
||||
private:
|
||||
friend bool performTransiencyCheck();
|
||||
};
|
||||
|
||||
// helper for Workspace::blockStackingUpdates() being called in pairs (true/false)
|
||||
|
@ -806,10 +842,9 @@ inline bool Workspace::globalShortcutsDisabled() const
|
|||
return global_shortcuts_disabled || global_shortcuts_disabled_for_client;
|
||||
}
|
||||
|
||||
inline
|
||||
bool Workspace::rulesUpdatesDisabled() const
|
||||
inline Window Workspace::overlayWindow()
|
||||
{
|
||||
return rules_updates_disabled;
|
||||
return overlay;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
|
@ -839,7 +874,27 @@ inline void Workspace::forEachClient( T procedure )
|
|||
return forEachClient( procedure, TruePredicate());
|
||||
}
|
||||
|
||||
KWIN_COMPARE_PREDICATE( ClientMatchPredicate, const Client*, cl == value );
|
||||
template< typename T >
|
||||
inline Unmanaged* Workspace::findUnmanaged( T predicate )
|
||||
{
|
||||
return findUnmanagedInList( unmanaged, predicate );
|
||||
}
|
||||
|
||||
template< typename T1, typename T2 >
|
||||
inline void Workspace::forEachUnmanaged( T1 procedure, T2 predicate )
|
||||
{
|
||||
for ( UnmanagedList::ConstIterator it = unmanaged.begin(); it != unmanaged.end(); ++it)
|
||||
if ( predicate( const_cast< const Unmanaged* >( *it)))
|
||||
procedure( *it );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline void Workspace::forEachUnmanaged( T procedure )
|
||||
{
|
||||
return forEachUnmanaged( procedure, TruePredicate());
|
||||
}
|
||||
|
||||
KWIN_COMPARE_PREDICATE( ClientMatchPredicate, Client, const Client*, cl == value );
|
||||
inline bool Workspace::hasClient( const Client* c )
|
||||
{
|
||||
return findClient( ClientMatchPredicate( c ));
|
||||
|
|
Loading…
Reference in a new issue