When the number of presented windows changes, do the rearranging smoothly.
Also rearrange only if the size of the grid would change. svn path=/branches/work/kwin_composite/; revision=654209icc-effect-5.14.5
parent
b65e6affd9
commit
894d08a522
|
@ -30,6 +30,7 @@ PresentWindowsEffect::PresentWindowsEffect()
|
||||||
: mShowWindowsFromAllDesktops ( false )
|
: mShowWindowsFromAllDesktops ( false )
|
||||||
, mActivated( false )
|
, mActivated( false )
|
||||||
, mActiveness( 0.0 )
|
, mActiveness( 0.0 )
|
||||||
|
, mRearranging( 1.0 )
|
||||||
, mHoverWindow( NULL )
|
, mHoverWindow( NULL )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -62,7 +63,11 @@ void PresentWindowsEffect::prePaintScreen( int* mask, QRegion* region, int time
|
||||||
// How long does it take for the effect to get it's full strength (in ms)
|
// How long does it take for the effect to get it's full strength (in ms)
|
||||||
const float changeTime = 300;
|
const float changeTime = 300;
|
||||||
if(mActivated)
|
if(mActivated)
|
||||||
|
{
|
||||||
mActiveness = qMin(1.0f, mActiveness + time/changeTime);
|
mActiveness = qMin(1.0f, mActiveness + time/changeTime);
|
||||||
|
if( mRearranging < 1 )
|
||||||
|
mRearranging = qMin(1.0f, mRearranging + time/changeTime);
|
||||||
|
}
|
||||||
else if(mActiveness > 0.0f)
|
else if(mActiveness > 0.0f)
|
||||||
{
|
{
|
||||||
mActiveness = qMax(0.0f, mActiveness - time/changeTime);
|
mActiveness = qMax(0.0f, mActiveness - time/changeTime);
|
||||||
|
@ -112,10 +117,22 @@ void PresentWindowsEffect::paintWindow( EffectWindow* w, int mask, QRegion regio
|
||||||
{
|
{
|
||||||
// Change window's position and scale
|
// Change window's position and scale
|
||||||
const WindowData& windata = mWindowData[w];
|
const WindowData& windata = mWindowData[w];
|
||||||
data.xScale = interpolate(data.xScale, windata.scale, mActiveness);
|
if( mRearranging < 1 ) // rearranging
|
||||||
data.yScale = interpolate(data.xScale, windata.scale, mActiveness);
|
{
|
||||||
data.xTranslate = (int)interpolate(data.xTranslate, windata.area.left() - w->x(), mActiveness);
|
data.xScale = interpolate(windata.old_scale, windata.scale, mRearranging);
|
||||||
data.yTranslate = (int)interpolate(data.yTranslate, windata.area.top() - w->y(), mActiveness);
|
data.yScale = interpolate(windata.old_scale, windata.scale, mRearranging);
|
||||||
|
data.xTranslate = (int)interpolate(windata.old_area.left() - w->x(),
|
||||||
|
windata.area.left() - w->x(), mRearranging);
|
||||||
|
data.yTranslate = (int)interpolate(windata.old_area.top() - w->y(),
|
||||||
|
windata.area.top() - w->y(), mRearranging);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.xScale = interpolate(data.xScale, windata.scale, mActiveness);
|
||||||
|
data.yScale = interpolate(data.xScale, windata.scale, mActiveness);
|
||||||
|
data.xTranslate = (int)interpolate(data.xTranslate, windata.area.left() - w->x(), mActiveness);
|
||||||
|
data.yTranslate = (int)interpolate(data.yTranslate, windata.area.top() - w->y(), mActiveness);
|
||||||
|
}
|
||||||
// Darken all windows except for the one under the cursor
|
// Darken all windows except for the one under the cursor
|
||||||
data.brightness *= interpolate(1.0, 0.7, mActiveness * (1.0f - windata.hover));
|
data.brightness *= interpolate(1.0, 0.7, mActiveness * (1.0f - windata.hover));
|
||||||
// If it's minimized window or on another desktop and effect is not
|
// If it's minimized window or on another desktop and effect is not
|
||||||
|
@ -132,6 +149,8 @@ void PresentWindowsEffect::postPaintScreen()
|
||||||
{
|
{
|
||||||
if( mActivated && mActiveness < 1.0 ) // activating effect
|
if( mActivated && mActiveness < 1.0 ) // activating effect
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
|
if( mActivated && mRearranging < 1.0 ) // rearranging
|
||||||
|
effects->addRepaintFull();
|
||||||
if( !mActivated && mActiveness > 0.0 ) // deactivating effect
|
if( !mActivated && mActiveness > 0.0 ) // deactivating effect
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
foreach( const WindowData& d, mWindowData )
|
foreach( const WindowData& d, mWindowData )
|
||||||
|
@ -207,6 +226,9 @@ void PresentWindowsEffect::setActive(bool active)
|
||||||
mHoverWindow = NULL;
|
mHoverWindow = NULL;
|
||||||
if( mActivated )
|
if( mActivated )
|
||||||
{
|
{
|
||||||
|
mWindowData.clear();
|
||||||
|
effectActivated();
|
||||||
|
mActiveness = 0;
|
||||||
mWindowsToPresent.clear();
|
mWindowsToPresent.clear();
|
||||||
const EffectWindowList& originalwindowlist = effects->stackingOrder();
|
const EffectWindowList& originalwindowlist = effects->stackingOrder();
|
||||||
// Filter out special windows such as panels and taskbars
|
// Filter out special windows such as panels and taskbars
|
||||||
|
@ -220,12 +242,14 @@ void PresentWindowsEffect::setActive(bool active)
|
||||||
continue;
|
continue;
|
||||||
mWindowsToPresent.append(window);
|
mWindowsToPresent.append(window);
|
||||||
}
|
}
|
||||||
|
rearrangeWindows();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
mWindowsToPresent.clear();
|
mWindowsToPresent.clear();
|
||||||
rearrangeWindows();
|
mRearranging = 1; // turn off
|
||||||
if( mActivated && mActiveness == 0.0f )
|
mActiveness = 1; // go back from arranged position
|
||||||
effectActivated();
|
}
|
||||||
effects->addRepaintFull(); // trigger next animation repaint
|
effects->addRepaintFull(); // trigger next animation repaint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,9 +271,30 @@ void PresentWindowsEffect::rearrangeWindows()
|
||||||
if( !mActivated )
|
if( !mActivated )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mWindowData.clear();
|
|
||||||
|
|
||||||
EffectWindowList windowlist = mWindowsToPresent;
|
EffectWindowList windowlist = mWindowsToPresent;
|
||||||
|
|
||||||
|
if( !mWindowData.isEmpty()) // this is not first arranging
|
||||||
|
{
|
||||||
|
bool canrearrange = canRearrangeClosest( windowlist );
|
||||||
|
QHash<EffectWindow*, WindowData> newdata;
|
||||||
|
for( QHash<EffectWindow*, WindowData>::ConstIterator it = mWindowData.begin();
|
||||||
|
it != mWindowData.end();
|
||||||
|
++it )
|
||||||
|
if( windowlist.contains( it.key())) // remove windows that are not in the window list
|
||||||
|
newdata[ it.key() ] = *it;
|
||||||
|
mWindowData = newdata;
|
||||||
|
if( !canrearrange ) // canRearrange was called before adjusting the list, so that
|
||||||
|
return; // changes can be detected
|
||||||
|
for( QHash<EffectWindow*, WindowData>::Iterator it = mWindowData.begin();
|
||||||
|
it != mWindowData.end();
|
||||||
|
++it )
|
||||||
|
{
|
||||||
|
(*it).old_area = (*it).area;
|
||||||
|
(*it).old_scale = (*it).scale;
|
||||||
|
}
|
||||||
|
mRearranging = 0; // start animation again
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate new positions and scales for windows
|
// Calculate new positions and scales for windows
|
||||||
// calculateWindowTransformationsDumb( windowlist );
|
// calculateWindowTransformationsDumb( windowlist );
|
||||||
// calculateWindowTransformationsKompose( windowlist );
|
// calculateWindowTransformationsKompose( windowlist );
|
||||||
|
@ -453,12 +498,7 @@ void PresentWindowsEffect::calculateWindowTransformationsClosest(EffectWindowLis
|
||||||
int columns = int( ceil( sqrt( windowlist.count())));
|
int columns = int( ceil( sqrt( windowlist.count())));
|
||||||
int rows = int( ceil( windowlist.count() / double( columns )));
|
int rows = int( ceil( windowlist.count() / double( columns )));
|
||||||
foreach( EffectWindow* w, windowlist )
|
foreach( EffectWindow* w, windowlist )
|
||||||
{
|
mWindowData[ w ].slot = -1;
|
||||||
WindowData d;
|
|
||||||
d.slot = -1;
|
|
||||||
d.hover = 0; // other data will be computed later
|
|
||||||
mWindowData[ w ] = d;
|
|
||||||
}
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
// Assign each window to the closest available slot
|
// Assign each window to the closest available slot
|
||||||
|
@ -487,6 +527,7 @@ void PresentWindowsEffect::calculateWindowTransformationsClosest(EffectWindowLis
|
||||||
geom.adjust( 10, 10, -10, -10 ); // borders
|
geom.adjust( 10, 10, -10, -10 ); // borders
|
||||||
(*it).area = geom;
|
(*it).area = geom;
|
||||||
(*it).scale = geom.width() / float( it.key()->width());
|
(*it).scale = geom.width() / float( it.key()->width());
|
||||||
|
(*it).hover = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,6 +600,16 @@ void PresentWindowsEffect::getBestAssignments()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PresentWindowsEffect::canRearrangeClosest(EffectWindowList windowlist)
|
||||||
|
{
|
||||||
|
QRect area = effects->clientArea( PlacementArea, QPoint( 0, 0 ), effects->currentDesktop());
|
||||||
|
int columns = int( ceil( sqrt( windowlist.count())));
|
||||||
|
int rows = int( ceil( windowlist.count() / double( columns )));
|
||||||
|
int old_columns = int( ceil( sqrt( mWindowData.count())));
|
||||||
|
int old_rows = int( ceil( mWindowData.count() / double( columns )));
|
||||||
|
return old_columns != columns || old_rows != rows;
|
||||||
|
}
|
||||||
|
|
||||||
bool PresentWindowsEffect::borderActivated( ElectricBorder border )
|
bool PresentWindowsEffect::borderActivated( ElectricBorder border )
|
||||||
{
|
{
|
||||||
if( border == borderActivate && !mActivated )
|
if( border == borderActivate && !mActivated )
|
||||||
|
|
|
@ -50,6 +50,7 @@ class PresentWindowsEffect
|
||||||
void calculateWindowTransformationsDumb(EffectWindowList windowlist);
|
void calculateWindowTransformationsDumb(EffectWindowList windowlist);
|
||||||
void calculateWindowTransformationsKompose(EffectWindowList windowlist);
|
void calculateWindowTransformationsKompose(EffectWindowList windowlist);
|
||||||
void calculateWindowTransformationsClosest(EffectWindowList windowlist);
|
void calculateWindowTransformationsClosest(EffectWindowList windowlist);
|
||||||
|
bool canRearrangeClosest(EffectWindowList windowlist);
|
||||||
|
|
||||||
// Helper methods for layout calculation
|
// Helper methods for layout calculation
|
||||||
float windowAspectRatio(EffectWindow* c);
|
float windowAspectRatio(EffectWindow* c);
|
||||||
|
@ -71,6 +72,8 @@ class PresentWindowsEffect
|
||||||
bool mActivated;
|
bool mActivated;
|
||||||
// 0 = not active, 1 = fully active
|
// 0 = not active, 1 = fully active
|
||||||
float mActiveness;
|
float mActiveness;
|
||||||
|
// 0 = start of rearranging (old_area), 1 = done
|
||||||
|
float mRearranging;
|
||||||
|
|
||||||
Window mInput;
|
Window mInput;
|
||||||
|
|
||||||
|
@ -78,7 +81,9 @@ class PresentWindowsEffect
|
||||||
struct WindowData
|
struct WindowData
|
||||||
{
|
{
|
||||||
QRect area;
|
QRect area;
|
||||||
|
QRect old_area; // when rearranging, otherwise unset
|
||||||
float scale;
|
float scale;
|
||||||
|
float old_scale; // when rearranging, otherwise unset
|
||||||
float hover;
|
float hover;
|
||||||
int slot;
|
int slot;
|
||||||
int slot_distance;
|
int slot_distance;
|
||||||
|
|
Loading…
Reference in New Issue