Rework how window painting is disabled; now effects can indicate reasons they want particular windows painted or not.
This solves a few problems, but may need revisiting in the future. svn path=/branches/work/kwin_composite/; revision=632581
This commit is contained in:
parent
949aa1a778
commit
c16656d66d
10 changed files with 77 additions and 22 deletions
|
@ -161,7 +161,7 @@ Effects framework TODO
|
|||
which means that if an effect sets PAINT_WINDOW_TRANSFORMED it needs to set it
|
||||
also in prePaintScreen()
|
||||
|
||||
* PAINT_WINDOW_DISABLED turning off from effects needs some utility functions
|
||||
* PAINT_DISABLED turning off from effects needs some improvement
|
||||
- a window may have painting disabled for various reasons and their numbers may increase
|
||||
over time
|
||||
- so e.g. an effect showing minimized windows cannot simply turn off DISABLED
|
||||
|
|
10
effects.cpp
10
effects.cpp
|
@ -443,6 +443,16 @@ EffectWindow::EffectWindow()
|
|||
{
|
||||
}
|
||||
|
||||
void EffectWindow::enablePainting( int reason )
|
||||
{
|
||||
sceneWindow()->enablePainting( reason );
|
||||
}
|
||||
|
||||
void EffectWindow::disablePainting( int reason )
|
||||
{
|
||||
sceneWindow()->disablePainting( reason );
|
||||
}
|
||||
|
||||
int EffectWindow::desktop() const
|
||||
{
|
||||
return toplevel->desktop();
|
||||
|
|
|
@ -169,6 +169,8 @@ class EffectWindow
|
|||
EffectWindow();
|
||||
const Toplevel* window() const;
|
||||
Toplevel* window();
|
||||
void enablePainting( int reason );
|
||||
void disablePainting( int reason );
|
||||
bool isOnDesktop( int d ) const;
|
||||
bool isOnCurrentDesktop() const;
|
||||
bool isOnAllDesktops() const;
|
||||
|
|
|
@ -40,9 +40,9 @@ void DesktopChangeSlideEffect::prePaintWindow( EffectWindow* w, int* mask, QRegi
|
|||
if( painting_old_desktop )
|
||||
{
|
||||
if( w->isOnDesktop( old_desktop ) && !w->isOnCurrentDesktop())
|
||||
*mask &= ~Scene::PAINT_WINDOW_DISABLED; // paint windows on old desktop
|
||||
w->enablePainting( Scene::Window::PAINT_DISABLED_BY_DESKTOP );
|
||||
else
|
||||
*mask |= Scene::PAINT_WINDOW_DISABLED;
|
||||
w->disablePainting( Scene::Window::PAINT_DISABLED_BY_DESKTOP );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -24,7 +24,8 @@ void FadeOutEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region,
|
|||
if( windows[ w ] > 0 )
|
||||
{
|
||||
*mask |= Scene::PAINT_WINDOW_TRANSLUCENT;
|
||||
*mask &= ~( Scene::PAINT_WINDOW_OPAQUE | Scene::PAINT_WINDOW_DISABLED );
|
||||
*mask &= ~Scene::PAINT_WINDOW_OPAQUE;
|
||||
w->enablePainting( Scene::Window::PAINT_DISABLED_BY_DELETE );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -62,7 +62,7 @@ void MinimizeAnimationEffect::prePaintWindow( EffectWindow* w, int* mask, QRegio
|
|||
{
|
||||
// We'll transform this window
|
||||
*mask |= Scene::PAINT_WINDOW_TRANSFORMED;
|
||||
*mask &= ~Scene::PAINT_WINDOW_DISABLED;
|
||||
w->enablePainting( Scene::Window::PAINT_DISABLED_BY_MINIMIZE );
|
||||
}
|
||||
else
|
||||
// Animation just finished
|
||||
|
|
|
@ -69,7 +69,7 @@ void PresentWindowsEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion*
|
|||
{
|
||||
// This window will be transformed by the effect
|
||||
*mask |= Scene::PAINT_WINDOW_TRANSFORMED;
|
||||
*mask &= ~Scene::PAINT_WINDOW_DISABLED;
|
||||
w->enablePainting( Scene::Window::PAINT_DISABLED_BY_MINIMIZE );
|
||||
// If it's minimized window and effect is not fully active, then apply
|
||||
// some transparency
|
||||
if( mActiveness < 1.0f && static_cast< Client* >( w->window() )->isMinimized() )
|
||||
|
|
40
scene.cpp
40
scene.cpp
|
@ -160,12 +160,11 @@ void Scene::paintGenericScreen( int orig_mask, ScreenPaintData )
|
|||
foreach( Window* w, stacking_order ) // bottom to top
|
||||
{
|
||||
int mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT );
|
||||
if( !w->isVisible())
|
||||
mask |= PAINT_WINDOW_DISABLED;
|
||||
w->resetPaintingEnabled();
|
||||
QRegion damage = infiniteRegion();
|
||||
// preparation step
|
||||
effects->prePaintWindow( effectWindow( w ), &mask, &damage, time_diff );
|
||||
if( mask & PAINT_WINDOW_DISABLED )
|
||||
if( !w->isPaintingEnabled())
|
||||
continue;
|
||||
paintWindow( w, mask, damage );
|
||||
}
|
||||
|
@ -191,12 +190,11 @@ void Scene::paintSimpleScreen( int orig_mask, QRegion region )
|
|||
if( region.isEmpty()) // completely clipped
|
||||
continue;
|
||||
int mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT );
|
||||
if( !w->isVisible())
|
||||
mask |= PAINT_WINDOW_DISABLED;
|
||||
w->resetPaintingEnabled();
|
||||
QRegion damage = region;
|
||||
// preparation step
|
||||
effects->prePaintWindow( effectWindow( w ), &mask, &damage, time_diff );
|
||||
if( mask & PAINT_WINDOW_DISABLED )
|
||||
if( !w->isPaintingEnabled())
|
||||
continue;
|
||||
// If the window is transparent, the transparent part will be done
|
||||
// in the 2nd pass.
|
||||
|
@ -243,6 +241,7 @@ void Scene::finalPaintWindow( EffectWindow* w, int mask, QRegion region, WindowP
|
|||
Scene::Window::Window( Toplevel * c )
|
||||
: toplevel( c )
|
||||
, filter( ImageFilterFast )
|
||||
, disable_painting( 0 )
|
||||
, shape_valid( false )
|
||||
{
|
||||
}
|
||||
|
@ -314,4 +313,33 @@ bool Scene::Window::isOpaque() const
|
|||
return toplevel->opacity() == 1.0 && !toplevel->hasAlpha();
|
||||
}
|
||||
|
||||
bool Scene::Window::isPaintingEnabled() const
|
||||
{
|
||||
return !disable_painting;
|
||||
}
|
||||
|
||||
void Scene::Window::resetPaintingEnabled()
|
||||
{
|
||||
disable_painting = 0;
|
||||
if( dynamic_cast< Deleted* >( toplevel ) != NULL )
|
||||
disable_painting |= PAINT_DISABLED_BY_DELETE;
|
||||
if( !toplevel->isOnCurrentDesktop())
|
||||
disable_painting |= PAINT_DISABLED_BY_DESKTOP;
|
||||
if( Client* c = dynamic_cast< Client* >( toplevel ))
|
||||
{
|
||||
if( c->isMinimized() )
|
||||
disable_painting |= PAINT_DISABLED_BY_MINIMIZE;
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::Window::enablePainting( int reason )
|
||||
{
|
||||
disable_painting &= ~reason;
|
||||
}
|
||||
|
||||
void Scene::Window::disablePainting( int reason )
|
||||
{
|
||||
disable_painting |= reason;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
29
scene.h
29
scene.h
|
@ -58,18 +58,15 @@ class Scene
|
|||
PAINT_WINDOW_TRANSLUCENT = 1 << 1,
|
||||
// Window will be painted with transformed geometry.
|
||||
PAINT_WINDOW_TRANSFORMED = 1 << 2,
|
||||
// When set, the window won't be painted (set by default
|
||||
// for hidden windows, can be unset in pre-paint).
|
||||
PAINT_WINDOW_DISABLED = 1 << 3,
|
||||
// Paint only a region of the screen (can be optimized, cannot
|
||||
// be used together with TRANSFORMED flags).
|
||||
PAINT_SCREEN_REGION = 1 << 4,
|
||||
PAINT_SCREEN_REGION = 1 << 3,
|
||||
// Whole screen will be painted with transformed geometry.
|
||||
PAINT_SCREEN_TRANSFORMED = 1 << 5,
|
||||
PAINT_SCREEN_TRANSFORMED = 1 << 4,
|
||||
// At least one window will be painted with transformed geometry.
|
||||
PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS = 1 << 6,
|
||||
PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS = 1 << 5,
|
||||
// Clear whole background as the very first step, without optimizing it
|
||||
PAINT_SCREEN_BACKGROUND_FIRST = 1 << 7
|
||||
PAINT_SCREEN_BACKGROUND_FIRST = 1 << 6
|
||||
};
|
||||
// types of filtering available
|
||||
enum ImageFilterType { ImageFilterFast, ImageFilterGood };
|
||||
|
@ -132,6 +129,23 @@ class Scene::Window
|
|||
// access to the internal window class
|
||||
// TODO eventually get rid of this
|
||||
Toplevel* window();
|
||||
// should the window be painted
|
||||
bool isPaintingEnabled() const;
|
||||
void resetPaintingEnabled();
|
||||
// Flags explaining why painting should be disabled
|
||||
enum
|
||||
{
|
||||
// Window will not be painted
|
||||
PAINT_DISABLED = 1 << 0,
|
||||
// Window will not be painted because it is deleted
|
||||
PAINT_DISABLED_BY_DELETE = 1 << 1,
|
||||
// Window will not be painted because of which desktop it's on
|
||||
PAINT_DISABLED_BY_DESKTOP = 1 << 2,
|
||||
// Window will not be painted because it is minimized
|
||||
PAINT_DISABLED_BY_MINIMIZE = 1 << 3,
|
||||
};
|
||||
void enablePainting( int reason );
|
||||
void disablePainting( int reason );
|
||||
// is the window visible at all
|
||||
bool isVisible() const;
|
||||
// is the window fully opaque
|
||||
|
@ -145,6 +159,7 @@ class Scene::Window
|
|||
Toplevel* toplevel;
|
||||
ImageFilterType filter;
|
||||
private:
|
||||
int disable_painting;
|
||||
mutable QRegion shape_region;
|
||||
mutable bool shape_valid;
|
||||
};
|
||||
|
|
|
@ -169,12 +169,11 @@ void SceneXrender::paintTransformedScreen( int orig_mask )
|
|||
if( region.isEmpty()) // completely clipped
|
||||
continue;
|
||||
int mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT );
|
||||
if( !w->isVisible())
|
||||
mask |= PAINT_WINDOW_DISABLED;
|
||||
w->resetPaintingEnabled();
|
||||
QRegion damage = region;
|
||||
// preparation step
|
||||
effects->prePaintWindow( effectWindow( w ), &mask, &damage, time_diff );
|
||||
if( mask & PAINT_WINDOW_DISABLED )
|
||||
if( !w->isPaintingEnabled())
|
||||
continue;
|
||||
// If the window is transparent, the transparent part will be done
|
||||
// in the 2nd pass.
|
||||
|
|
Loading…
Reference in a new issue