From 0ae5a772e73360e4ab5702ea6fc66b81004ef9c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Mon, 22 Jan 2007 22:57:22 +0000 Subject: [PATCH] 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 --- COMPOSITE_TODO | 7 +-- activation.cpp | 2 +- client.cpp | 8 +-- composite.cpp | 4 ++ effects.cpp | 47 ++++++++-------- effects.h | 108 +++++++++++++++++++++++++++++------- effects/dialogparent.cpp | 14 ++--- effects/dialogparent.h | 12 ++-- effects/fadein.cpp | 28 +++++----- effects/fadein.h | 12 ++-- effects/fadeout.cpp | 32 +++++------ effects/fadeout.h | 12 ++-- effects/howto.cpp | 34 +++++------- effects/howto.h | 17 +++--- effects/maketransparent.cpp | 8 +-- effects/maketransparent.h | 6 +- effects/presentwindows.cpp | 12 ++-- effects/presentwindows.h | 8 +-- effects/scalein.cpp | 34 ++++++------ effects/scalein.h | 12 ++-- effects/shakymove.cpp | 20 +++---- effects/shakymove.h | 10 ++-- effects/test_input.cpp | 2 +- geometry.cpp | 90 +++++++++++++++++++----------- scene.cpp | 12 ++-- scene.h | 3 +- scene_xrender.cpp | 2 +- toplevel.cpp | 7 +++ toplevel.h | 9 +++ unmanaged.cpp | 2 +- workspace.cpp | 7 ++- 31 files changed, 342 insertions(+), 239 deletions(-) diff --git a/COMPOSITE_TODO b/COMPOSITE_TODO index e5cab9c054..1b5c0bc0a3 100644 --- a/COMPOSITE_TODO +++ b/COMPOSITE_TODO @@ -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. diff --git a/activation.cpp b/activation.cpp index acab108b79..de5a08f63e 100644 --- a/activation.cpp +++ b/activation.cpp @@ -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; } diff --git a/client.cpp b/client.cpp index daab947696..fe437e6732 100644 --- a/client.cpp +++ b/client.cpp @@ -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; diff --git a/composite.cpp b/composite.cpp index 8229ae881c..abcf945891 100644 --- a/composite.cpp +++ b/composite.cpp @@ -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() diff --git a/effects.cpp b/effects.cpp index c4dd4ef363..6c5ce0f9e2 100644 --- a/effects.cpp +++ b/effects.cpp @@ -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; diff --git a/effects.h b/effects.h index 7b06a111ac..fb5eb44e70 100644 --- a/effects.h +++ b/effects.h @@ -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 diff --git a/effects/dialogparent.cpp b/effects/dialogparent.cpp index aa7614ea7f..5d80e2b5eb 100644 --- a/effects/dialogparent.cpp +++ b/effects/dialogparent.cpp @@ -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(t); + Client* c = qobject_cast(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(t); + Client* c = qobject_cast(t->window()); if ( c && c->isModal() ) { // c is a modal dialog diff --git a/effects/dialogparent.h b/effects/dialogparent.h index 43a19cb4f8..65f1e4a042 100644 --- a/effects/dialogparent.h +++ b/effects/dialogparent.h @@ -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 effectStrength; + QMap effectStrength; }; } // namespace diff --git a/effects/fadein.cpp b/effects/fadein.cpp index 083636eb79..9209ab71cb 100644 --- a/effects/fadein.cpp +++ b/effects/fadein.cpp @@ -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 ); } diff --git a/effects/fadein.h b/effects/fadein.h index 698b9d88e4..087fc5ccf7 100644 --- a/effects/fadein.h +++ b/effects/fadein.h @@ -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 diff --git a/effects/fadeout.cpp b/effects/fadeout.cpp index 5b8a4fed57..016fba62c8 100644 --- a/effects/fadeout.cpp +++ b/effects/fadeout.cpp @@ -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 ); } diff --git a/effects/fadeout.h b/effects/fadeout.h index ffb0303fbc..7e9ed8498d 100644 --- a/effects/fadeout.h +++ b/effects/fadeout.h @@ -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 diff --git a/effects/howto.cpp b/effects/howto.cpp index a518567eac..17535d1a3d 100644 --- a/effects/howto.cpp +++ b/effects/howto.cpp @@ -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; diff --git a/effects/howto.h b/effects/howto.h index 609543ad69..5fb774ee2d 100644 --- a/effects/howto.h +++ b/effects/howto.h @@ -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; diff --git a/effects/maketransparent.cpp b/effects/maketransparent.cpp index d0f587b053..8dfea11dab 100644 --- a/effects/maketransparent.cpp +++ b/effects/maketransparent.cpp @@ -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 diff --git a/effects/maketransparent.h b/effects/maketransparent.h index 67614b6d6f..49f25a1a09 100644 --- a/effects/maketransparent.h +++ b/effects/maketransparent.h @@ -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 diff --git a/effects/presentwindows.cpp b/effects/presentwindows.cpp index 8695202fc1..d2b662505e 100644 --- a/effects/presentwindows.cpp +++ b/effects/presentwindows.cpp @@ -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(); } diff --git a/effects/presentwindows.h b/effects/presentwindows.h index bf6a35363e..0ea2bb68d3 100644 --- a/effects/presentwindows.h +++ b/effects/presentwindows.h @@ -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: diff --git a/effects/scalein.cpp b/effects/scalein.cpp index 850a97dc43..a889b5645f 100644 --- a/effects/scalein.cpp +++ b/effects/scalein.cpp @@ -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 ); } diff --git a/effects/scalein.h b/effects/scalein.h index 8904bc85ed..9279e4f5aa 100644 --- a/effects/scalein.h +++ b/effects/scalein.h @@ -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 diff --git a/effects/shakymove.cpp b/effects/shakymove.cpp index a6f39fe644..cd7f3c5b83 100644 --- a/effects/shakymove.cpp +++ b/effects/shakymove.cpp @@ -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(); } } diff --git a/effects/shakymove.h b/effects/shakymove.h index 0def91d043..2bff92c0bb 100644 --- a/effects/shakymove.h +++ b/effects/shakymove.h @@ -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; }; diff --git a/effects/test_input.cpp b/effects/test_input.cpp index 26391e5810..c60dfccc8f 100644 --- a/effects/test_input.cpp +++ b/effects/test_input.cpp @@ -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; } } diff --git a/geometry.cpp b/geometry.cpp index 0fcac38485..b7715b3a4f 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -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 #include @@ -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 diff --git a/scene.cpp b/scene.cpp index d740ff0317..0ceda160a9 100644 --- a/scene.cpp +++ b/scene.cpp @@ -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 ); } //**************************************** diff --git a/scene.h b/scene.h index 7907e09547..5771e332b1 100644 --- a/scene.h +++ b/scene.h @@ -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 diff --git a/scene_xrender.cpp b/scene_xrender.cpp index 70f8691d6f..42a4c1768f 100644 --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -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 ) diff --git a/toplevel.cpp b/toplevel.cpp index 0343c2c1af..1822a45395 100644 --- a/toplevel.cpp +++ b/toplevel.cpp @@ -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 diff --git a/toplevel.h b/toplevel.h index 3bb658e212..a335225b29 100644 --- a/toplevel.h +++ b/toplevel.h @@ -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; } diff --git a/unmanaged.cpp b/unmanaged.cpp index 750862bff3..42eb529ab0 100644 --- a/unmanaged.cpp +++ b/unmanaged.cpp @@ -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(); } diff --git a/workspace.cpp b/workspace.cpp index 78cb793862..8b05175049 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -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 @@ -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 ); }