Add EffectWindow as a window representation for effects,

to hide the change from Client/Unmanaged and eventually also
act as the only API available to effects.


svn path=/branches/work/kwin_composite/; revision=626360
This commit is contained in:
Luboš Luňák 2007-01-22 22:57:22 +00:00
parent e8147c2244
commit 0ae5a772e7
31 changed files with 342 additions and 239 deletions

View file

@ -226,10 +226,6 @@ Effects TODO
initiated by the user or by the application
* - fade-out needs framework for disappearing windows (see the todo entry)
+ add API that'll hide the internals (for making backwards compatibility easier, etc.)
- effects should have access only to classes from this API
- hide the fact that Client/Unmanaged become Deleted in windowClosed()
+ minimize/shade effects
- to replace the ones from KWin core
- Client::animateMinimizeOrUnminimize()
@ -260,3 +256,6 @@ Effects TODO
part of screen to clear its own painting, that triggers itself again next repaint)
? other effects
+ EffectWindow should be completely opaque when kept as the only API for effects
- no inlines, etc.

View file

@ -247,7 +247,7 @@ void Workspace::setActiveClient( Client* c, allowed_t )
rootInfo->setActiveWindow( active_client? active_client->window() : 0 );
updateColormap();
if( effects )
effects->windowActivated( active_client );
effects->windowActivated( active_client ? active_client->effectWindow() : NULL );
--set_active_client_recursion;
}

View file

@ -181,7 +181,7 @@ void Client::releaseWindow( bool on_shutdown )
if( effects )
{
Deleted* del = Deleted::create( this );
effects->windowClosed( this, del );
effects->windowClosed( del->effectWindow()); // effectWindow is already 'del'
scene->windowClosed( this, del );
del->unrefWindow();
}
@ -247,7 +247,7 @@ void Client::destroyClient()
if( effects )
{
Deleted* del = Deleted::create( this );
effects->windowClosed( this, del );
effects->windowClosed( del->effectWindow()); // effectWindow is already 'del'
scene->windowClosed( this, del );
del->unrefWindow();
}
@ -575,7 +575,7 @@ void Client::minimize( bool avoid_animation )
updateWindowRules();
workspace()->updateFocusChains( this, Workspace::FocusChainMakeLast );
if( effects )
effects->windowMinimized( this );
effects->windowMinimized( effectWindow());
}
void Client::unminimize( bool avoid_animation )
@ -595,7 +595,7 @@ void Client::unminimize( bool avoid_animation )
workspace()->updateMinimizedOfTransients( this );
updateWindowRules();
if( effects )
effects->windowUnminimized( this );
effects->windowUnminimized( effectWindow());
}
extern bool blockAnimation;

View file

@ -295,6 +295,8 @@ void Toplevel::setupCompositing()
return;
damage_handle = XDamageCreate( display(), handle(), XDamageReportRawRectangles );
damage_region = QRegion( 0, 0, width(), height());
effect_window = new EffectWindow();
effect_window->setWindow( this );
}
void Toplevel::finishCompositing()
@ -305,6 +307,8 @@ void Toplevel::finishCompositing()
discardWindowPixmap();
damage_handle = None;
damage_region = QRegion();
delete effect_window;
effect_window = NULL;
}
void Toplevel::discardWindowPixmap()

View file

@ -39,31 +39,31 @@ Effect::~Effect()
{
}
void Effect::windowUserMovedResized( Toplevel* , bool, bool )
void Effect::windowUserMovedResized( EffectWindow* , bool, bool )
{
}
void Effect::windowAdded( Toplevel* )
void Effect::windowAdded( EffectWindow* )
{
}
void Effect::windowClosed( Toplevel*, Deleted* )
void Effect::windowClosed( EffectWindow* )
{
}
void Effect::windowDeleted( Deleted* )
void Effect::windowDeleted( EffectWindow* )
{
}
void Effect::windowActivated( Toplevel* )
void Effect::windowActivated( EffectWindow* )
{
}
void Effect::windowMinimized( Toplevel* )
void Effect::windowMinimized( EffectWindow* )
{
}
void Effect::windowUnminimized( Toplevel* )
void Effect::windowUnminimized( EffectWindow* )
{
}
@ -86,17 +86,17 @@ void Effect::postPaintScreen()
effects->postPaintScreen();
}
void Effect::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time )
void Effect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
{
effects->prePaintWindow( w, mask, region, time );
}
void Effect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
void Effect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
effects->paintWindow( w, mask, region, data );
}
void Effect::postPaintWindow( Scene::Window* w )
void Effect::postPaintWindow( EffectWindow* w )
{
effects->postPaintWindow( w );
}
@ -135,43 +135,43 @@ EffectsHandler::~EffectsHandler()
XDestroyWindow( display(), pos.second );
}
void EffectsHandler::windowUserMovedResized( Toplevel* c, bool first, bool last )
void EffectsHandler::windowUserMovedResized( EffectWindow* c, bool first, bool last )
{
foreach( Effect* e, effects )
e->windowUserMovedResized( c, first, last );
}
void EffectsHandler::windowAdded( Toplevel* c )
void EffectsHandler::windowAdded( EffectWindow* c )
{
foreach( Effect* e, effects )
e->windowAdded( c );
}
void EffectsHandler::windowDeleted( Deleted* c )
void EffectsHandler::windowDeleted( EffectWindow* c )
{
foreach( Effect* e, effects )
e->windowDeleted( c );
}
void EffectsHandler::windowClosed( Toplevel* c, Deleted* deleted )
void EffectsHandler::windowClosed( EffectWindow* c )
{
foreach( Effect* e, effects )
e->windowClosed( c, deleted );
e->windowClosed( c );
}
void EffectsHandler::windowActivated( Toplevel* c )
void EffectsHandler::windowActivated( EffectWindow* c )
{
foreach( Effect* e, effects )
e->windowActivated( c );
}
void EffectsHandler::windowMinimized( Toplevel* c )
void EffectsHandler::windowMinimized( EffectWindow* c )
{
foreach( Effect* e, effects )
e->windowMinimized( c );
}
void EffectsHandler::windowUnminimized( Toplevel* c )
void EffectsHandler::windowUnminimized( EffectWindow* c )
{
foreach( Effect* e, effects )
e->windowUnminimized( c );
@ -216,7 +216,7 @@ void EffectsHandler::postPaintScreen()
// no special final code
}
void EffectsHandler::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time )
void EffectsHandler::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
{
if( current_paint_window < effects.size())
{
@ -226,7 +226,7 @@ void EffectsHandler::prePaintWindow( Scene::Window* w, int* mask, QRegion* regio
// no special final code
}
void EffectsHandler::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
void EffectsHandler::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
if( current_paint_window < effects.size())
{
@ -237,7 +237,7 @@ void EffectsHandler::paintWindow( Scene::Window* w, int mask, QRegion region, Wi
scene->finalPaintWindow( w, mask, region, data );
}
void EffectsHandler::postPaintWindow( Scene::Window* w )
void EffectsHandler::postPaintWindow( EffectWindow* w )
{
if( current_paint_window < effects.size())
{
@ -329,9 +329,10 @@ void EffectsHandler::checkInputWindowStacking()
delete[] wins;
}
void EffectsHandler::activateWindow( Client* c )
void EffectsHandler::activateWindow( EffectWindow* c )
{
Workspace::self()->activateClient( c, true );
if( Client* cl = dynamic_cast< Client* >( c->window()))
Workspace::self()->activateClient( cl, true );
}
EffectsHandler* effects;

108
effects.h
View file

@ -22,6 +22,7 @@ namespace KWinInternal
class Toplevel;
class Workspace;
class EffectWindow;
class WindowPaintData
{
@ -67,17 +68,17 @@ 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( Scene::Window* w, int* mask, QRegion* region, int time );
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
virtual void postPaintWindow( Scene::Window* w );
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
virtual void postPaintWindow( EffectWindow* w );
// called when moved/resized or once after it's finished
virtual void windowUserMovedResized( Toplevel* c, bool first, bool last );
virtual void windowAdded( Toplevel* c );
virtual void windowClosed( Toplevel* c, Deleted* deleted );
virtual void windowDeleted( Deleted* c );
virtual void windowActivated( Toplevel* c );
virtual void windowMinimized( Toplevel* c );
virtual void windowUnminimized( Toplevel* c );
virtual void windowUserMovedResized( EffectWindow* c, bool first, bool last );
virtual void windowAdded( EffectWindow* c );
virtual void windowClosed( EffectWindow* c );
virtual void windowDeleted( EffectWindow* c );
virtual void windowActivated( EffectWindow* c );
virtual void windowMinimized( EffectWindow* c );
virtual void windowUnminimized( EffectWindow* c );
virtual void windowInputMouseEvent( Window w, QEvent* e );
// Interpolates between x and y
@ -96,9 +97,9 @@ class EffectsHandler
void prePaintScreen( int* mask, QRegion* region, int time );
void paintScreen( int mask, QRegion region, ScreenPaintData& data );
void postPaintScreen();
void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time );
void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
void postPaintWindow( Scene::Window* w );
void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
void postPaintWindow( EffectWindow* w );
// 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.
@ -106,16 +107,16 @@ class EffectsHandler
Window createInputWindow( Effect* e, const QRect& r, const QCursor& cursor );
void destroyInputWindow( Window w );
// functions that allow controlling windows/desktop
void activateWindow( Client* c );
void activateWindow( EffectWindow* c );
// internal (used by kwin core or compositing code)
void startPaint();
void windowUserMovedResized( Toplevel* c, bool first, bool last );
void windowAdded( Toplevel* c );
void windowClosed( Toplevel* c, Deleted* deleted );
void windowDeleted( Deleted* c );
void windowActivated( Toplevel* c );
void windowMinimized( Toplevel* c );
void windowUnminimized( Toplevel* c );
void windowUserMovedResized( EffectWindow* c, bool first, bool last );
void windowAdded( EffectWindow* c );
void windowClosed( EffectWindow* c );
void windowDeleted( EffectWindow* c );
void windowActivated( EffectWindow* c );
void windowMinimized( EffectWindow* c );
void windowUnminimized( EffectWindow* c );
bool checkInputWindowEvent( XEvent* e );
void checkInputWindowStacking();
private:
@ -126,6 +127,25 @@ class EffectsHandler
int current_paint_screen;
};
// This class is a representation of a window used by/for Effect classes.
// The purpose is to hide internal data and also to serve as a single
// representation for the case when Client/Unmanaged becomes Deleted.
class EffectWindow
{
public:
const Toplevel* window() const;
Toplevel* window();
void setWindow( Toplevel* w ); // internal
void setSceneWindow( Scene::Window* w ); // internal
Scene::Window* sceneWindow(); // internal
private:
Toplevel* tw;
Scene::Window* sw; // This one is used only during paint pass.
};
EffectWindow* effectWindow( Toplevel* w );
EffectWindow* effectWindow( Scene::Window* w );
extern EffectsHandler* effects;
inline
@ -149,6 +169,52 @@ ScreenPaintData::ScreenPaintData()
{
}
inline
const Toplevel* EffectWindow::window() const
{
return tw;
}
inline
Toplevel* EffectWindow::window()
{
return tw;
}
inline
void EffectWindow::setWindow( Toplevel* w )
{
tw = w;
}
inline
void EffectWindow::setSceneWindow( Scene::Window* w )
{
sw = w;
}
inline
Scene::Window* EffectWindow::sceneWindow()
{
return sw;
}
inline
EffectWindow* effectWindow( Toplevel* w )
{
EffectWindow* ret = w->effectWindow();
ret->setSceneWindow( NULL ); // just in case
return ret;
}
inline
EffectWindow* effectWindow( Scene::Window* w )
{
EffectWindow* ret = w->window()->effectWindow();
ret->setSceneWindow( w );
return ret;
}
} // namespace
#endif

View file

@ -19,7 +19,7 @@ License. See the file "COPYING" for the exact licensing terms.
namespace KWinInternal
{
void DialogParentEffect::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time )
void DialogParentEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
{
// How long does it take for the effect to get it's full strength (in ms)
const float changeTime = 200;
@ -41,7 +41,7 @@ void DialogParentEffect::prePaintWindow( Scene::Window* w, int* mask, QRegion* r
effects->prePaintWindow( w, mask, region, time );
}
void DialogParentEffect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
void DialogParentEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
float s = effectStrength[w];
if(s > 0.0f)
@ -56,7 +56,7 @@ void DialogParentEffect::paintWindow( Scene::Window* w, int mask, QRegion region
effects->paintWindow( w, mask, region, data );
}
void DialogParentEffect::postPaintWindow( Scene::Window* w )
void DialogParentEffect::postPaintWindow( EffectWindow* w )
{
float s = effectStrength[w];
@ -69,12 +69,12 @@ void DialogParentEffect::postPaintWindow( Scene::Window* w )
effects->postPaintWindow( w );
}
void DialogParentEffect::windowActivated( Toplevel* t )
void DialogParentEffect::windowActivated( EffectWindow* t )
{
// If this window is a dialog, we need to damage it's parent window, so
// that the effect could be run for it
// Set the window to be faded (or NULL if no window is active).
Client* c = qobject_cast<Client *>(t);
Client* c = qobject_cast<Client *>(t?t->window():NULL);
if ( c && c->isModal() )
{
// c is a modal dialog
@ -84,12 +84,12 @@ void DialogParentEffect::windowActivated( Toplevel* t )
}
}
void DialogParentEffect::windowClosed( Toplevel* t, Deleted* )
void DialogParentEffect::windowClosed( EffectWindow* t )
{
// If this window is a dialog, we need to damage it's parent window, so
// that the effect could be run for it
// Set the window to be faded (or NULL if no window is active).
Client* c = qobject_cast<Client *>(t);
Client* c = qobject_cast<Client *>(t->window());
if ( c && c->isModal() )
{
// c is a modal dialog

View file

@ -28,18 +28,18 @@ class DialogParentEffect
: public Effect
{
public:
virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time );
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
virtual void postPaintWindow( Scene::Window* w );
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
virtual void postPaintWindow( EffectWindow* w );
virtual void windowClosed( Toplevel* c, Deleted* );
virtual void windowActivated( Toplevel* c );
virtual void windowClosed( EffectWindow* c );
virtual void windowActivated( EffectWindow* c );
protected:
bool hasModalWindow( Toplevel* t );
private:
// The progress of the fading.
QMap<Scene::Window*, float> effectStrength;
QMap<EffectWindow*, float> effectStrength;
};
} // namespace

View file

@ -15,49 +15,49 @@ License. See the file "COPYING" for the exact licensing terms.
namespace KWinInternal
{
void FadeInEffect::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time )
void FadeInEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
{
if( windows.contains( w->window()))
if( windows.contains( w ))
{
windows[ w->window() ] += time / 1000.; // complete change in 1000ms
if( windows[ w->window() ] < 1 )
windows[ w ] += time / 1000.; // complete change in 1000ms
if( windows[ w ] < 1 )
{
*mask |= Scene::PAINT_WINDOW_TRANSLUCENT;
*mask &= ~Scene::PAINT_WINDOW_OPAQUE;
}
else
windows.remove( w->window());
windows.remove( w );
}
effects->prePaintWindow( w, mask, region, time );
}
void FadeInEffect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
void FadeInEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
if( windows.contains( w->window()))
if( windows.contains( w ))
{
data.opacity *= windows[ w->window()];
data.opacity *= windows[ w ];
}
effects->paintWindow( w, mask, region, data );
}
void FadeInEffect::postPaintWindow( Scene::Window* w )
void FadeInEffect::postPaintWindow( EffectWindow* w )
{
if( windows.contains( w->window()))
if( windows.contains( w ))
w->window()->addDamageFull(); // trigger next animation repaint
effects->postPaintWindow( w );
}
void FadeInEffect::windowAdded( Toplevel* c )
void FadeInEffect::windowAdded( EffectWindow* c )
{
Client* cc = dynamic_cast< Client* >( c );
Client* cc = dynamic_cast< Client* >( c->window());
if( cc == NULL || cc->isOnCurrentDesktop())
{
windows[ c ] = 0;
c->addDamageFull();
c->window()->addDamageFull();
}
}
void FadeInEffect::windowClosed( Toplevel* c, Deleted* )
void FadeInEffect::windowClosed( EffectWindow* c )
{
windows.remove( c );
}

View file

@ -22,14 +22,14 @@ class FadeInEffect
: public Effect
{
public:
virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time );
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
virtual void postPaintWindow( Scene::Window* w );
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, 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
virtual void windowAdded( Toplevel* c );
virtual void windowClosed( Toplevel* c, Deleted* );
virtual void windowAdded( EffectWindow* c );
virtual void windowClosed( EffectWindow* c );
private:
QMap< const Toplevel*, double > windows;
QMap< const EffectWindow*, double > windows;
};
} // namespace

View file

@ -16,53 +16,53 @@ License. See the file "COPYING" for the exact licensing terms.
namespace KWinInternal
{
void FadeOutEffect::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time )
void FadeOutEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
{
if( windows.contains( w->window()))
if( windows.contains( w ))
{
windows[ w->window() ] -= time / 1000.; // complete change in 1000ms
if( windows[ w->window() ] > 0 )
windows[ w ] -= time / 1000.; // complete change in 1000ms
if( windows[ w ] > 0 )
{
*mask |= Scene::PAINT_WINDOW_TRANSLUCENT;
*mask &= ~( Scene::PAINT_WINDOW_OPAQUE | Scene::PAINT_WINDOW_DISABLED );
}
else
{
windows.remove( w->window());
windows.remove( w );
static_cast< Deleted* >( w->window())->unrefWindow();
}
}
effects->prePaintWindow( w, mask, region, time );
}
void FadeOutEffect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
void FadeOutEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
if( windows.contains( w->window()))
if( windows.contains( w ))
{
data.opacity *= windows[ w->window()];
data.opacity *= windows[ w ];
}
effects->paintWindow( w, mask, region, data );
}
void FadeOutEffect::postPaintWindow( Scene::Window* w )
void FadeOutEffect::postPaintWindow( EffectWindow* w )
{
if( windows.contains( w->window()))
if( windows.contains( w ))
w->window()->addDamageFull(); // trigger next animation repaint
effects->postPaintWindow( w );
}
void FadeOutEffect::windowClosed( Toplevel* c, Deleted* d )
void FadeOutEffect::windowClosed( EffectWindow* c )
{
Client* cc = dynamic_cast< Client* >( c );
Client* cc = dynamic_cast< Client* >( c->window());
if( cc == NULL || cc->isOnCurrentDesktop())
{
windows[ d ] = 1; // count down to 0
d->addDamageFull();
d->refWindow();
windows[ c ] = 1; // count down to 0
c->window()->addDamageFull();
static_cast< Deleted* >( c->window())->refWindow();
}
}
void FadeOutEffect::windowDeleted( Deleted* c )
void FadeOutEffect::windowDeleted( EffectWindow* c )
{
windows.remove( c );
}

View file

@ -22,14 +22,14 @@ class FadeOutEffect
: public Effect
{
public:
virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time );
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
virtual void postPaintWindow( Scene::Window* w );
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, 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
virtual void windowClosed( Toplevel* c, Deleted* d );
virtual void windowDeleted( Deleted* c );
virtual void windowClosed( EffectWindow* c );
virtual void windowDeleted( EffectWindow* c );
private:
QMap< const Toplevel*, double > windows;
QMap< const EffectWindow*, double > windows;
};
} // namespace

View file

@ -38,13 +38,10 @@ 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( Scene::Window* w, int* mask, QRegion* region, int time )
void HowtoEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
{
// Is this window the one that is going to be faded out and in again?
// Note that since the effects framework is still work in progress, the window()
// function is used to access internal class Toplevel. The plan is to hide away
// internal classes and have only API for effects.
if( w->window() == fade_window )
if( w == fade_window )
{
// Simply add the time to the total progress. The value of progress will be used
// to determine how far in effect is.
@ -79,10 +76,10 @@ void HowtoEffect::prePaintWindow( Scene::Window* w, int* mask, QRegion* region,
// then special care needs to be taken, because the region may be infiniteRegion(), meaning
// everything needs to be painted
// data - painting data that can be modified to do some simple transformations
void HowtoEffect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
void HowtoEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
// Is this the window to be faded out and in again?
if( w->window() == fade_window )
if( w == fade_window )
{
// This effect, after a window has been activated, fades it out to only 50% transparency
// and then fades it in again to be fully opaque (assuming it's otherwise a fully opaque
@ -112,12 +109,14 @@ void HowtoEffect::paintWindow( Scene::Window* w, int mask, QRegion region, Windo
// The function that is called after the painting pass is finished. When an animation is going on,
// it can damage some areas so that the next painting pass has to repaint them again.
void HowtoEffect::postPaintWindow( Scene::Window* w )
void HowtoEffect::postPaintWindow( EffectWindow* w )
{
// Is this the window to be faded out and in again?
if( w->window() == fade_window )
if( w == fade_window )
{
// Damage the whole window, this will cause it to be repainted the next painting pass.
// Currently the API for effects is not complete, so for now window() is used to access
// internal class Toplevel. This should change in the future.
w->window()->addDamageFull(); // trigger next animation repaint
}
// Call the next effect.
@ -125,7 +124,7 @@ void HowtoEffect::postPaintWindow( Scene::Window* w )
}
// This function is called when a new window becomes active.
void HowtoEffect::windowActivated( Toplevel* c )
void HowtoEffect::windowActivated( EffectWindow* c )
{
// Set the window to be faded (or NULL if no window is active).
fade_window = c;
@ -134,21 +133,14 @@ void HowtoEffect::windowActivated( Toplevel* c )
// If there is a window to be faded, reset the progress to zero.
progress = 0;
// And damage the window so that it needs to be repainted.
c->addDamageFull();
c->window()->addDamageFull();
}
}
// TODO
void HowtoEffect::windowClosed( Toplevel* c, Deleted* d )
// This function is called when a window is closed.
void HowtoEffect::windowClosed( EffectWindow* c )
{
if( fade_window == c )
fade_window = d;
}
// This function is called when a window is destroyed.
void HowtoEffect::windowDeleted( Deleted* c )
{
// If the window to be faded out and in is destroyed, just reset the pointer.
// If the window to be faded out and in is closed, just reset the pointer.
// This effect then will do nothing and just call the next effect.
if( fade_window == c )
fade_window = NULL;

View file

@ -38,30 +38,27 @@ class HowtoEffect
// A pre-paint function. It tells the compositing code how the painting will
// be affected by this effect.
virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time );
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
// A paint function. It actually performs the modifications to the painting.
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
// A post-paint function. It can be used for cleanups after painting, but with animations
// it is also used to trigger repaints during the next painting pass by manually "damaging"
// areas of the window.
virtual void postPaintWindow( Scene::Window* w );
virtual void postPaintWindow( EffectWindow* w );
// Notification functions: These inform the effect about changes such as a new window
// being activated.
// TODO
virtual void windowClosed( Toplevel* c, Deleted* d );
// The given window has been deleted (destroyed).
virtual void windowDeleted( Deleted* c );
// The given window has been closed.
virtual void windowClosed( EffectWindow* c );
// The given window has been activated.
virtual void windowActivated( Toplevel* c );
virtual void windowActivated( EffectWindow* c );
private:
// The window that will be faded out and in again.
Toplevel* fade_window;
EffectWindow* fade_window;
// The progress of the fading.
int progress;

View file

@ -15,7 +15,7 @@ License. See the file "COPYING" for the exact licensing terms.
namespace KWinInternal
{
void MakeTransparentEffect::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time )
void MakeTransparentEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
{
const Client* c = dynamic_cast< const Client* >( w->window());
if(( c != NULL && ( c->isMove() || c->isResize())) || w->window()->isDialog())
@ -26,7 +26,7 @@ void MakeTransparentEffect::prePaintWindow( Scene::Window* w, int* mask, QRegion
effects->prePaintWindow( w, mask, region, time );
}
void MakeTransparentEffect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
void MakeTransparentEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
const Client* c = dynamic_cast< const Client* >( w->window());
if( w->window()->isDialog())
@ -36,10 +36,10 @@ void MakeTransparentEffect::paintWindow( Scene::Window* w, int mask, QRegion reg
effects->paintWindow( w, mask, region, data );
}
void MakeTransparentEffect::windowUserMovedResized( Toplevel* c, bool first, bool last )
void MakeTransparentEffect::windowUserMovedResized( EffectWindow* c, bool first, bool last )
{
if( first || last )
c->addDamageFull();
c->window()->addDamageFull();
}
} // namespace

View file

@ -22,9 +22,9 @@ class MakeTransparentEffect
: public Effect
{
public:
virtual void windowUserMovedResized( Toplevel* c, bool first, bool last );
virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time );
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
virtual void windowUserMovedResized( EffectWindow* c, bool first, bool last );
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
};
} // namespace

View file

@ -64,7 +64,7 @@ void PresentWindowsEffect::prePaintScreen( int* mask, QRegion* region, int time
effects->prePaintScreen(mask, region, time);
}
void PresentWindowsEffect::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time )
void PresentWindowsEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
{
if( mActiveness > 0.0f && mWindowData.contains(w->window()) )
// This window will be transformed by the effect
@ -73,7 +73,7 @@ void PresentWindowsEffect::prePaintWindow( Scene::Window* w, int* mask, QRegion*
effects->prePaintWindow( w, mask, region, time );
}
void PresentWindowsEffect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
void PresentWindowsEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
if(mActiveness > 0.0f && mWindowData.contains(w->window()))
{
@ -116,9 +116,9 @@ void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent* e )
{
if( it.value().area.contains(pos) )
{
effects->activateWindow( (Client*)it.key() ); // All keys of mWindowData are Clients anyway
effects->activateWindow( it.key()->effectWindow());
// Prevent re-minimizing when the effect terminates
mTemporarilyUnminimized.removeAll( (Client*)it.key() );
mTemporarilyUnminimized.removeAll( static_cast< Client* >(it.key()));
}
}
@ -126,12 +126,12 @@ void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent* e )
setActive(false);
}
void PresentWindowsEffect::windowActivated( Toplevel* t )
void PresentWindowsEffect::windowActivated( EffectWindow* )
{
rearrangeWindows();
}
void PresentWindowsEffect::windowClosed( Toplevel* t, Deleted* )
void PresentWindowsEffect::windowClosed( EffectWindow* )
{
rearrangeWindows();
}

View file

@ -31,12 +31,12 @@ class PresentWindowsEffect
virtual void prePaintScreen( int* mask, QRegion* region, int time );
virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time );
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time );
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
virtual void postPaintScreen();
virtual void windowClosed( Toplevel* c, Deleted* );
virtual void windowActivated( Toplevel* c );
virtual void windowClosed( EffectWindow* c );
virtual void windowActivated( EffectWindow* c );
virtual void windowInputMouseEvent( Window w, QEvent* e );
public slots:

View file

@ -23,49 +23,49 @@ void ScaleInEffect::prePaintScreen( int* mask, QRegion* region, int time )
effects->prePaintScreen( mask, region, time );
}
void ScaleInEffect::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time )
void ScaleInEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
{
if( windows.contains( w->window()))
if( windows.contains( w ))
{
windows[ w->window() ] += time / 500.; // complete change in 500ms
if( windows[ w->window() ] < 1 )
windows[ w ] += time / 500.; // complete change in 500ms
if( windows[ w ] < 1 )
*mask |= Scene::PAINT_WINDOW_TRANSFORMED;
else
windows.remove( w->window());
windows.remove( w );
}
effects->prePaintWindow( w, mask, region, time );
}
void ScaleInEffect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
void ScaleInEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
if( windows.contains( w->window()))
if( windows.contains( w ))
{
data.xScale *= windows[ w->window()];
data.yScale *= windows[ w->window()];
data.xTranslate += int( w->window()->width() / 2 * ( 1 - windows[ w->window()] ));
data.yTranslate += int( w->window()->height() / 2 * ( 1 - windows[ w->window()] ));
data.xScale *= windows[ w ];
data.yScale *= windows[ w ];
data.xTranslate += int( w->window()->width() / 2 * ( 1 - windows[ w ] ));
data.yTranslate += int( w->window()->height() / 2 * ( 1 - windows[ w ] ));
}
effects->paintWindow( w, mask, region, data );
}
void ScaleInEffect::postPaintWindow( Scene::Window* w )
void ScaleInEffect::postPaintWindow( EffectWindow* w )
{
if( windows.contains( w->window()))
if( windows.contains( w ))
w->window()->addDamageFull(); // trigger next animation repaint
effects->postPaintWindow( w );
}
void ScaleInEffect::windowAdded( Toplevel* c )
void ScaleInEffect::windowAdded( EffectWindow* c )
{
Client* cc = dynamic_cast< Client* >( c );
Client* cc = dynamic_cast< Client* >( c->window());
if( cc == NULL || cc->isOnCurrentDesktop())
{
windows[ c ] = 0;
c->addDamageFull();
c->window()->addDamageFull();
}
}
void ScaleInEffect::windowClosed( Toplevel* c, Deleted* )
void ScaleInEffect::windowClosed( EffectWindow* c )
{
windows.remove( c );
}

View file

@ -23,14 +23,14 @@ class ScaleInEffect
{
public:
virtual void prePaintScreen( int* mask, QRegion* region, int time );
virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time );
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
virtual void postPaintWindow( Scene::Window* w );
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, 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
virtual void windowAdded( Toplevel* c );
virtual void windowClosed( Toplevel* c, Deleted* );
virtual void windowAdded( EffectWindow* c );
virtual void windowClosed( EffectWindow* c );
private:
QMap< const Toplevel*, double > windows;
QMap< const EffectWindow*, double > windows;
};
} // namespace

View file

@ -30,21 +30,21 @@ void ShakyMoveEffect::prePaintScreen( int* mask, QRegion* region, int time )
effects->prePaintScreen( mask, region, time );
}
void ShakyMoveEffect::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time )
void ShakyMoveEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time )
{
if( windows.contains( w->window()))
if( windows.contains( w ))
*mask |= Scene::PAINT_WINDOW_TRANSFORMED;
effects->prePaintWindow( w, mask, region, time );
}
void ShakyMoveEffect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
void ShakyMoveEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
if( windows.contains( w->window()))
data.xTranslate += shaky_diff[ windows[ w->window() ]];
if( windows.contains( w ))
data.xTranslate += shaky_diff[ windows[ w ]];
effects->paintWindow( w, mask, region, data );
}
void ShakyMoveEffect::windowUserMovedResized( Toplevel* c, bool first, bool last )
void ShakyMoveEffect::windowUserMovedResized( EffectWindow* c, bool first, bool last )
{
if( first )
{
@ -56,13 +56,13 @@ void ShakyMoveEffect::windowUserMovedResized( Toplevel* c, bool first, bool last
{
windows.remove( c );
// just damage whole screen, transformation is involved
c->workspace()->addDamageFull();
c->window()->workspace()->addDamageFull();
if( windows.isEmpty())
timer.stop();
}
}
void ShakyMoveEffect::windowClosed( Toplevel* c, Deleted* )
void ShakyMoveEffect::windowClosed( EffectWindow* c )
{
windows.remove( c );
if( windows.isEmpty())
@ -72,7 +72,7 @@ void ShakyMoveEffect::windowClosed( Toplevel* c, Deleted* )
// TODO use time provided with prePaintWindow() instead
void ShakyMoveEffect::tick()
{
for( QMap< const Toplevel*, int >::Iterator it = windows.begin();
for( QMap< const EffectWindow*, int >::Iterator it = windows.begin();
it != windows.end();
++it )
{
@ -81,7 +81,7 @@ void ShakyMoveEffect::tick()
else
++(*it);
// just damage whole screen, transformation is involved
it.key()->workspace()->addDamageFull();
it.key()->window()->workspace()->addDamageFull();
}
}

View file

@ -26,15 +26,15 @@ class ShakyMoveEffect
Q_OBJECT
public:
ShakyMoveEffect();
virtual void windowUserMovedResized( Toplevel* c, bool first, bool last );
virtual void prePaintScreen( int* mask, QRegion* region, int time );
virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time );
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
virtual void windowClosed( Toplevel* c, Deleted* );
virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, 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 );
private slots:
void tick();
private:
QMap< const Toplevel*, int > windows;
QMap< const EffectWindow*, int > windows;
QTimer timer;
};

View file

@ -61,7 +61,7 @@ void TestInputEffect::windowInputMouseEvent( Window w, QEvent* e )
if( c->isShown( true ) && c->isOnCurrentDesktop()
&& c->geometry().contains( pos ))
{
effects->activateWindow( c );
effects->activateWindow( c->effectWindow());
return;
}
}

View file

@ -28,6 +28,7 @@ License. See the file "COPYING" for the exact licensing terms.
#include "notifications.h"
#include "geometrytip.h"
#include "rules.h"
#include "effects.h"
#include <QX11Info>
#include <QDesktopWidget>
@ -45,6 +46,11 @@ void Workspace::desktopResized()
{
updateClientArea();
checkElectricBorders( true );
if( compositing() )
{
finishCompositing();
QTimer::singleShot( 0, this, SLOT( setupCompositing() ) );
}
}
/*!
@ -210,7 +216,7 @@ QRect Workspace::clientArea( clientAreaOption opt, const QPoint& p, int desktop
if( desktop == NETWinInfo::OnAllDesktops || desktop == 0 )
desktop = currentDesktop();
QDesktopWidget *desktopwidget = KApplication::desktop();
int screen = desktopwidget->isVirtualDesktop() ? desktopwidget->screenNumber( p ) : desktopwidget->primaryScreen();
int screen = desktopwidget->screenNumber( p );
if( screen < 0 )
screen = desktopwidget->primaryScreen();
QRect sarea = screenarea // may be NULL during KWin initialization
@ -1404,7 +1410,7 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
|| ns != size())
{
QRect orig_geometry = geometry();
GeometryUpdatesPostponer blocker( this );
GeometryUpdatesBlocker blocker( this );
move( new_pos );
plainResize( ns );
setGeometry( QRect( calculateGravitation( false, gravity ), size()));
@ -1437,7 +1443,7 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
if( ns != size()) // don't restore if some app sets its own size again
{
QRect orig_geometry = geometry();
GeometryUpdatesPostponer blocker( this );
GeometryUpdatesBlocker blocker( this );
int save_gravity = xSizeHint.win_gravity;
xSizeHint.win_gravity = gravity;
resizeWithChecks( ns );
@ -1657,31 +1663,40 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force )
{
client_size = QSize( w - border_left - border_right, h - border_top - border_bottom );
}
if( force == NormalGeometrySet && frame_geometry == QRect( x, y, w, h ))
if( force == NormalGeometrySet && geom == QRect( x, y, w, h ))
return;
frame_geometry = QRect( x, y, w, h );
geom = QRect( x, y, w, h );
updateWorkareaDiffs();
if( postpone_geometry_updates != 0 )
if( block_geometry_updates != 0 )
{
pending_geometry_update = true;
return;
}
resizeDecoration( QSize( w, h ));
XMoveResizeWindow( display(), frameId(), x, y, w, h );
// resizeDecoration( QSize( w, h ));
if( !isShade())
if( geom_before_block.size() != geom.size())
{
QSize cs = clientSize();
XMoveResizeWindow( display(), wrapperId(), clientPos().x(), clientPos().y(),
cs.width(), cs.height());
XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height());
resizeDecoration( QSize( w, h ));
XMoveResizeWindow( display(), frameId(), x, y, w, h );
if( !isShade())
{
QSize cs = clientSize();
XMoveResizeWindow( display(), wrapperId(), clientPos().x(), clientPos().y(),
cs.width(), cs.height());
XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height());
}
if( shape())
updateShape();
}
updateShape();
else
XMoveWindow( display(), frameId(), x, y );
// SELI TODO won't this be too expensive?
updateWorkareaDiffs();
sendSyntheticConfigureNotify();
updateWindowRules();
checkMaximizeGeometry();
if( geom_before_block.size() != geom.size())
addDamageFull(); // damage window only if it actually was a resize
workspace()->addDamage( geom_before_block ); // TODO add damage only if not obscured
geom_before_block = geom;
}
void Client::plainResize( int w, int h, ForceGeometry_t force )
@ -1711,11 +1726,11 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
kDebug() << "forced size fail:" << QSize( w,h ) << ":" << rules()->checkSize( QSize( w, h )) << endl;
kDebug() << kBacktrace() << endl;
}
if( force == NormalGeometrySet && frame_geometry.size() == QSize( w, h ))
if( force == NormalGeometrySet && geom.size() == QSize( w, h ))
return;
frame_geometry.setSize( QSize( w, h ));
geom.setSize( QSize( w, h ));
updateWorkareaDiffs();
if( postpone_geometry_updates != 0 )
if( block_geometry_updates != 0 )
{
pending_geometry_update = true;
return;
@ -1730,11 +1745,15 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
cs.width(), cs.height());
XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height());
}
updateShape();
if( shape())
updateShape();
updateWorkareaDiffs();
sendSyntheticConfigureNotify();
updateWindowRules();
checkMaximizeGeometry();
addDamageFull(); // TODO add damage only in added area?
workspace()->addDamage( geom_before_block ); // TODO add damage only if not obscured
geom_before_block = geom;
}
/*!
@ -1742,11 +1761,11 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
*/
void Client::move( int x, int y, ForceGeometry_t force )
{
if( force == NormalGeometrySet && frame_geometry.topLeft() == QPoint( x, y ))
if( force == NormalGeometrySet && geom.topLeft() == QPoint( x, y ))
return;
frame_geometry.moveTopLeft( QPoint( x, y ));
geom.moveTopLeft( QPoint( x, y ));
updateWorkareaDiffs();
if( postpone_geometry_updates != 0 )
if( block_geometry_updates != 0 )
{
pending_geometry_update = true;
return;
@ -1755,20 +1774,22 @@ void Client::move( int x, int y, ForceGeometry_t force )
sendSyntheticConfigureNotify();
updateWindowRules();
checkMaximizeGeometry();
// client itself is not damaged
workspace()->addDamage( geom_before_block ); // TODO add damage only if not obscured
geom_before_block = geom;
}
void Client::postponeGeometryUpdates( bool postpone )
void Client::blockGeometryUpdates( bool block )
{
if( postpone )
if( block )
{
if( postpone_geometry_updates == 0 )
if( block_geometry_updates == 0 )
pending_geometry_update = false;
++postpone_geometry_updates;
++block_geometry_updates;
}
else
{
if( --postpone_geometry_updates == 0 )
if( --block_geometry_updates == 0 )
{
if( pending_geometry_update )
{
@ -1817,7 +1838,7 @@ void Client::changeMaximize( bool vertical, bool horizontal, bool adjust )
if( !adjust && max_mode == old_mode )
return;
GeometryUpdatesPostponer blocker( this );
GeometryUpdatesBlocker blocker( this );
// maximing one way and unmaximizing the other way shouldn't happen
Q_ASSERT( !( vertical && horizontal )
@ -2069,7 +2090,7 @@ void Client::setFullScreen( bool set, bool user )
if( was_fs == isFullScreen())
return;
StackingUpdatesBlocker blocker1( workspace());
GeometryUpdatesPostponer blocker2( this );
GeometryUpdatesBlocker blocker2( this );
workspace()->updateClientLayer( this ); // active fullscreens get different layer
info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen );
updateDecoration( false, false );
@ -2225,7 +2246,7 @@ bool Client::startMoveResize()
XMapRaised( display(), move_resize_grab_window );
if( XGrabPointer( display(), move_resize_grab_window, False,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask,
GrabModeAsync, GrabModeAsync, move_resize_grab_window, cursor.handle(), xTime() ) == Success )
GrabModeAsync, GrabModeAsync, None, cursor.handle(), xTime() ) == Success )
has_grab = true;
if( XGrabKeyboard( display(), frameId(), False, GrabModeAsync, GrabModeAsync, xTime() ) == Success )
has_grab = true;
@ -2255,6 +2276,8 @@ bool Client::startMoveResize()
// not needed anymore? kapp->installEventFilter( eater );
}
Notify::raise( isResize() ? Notify::ResizeStart : Notify::MoveStart );
if( effects )
effects->windowUserMovedResized( effectWindow(), true, false );
return true;
}
@ -2268,6 +2291,8 @@ void Client::finishMoveResize( bool cancel )
checkMaximizeGeometry();
// FRAME update();
Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd );
if( effects )
effects->windowUserMovedResized( effectWindow(), false, true );
}
void Client::leaveMoveResize()
@ -2531,7 +2556,8 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root )
}
if ( isMove() )
workspace()->clientMoved(globalPos, xTime());
if( effects )
effects->windowUserMovedResized( effectWindow(), false, false );
}
} // namespace

View file

@ -113,7 +113,7 @@ void Scene::paintScreen( int* mask, QRegion* region )
effects->paintScreen( *mask, *region, data );
effects->postPaintScreen();
foreach( Window* w, stacking_order )
effects->postPaintWindow( w );
effects->postPaintWindow( effectWindow( w ));
}
// Compute time since the last painting pass.
@ -161,7 +161,7 @@ void Scene::paintGenericScreen( int orig_mask, ScreenPaintData )
mask |= PAINT_WINDOW_DISABLED;
QRegion damage = infiniteRegion();
// preparation step
effects->prePaintWindow( w, &mask, &damage, time_diff );
effects->prePaintWindow( effectWindow( w ), &mask, &damage, time_diff );
if( mask & PAINT_WINDOW_DISABLED )
continue;
paintWindow( w, mask, damage );
@ -192,7 +192,7 @@ void Scene::paintSimpleScreen( int orig_mask, QRegion region )
mask |= PAINT_WINDOW_DISABLED;
QRegion damage = region;
// preparation step
effects->prePaintWindow( w, &mask, &damage, time_diff );
effects->prePaintWindow( effectWindow( w ), &mask, &damage, time_diff );
if( mask & PAINT_WINDOW_DISABLED )
continue;
// If the window is transparent, the transparent part will be done
@ -223,13 +223,13 @@ void Scene::paintWindow( Window* w, int mask, QRegion region )
{
WindowPaintData data;
data.opacity = w->window()->opacity();
effects->paintWindow( w, mask, region, data );
effects->paintWindow( effectWindow( w ), mask, region, data );
}
// the function that'll be eventually called by paintWindow() above
void Scene::finalPaintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
void Scene::finalPaintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
w->performPaint( mask, region, data );
w->sceneWindow()->performPaint( mask, region, data );
}
//****************************************

View file

@ -23,6 +23,7 @@ class Workspace;
class Deleted;
class WindowPaintData;
class ScreenPaintData;
class EffectWindow;
// The base class for compositing backends.
class Scene
@ -83,7 +84,7 @@ class Scene
// paint the background (not the desktop background - the whole background)
virtual void paintBackground( QRegion region ) = 0;
// called after all effects had their paintWindow() called
void finalPaintWindow( Window* w, int mask, QRegion region, WindowPaintData& data );
void finalPaintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
// shared implementation, starts painting the window
virtual void paintWindow( Window* w, int mask, QRegion region );
// infinite region, i.e. everything

View file

@ -173,7 +173,7 @@ void SceneXrender::paintTransformedScreen( int orig_mask )
int mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT );
QRegion damage = region;
// preparation step
effects->prePaintWindow( w, &mask, &damage, time_diff );
effects->prePaintWindow( effectWindow( w ), &mask, &damage, time_diff );
// If the window is transparent, the transparent part will be done
// in the 2nd pass.
if( mask & PAINT_WINDOW_TRANSLUCENT )

View file

@ -10,6 +10,8 @@ License. See the file "COPYING" for the exact licensing terms.
#include "toplevel.h"
#include "effects.h"
namespace KWinInternal
{
@ -20,6 +22,7 @@ Toplevel::Toplevel( Workspace* ws )
, window_pix( None )
, damage_handle( None )
, is_shape( false )
, effect_window( NULL )
{
}
@ -91,6 +94,10 @@ void Toplevel::copyToDeleted( Toplevel* c )
damage_handle = None;
damage_region = c->damage_region;
is_shape = c->is_shape;
// reassign the representation for Effect classes
effect_window = c->effect_window;
effect_window->setWindow( this );
c->effect_window = NULL;
}
} // namespace

View file

@ -21,6 +21,7 @@ namespace KWinInternal
{
class Workspace;
class EffectWindow;
class Toplevel
: public QObject, public KDecorationDefines
@ -65,6 +66,7 @@ class Toplevel
void addDamageFull();
QRegion damage() const;
void resetDamage( const QRect& r );
EffectWindow* effectWindow();
protected:
virtual ~Toplevel();
@ -87,6 +89,7 @@ class Toplevel
Damage damage_handle;
QRegion damage_region;
bool is_shape;
EffectWindow* effect_window;
};
inline Window Toplevel::handle() const
@ -222,6 +225,12 @@ inline bool Toplevel::hasAlpha() const
return depth() == 32;
}
inline
EffectWindow* Toplevel::effectWindow()
{
return effect_window;
}
#ifdef NDEBUG
inline
kndbgstream& operator<<( kndbgstream& stream, const Toplevel* ) { return stream; }

View file

@ -74,7 +74,7 @@ void Unmanaged::release()
if( effects )
{
Deleted* del = Deleted::create( this );
effects->windowClosed( this, del );
effects->windowClosed( del->effectWindow()); // effectWindow is already 'del'
scene->windowClosed( this, del );
del->unrefWindow();
}

View file

@ -44,6 +44,7 @@ License. See the file "COPYING" for the exact licensing terms.
#include "kwinadaptor.h"
#include "unmanaged.h"
#include "scene.h"
#include "deleted.h"
#include "effects.h"
#include <X11/extensions/shape.h>
@ -498,7 +499,7 @@ Client* Workspace::createClient( Window w, bool is_mapped )
if( scene )
scene->windowAdded( c );
if( effects )
effects->windowAdded( c );
effects->windowAdded( c->effectWindow());
return c;
}
@ -516,7 +517,7 @@ Unmanaged* Workspace::createUnmanaged( Window w )
if( scene )
scene->windowAdded( c );
if( effects )
effects->windowAdded( c );
effects->windowAdded( c->effectWindow());
return c;
}
@ -636,7 +637,7 @@ void Workspace::removeDeleted( Deleted* c, allowed_t )
if( scene )
scene->windowDeleted( c );
if( effects )
effects->windowDeleted( c );
effects->windowDeleted( c->effectWindow());
deleted.removeAll( c );
}