restrict animationeffect repaints
REVIEW: 103932
This commit is contained in:
parent
cd8e84f5f2
commit
590d9b42d8
8 changed files with 249 additions and 36 deletions
11
effects.cpp
11
effects.cpp
|
@ -152,6 +152,7 @@ void EffectsHandlerImpl::setupClientConnections(Client* c)
|
|||
connect(c, SIGNAL(clientMinimized(KWin::Client*,bool)), this, SLOT(slotClientMinimized(KWin::Client*,bool)));
|
||||
connect(c, SIGNAL(clientUnminimized(KWin::Client*,bool)), this, SLOT(slotClientUnminimized(KWin::Client*,bool)));
|
||||
connect(c, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), this, SLOT(slotGeometryShapeChanged(KWin::Toplevel*,QRect)));
|
||||
connect(c, SIGNAL(paddingChanged(KWin::Toplevel*,QRect)), this, SLOT(slotPaddingChanged(KWin::Toplevel*,QRect)));
|
||||
connect(c, SIGNAL(damaged(KWin::Toplevel*,QRect)), this, SLOT(slotWindowDamaged(KWin::Toplevel*,QRect)));
|
||||
connect(c, SIGNAL(propertyNotify(KWin::Toplevel*,long)), this, SLOT(slotPropertyNotify(KWin::Toplevel*,long)));
|
||||
}
|
||||
|
@ -161,6 +162,7 @@ void EffectsHandlerImpl::setupUnmanagedConnections(Unmanaged* u)
|
|||
connect(u, SIGNAL(windowClosed(KWin::Toplevel*,KWin::Deleted*)), this, SLOT(slotWindowClosed(KWin::Toplevel*)));
|
||||
connect(u, SIGNAL(opacityChanged(KWin::Toplevel*,qreal)), this, SLOT(slotOpacityChanged(KWin::Toplevel*,qreal)));
|
||||
connect(u, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), this, SLOT(slotGeometryShapeChanged(KWin::Toplevel*,QRect)));
|
||||
connect(u, SIGNAL(paddingChanged(KWin::Toplevel*,QRect)), this, SLOT(slotPaddingChanged(KWin::Toplevel*,QRect)));
|
||||
connect(u, SIGNAL(damaged(KWin::Toplevel*,QRect)), this, SLOT(slotWindowDamaged(KWin::Toplevel*,QRect)));
|
||||
connect(u, SIGNAL(propertyNotify(KWin::Toplevel*,long)), this, SLOT(slotPropertyNotify(KWin::Toplevel*,long)));
|
||||
}
|
||||
|
@ -484,6 +486,15 @@ void EffectsHandlerImpl::slotGeometryShapeChanged(Toplevel* t, const QRect& old)
|
|||
emit windowGeometryShapeChanged(t->effectWindow(), old);
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::slotPaddingChanged(Toplevel* t, const QRect& old)
|
||||
{
|
||||
// during late cleanup effectWindow() may be already NULL
|
||||
// in some functions that may still call this
|
||||
if (t == NULL || t->effectWindow() == NULL)
|
||||
return;
|
||||
emit windowPaddingChanged(t->effectWindow(), old);
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::setActiveFullScreenEffect(Effect* e)
|
||||
{
|
||||
fullscreen_effect = e;
|
||||
|
|
|
@ -197,6 +197,7 @@ protected Q_SLOTS:
|
|||
void slotClientMinimized(KWin::Client *c, bool animate);
|
||||
void slotClientUnminimized(KWin::Client *c, bool animate);
|
||||
void slotGeometryShapeChanged(KWin::Toplevel *t, const QRect &old);
|
||||
void slotPaddingChanged(KWin::Toplevel *t, const QRect &old);
|
||||
void slotWindowDamaged(KWin::Toplevel *t, const QRect& r);
|
||||
void slotPropertyNotify(KWin::Toplevel *t, long atom);
|
||||
void slotPropertyNotify(long atom);
|
||||
|
|
|
@ -27,10 +27,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
namespace KWin {
|
||||
struct AnimationEffectPrivate {
|
||||
public:
|
||||
AnimationEffectPrivate() { m_animated = false; }
|
||||
AnimationEffectPrivate() { m_animated = m_damageDirty = false; }
|
||||
AnimationEffect::AniMap m_animations;
|
||||
EffectWindowList m_zombies;
|
||||
bool m_animated;
|
||||
bool m_animated, m_damageDirty, m_needSceneRepaint;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -51,8 +51,12 @@ void AnimationEffect::init()
|
|||
* connect it we can provide auto-referencing of animated and closed windows, since at the time
|
||||
* our slot will be called, the slot of the subclass has been (SIGNAL/SLOT connections are FIFO)
|
||||
* and has pot. started an animation so we have the window in our hash :) */
|
||||
connect ( effects, SIGNAL(windowClosed(KWin::EffectWindow*)), SLOT(_windowClosed(KWin::EffectWindow*)) );
|
||||
connect ( effects, SIGNAL(windowDeleted(KWin::EffectWindow*)), SLOT(_windowDeleted(KWin::EffectWindow*)) );
|
||||
connect ( effects, SIGNAL(windowClosed(KWin::EffectWindow*)), SLOT(_windowClosed(KWin::EffectWindow*)) );
|
||||
connect ( effects, SIGNAL(windowDeleted(KWin::EffectWindow*)), SLOT(_windowDeleted(KWin::EffectWindow*)) );
|
||||
connect ( effects, SIGNAL(windowGeometryShapeChanged(KWin::EffectWindow*, const QRect&)),
|
||||
SLOT(_expandedGeometryChanged(KWin::EffectWindow*, const QRect&)) );
|
||||
connect ( effects, SIGNAL(windowPaddingChanged(KWin::EffectWindow*, const QRect&)),
|
||||
SLOT(_expandedGeometryChanged(KWin::EffectWindow*, const QRect&)) );
|
||||
}
|
||||
|
||||
bool AnimationEffect::isActive() const
|
||||
|
@ -124,17 +128,17 @@ void AnimationEffect::animate( EffectWindow *w, Attribute a, uint meta, int ms,
|
|||
RELATIVE_XY(Source);
|
||||
from.set( relative[0] ? from[0] * area.width() : from[0],
|
||||
relative[1] ? from[1] * area.height() : from[1] );
|
||||
}
|
||||
else
|
||||
} else {
|
||||
from.set(w->width(), w->height());
|
||||
}
|
||||
|
||||
if (to.isValid()) {
|
||||
RELATIVE_XY(Target);
|
||||
to.set( relative[0] ? to[0] * area.width() : to[0],
|
||||
relative[1] ? to[1] * area.height() : to[1] );
|
||||
}
|
||||
else
|
||||
} else {
|
||||
from.set(w->width(), w->height());
|
||||
}
|
||||
|
||||
|
||||
} else if (a == Translation) {
|
||||
|
@ -143,27 +147,34 @@ void AnimationEffect::animate( EffectWindow *w, Attribute a, uint meta, int ms,
|
|||
RELATIVE_XY(Source);
|
||||
from.set( relative[0] ? from[0] * area.width() : from[0],
|
||||
relative[1] ? from[1] * area.height() : from[1] );
|
||||
} else
|
||||
} else {
|
||||
from.set(0.0, 0.0);
|
||||
}
|
||||
|
||||
if (to.isValid()) {
|
||||
RELATIVE_XY(Target);
|
||||
to.set( relative[0] ? to[0] * area.width() : to[0],
|
||||
relative[1] ? to[1] * area.height() : to[1] );
|
||||
} else
|
||||
} else {
|
||||
to.set(0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
Q_D(AnimationEffect);
|
||||
AniMap::iterator it = d->m_animations.find(w);
|
||||
if (it == d->m_animations.end())
|
||||
it = d->m_animations.insert(w, QList<AniData>());
|
||||
it->append(AniData(a, meta, ms, to, curve, delay, from, waitAtSource));
|
||||
it = d->m_animations.insert(w, QPair<QList<AniData>, QRect>(QList<AniData>(), QRect()));
|
||||
it->first.append(AniData(a, meta, ms, to, curve, delay, from, waitAtSource));
|
||||
it->second = QRect();
|
||||
|
||||
if (delay > 0)
|
||||
if (delay > 0) {
|
||||
QTimer::singleShot(delay, this, SLOT(triggerRepaint()));
|
||||
else
|
||||
if (waitAtSource)
|
||||
w->addLayerRepaint(0, 0, displayWidth(), displayHeight());
|
||||
}
|
||||
else {
|
||||
triggerRepaint();
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationEffect::prePaintScreen( ScreenPrePaintData& data, int time )
|
||||
|
@ -174,42 +185,55 @@ void AnimationEffect::prePaintScreen( ScreenPrePaintData& data, int time )
|
|||
return;
|
||||
}
|
||||
|
||||
AniMap::iterator entry = d->m_animations.begin();
|
||||
AniMap::iterator entry = d->m_animations.begin(), mapEnd = d->m_animations.end();
|
||||
d->m_animated = false;
|
||||
while (entry != d->m_animations.end()) {
|
||||
QList<AniData>::iterator anim = entry->begin();
|
||||
while (anim != entry->end()) {
|
||||
// short int transformed = 0;
|
||||
while (entry != mapEnd) {
|
||||
bool invalidateLayerRect = false;
|
||||
QList<AniData>::iterator anim = entry->first.begin(), animEnd = entry->first.end();
|
||||
while (anim != animEnd) {
|
||||
if (QTime::currentTime() < anim->startTime) {
|
||||
if (!anim->waitAtSource) {
|
||||
++anim;
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
anim->addTime(time);
|
||||
}
|
||||
|
||||
if (anim->time < anim->duration) {
|
||||
// if (anim->attribute != Brightness && anim->attribute != Saturation && anim->attribute != Opacity)
|
||||
// transformed = true;
|
||||
d->m_animated = true;
|
||||
++anim;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
animationEnded(entry.key(), anim->attribute);
|
||||
anim = entry->erase(anim);
|
||||
anim = entry->first.erase(anim);
|
||||
invalidateLayerRect = d->m_damageDirty = true;
|
||||
animEnd = entry->first.end();
|
||||
}
|
||||
}
|
||||
if (entry->isEmpty()) {
|
||||
if (entry->first.isEmpty()) {
|
||||
const int i = d->m_zombies.indexOf(entry.key());
|
||||
if ( i > -1 ) {
|
||||
d->m_zombies.removeAt( i );
|
||||
entry.key()->unrefWindow();
|
||||
}
|
||||
data.paint |= entry->second;
|
||||
// d->m_damageDirty = true; // TODO likely no longer required
|
||||
entry = d->m_animations.erase(entry);
|
||||
}
|
||||
else
|
||||
mapEnd = d->m_animations.end();
|
||||
} else {
|
||||
if (invalidateLayerRect)
|
||||
*const_cast<QRect*>(&(entry->second)) = QRect(); // invalidate
|
||||
++entry;
|
||||
}
|
||||
}
|
||||
|
||||
if ( d->m_animated )
|
||||
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
||||
// NOTICE PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_WITHOUT_FULL_REPAINTS and thus now no flag should be required
|
||||
// ... unless we start to get glitches ;-)
|
||||
// if ( transformed )
|
||||
// data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_WITHOUT_FULL_REPAINTS; //PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
||||
|
||||
// janitorial...
|
||||
if ( !(d->m_animations.count() || d->m_zombies.isEmpty()) )
|
||||
|
@ -229,14 +253,14 @@ void AnimationEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data,
|
|||
AniMap::const_iterator entry = d->m_animations.constFind( w );
|
||||
if ( entry != d->m_animations.constEnd() ) {
|
||||
bool isUsed = false;
|
||||
for (QList<AniData>::const_iterator anim = entry->constBegin(); anim != entry->constEnd(); ++anim) {
|
||||
for (QList<AniData>::const_iterator anim = entry->first.constBegin(); anim != entry->first.constEnd(); ++anim) {
|
||||
if (QTime::currentTime() < anim->startTime && !anim->waitAtSource)
|
||||
continue;
|
||||
|
||||
isUsed = true;
|
||||
if (anim->attribute == Opacity)
|
||||
data.setTranslucent();
|
||||
else {
|
||||
else if (!(anim->attribute == Brightness || anim->attribute == Saturation)) {
|
||||
data.setTransformed();
|
||||
data.mask |= PAINT_WINDOW_TRANSFORMED;
|
||||
}
|
||||
|
@ -248,8 +272,8 @@ void AnimationEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data,
|
|||
w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DELETE );
|
||||
else if ( !w->isOnCurrentDesktop() )
|
||||
w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP );
|
||||
if( !w->isPaintingEnabled() && !effects->activeFullScreenEffect() )
|
||||
w->addRepaintFull();
|
||||
// if( !w->isPaintingEnabled() && !effects->activeFullScreenEffect() )
|
||||
// effects->addLayerRepaint(w->expandedGeometry());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +314,7 @@ void AnimationEffect::paintWindow( EffectWindow* w, int mask, QRegion region, Wi
|
|||
if ( d->m_animated ) {
|
||||
AniMap::const_iterator entry = d->m_animations.constFind( w );
|
||||
if ( entry != d->m_animations.constEnd() ) {
|
||||
for ( QList<AniData>::const_iterator anim = entry->constBegin(); anim != entry->constEnd(); ++anim ) {
|
||||
for ( QList<AniData>::const_iterator anim = entry->first.constBegin(); anim != entry->first.constEnd(); ++anim ) {
|
||||
|
||||
if (QTime::currentTime() < anim->startTime && !anim->waitAtSource)
|
||||
continue;
|
||||
|
@ -395,8 +419,18 @@ void AnimationEffect::paintWindow( EffectWindow* w, int mask, QRegion region, Wi
|
|||
void AnimationEffect::postPaintScreen()
|
||||
{
|
||||
Q_D(AnimationEffect);
|
||||
if ( d->m_animated )
|
||||
effects->addRepaintFull();
|
||||
if ( d->m_animated ) {
|
||||
if (d->m_damageDirty)
|
||||
updateLayerRepaints();
|
||||
if (d->m_needSceneRepaint) {
|
||||
effects->addRepaintFull();
|
||||
} else {
|
||||
AniMap::const_iterator it = d->m_animations.constBegin(), end = d->m_animations.constEnd();
|
||||
for (; it != end; ++it) {
|
||||
it.key()->addLayerRepaint(it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
effects->postPaintScreen();
|
||||
}
|
||||
|
||||
|
@ -478,10 +512,153 @@ void AnimationEffect::setMetaData( MetaType type, uint value, uint &meta )
|
|||
void AnimationEffect::triggerRepaint()
|
||||
{
|
||||
Q_D(AnimationEffect);
|
||||
if (!d->m_animated)
|
||||
for (AniMap::const_iterator entry = d->m_animations.constBegin(), mapEnd = d->m_animations.constEnd(); entry != mapEnd; ++entry)
|
||||
*const_cast<QRect*>(&(entry->second)) = QRect();
|
||||
updateLayerRepaints();
|
||||
if (d->m_needSceneRepaint) {
|
||||
effects->addRepaintFull();
|
||||
} else {
|
||||
AniMap::const_iterator it = d->m_animations.constBegin(), end = d->m_animations.constEnd();
|
||||
for (; it != end; ++it)
|
||||
it.key()->addLayerRepaint(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
static float fixOvershoot(float f, const AniData &d, short int dir, float s = 1.1)
|
||||
{
|
||||
switch(d.curve.type()) {
|
||||
case QEasingCurve::InOutElastic:
|
||||
case QEasingCurve::InOutBack:
|
||||
return f * s;
|
||||
case QEasingCurve::InElastic:
|
||||
case QEasingCurve::OutInElastic:
|
||||
case QEasingCurve::OutBack:
|
||||
return (dir&2) ? f * s : f;
|
||||
case QEasingCurve::OutElastic:
|
||||
case QEasingCurve::InBack:
|
||||
return (dir&1) ? f * s : f;
|
||||
default:
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationEffect::updateLayerRepaints()
|
||||
{
|
||||
Q_D(AnimationEffect);
|
||||
d->m_needSceneRepaint = false;
|
||||
for (AniMap::const_iterator entry = d->m_animations.constBegin(), mapEnd = d->m_animations.constEnd(); entry != mapEnd; ++entry) {
|
||||
if (!entry->second.isNull())
|
||||
continue;
|
||||
float f[2] = {1.0, 1.0};
|
||||
float t[2] = {0.0, 0.0};
|
||||
bool createRegion = false;
|
||||
QList<QRect> rects;
|
||||
QRect *layerRect = const_cast<QRect*>(&(entry->second));
|
||||
for (QList<AniData>::const_iterator anim = entry->first.constBegin(), animEnd = entry->first.constEnd(); anim != animEnd; ++anim) {
|
||||
if (QTime::currentTime() < anim->startTime)
|
||||
continue;
|
||||
switch (anim->attribute) {
|
||||
case Opacity:
|
||||
case Brightness:
|
||||
case Saturation:
|
||||
createRegion = true;
|
||||
break;
|
||||
case Rotation:
|
||||
createRegion = false;
|
||||
*layerRect = QRect(0, 0, displayWidth(), displayHeight());
|
||||
goto region_creation; // sic! no need to do anything else
|
||||
case Generic:
|
||||
d->m_needSceneRepaint = true; // we don't know whether this will change visual stacking order
|
||||
return; // sic! no need to do anything else
|
||||
case Translation:
|
||||
case Position: {
|
||||
createRegion = true;
|
||||
QRect r(entry.key()->geometry());
|
||||
int x[2] = {0,0};
|
||||
int y[2] = {0,0};
|
||||
if (anim->attribute == Translation) {
|
||||
x[0] = anim->from[0];
|
||||
x[1] = anim->to[0];
|
||||
y[0] = anim->from[1];
|
||||
y[1] = anim->to[1];
|
||||
} else {
|
||||
if ( anim->from[0] >= 0.0 && anim->to[0] >= 0.0 ) {
|
||||
x[0] = anim->from[0] - xCoord(r, metaData(SourceAnchor, anim->meta));
|
||||
x[1] = anim->to[0] - xCoord(r, metaData(TargetAnchor, anim->meta));
|
||||
}
|
||||
if ( anim->from[1] >= 0.0 && anim->to[1] >= 0.0 ) {
|
||||
y[0] = anim->from[1] - yCoord(r, metaData(SourceAnchor, anim->meta));
|
||||
y[1] = anim->to[1] - yCoord(r, metaData(TargetAnchor, anim->meta));
|
||||
}
|
||||
}
|
||||
r = entry.key()->expandedGeometry();
|
||||
rects << r.translated(x[0], y[0]) << r.translated(x[1], y[1]);
|
||||
break;
|
||||
}
|
||||
case Size:
|
||||
case Scale: {
|
||||
createRegion = true;
|
||||
const QSize sz = entry.key()->geometry().size();
|
||||
float fx = qMax(fixOvershoot(anim->from[0], *anim, 1), fixOvershoot(anim->to[0], *anim, 2));
|
||||
// float fx = qMax(interpolated(*anim,0), anim->to[0]);
|
||||
if (fx >= 0.0) {
|
||||
if (anim->attribute == Size)
|
||||
fx /= sz.width();
|
||||
f[0] *= fx;
|
||||
t[0] += geometryCompensation( anim->meta & AnimationEffect::Horizontal, fx ) * sz.width();
|
||||
}
|
||||
// float fy = qMax(interpolated(*anim,1), anim->to[1]);
|
||||
float fy = qMax(fixOvershoot(anim->from[1], *anim, 1), fixOvershoot(anim->to[1], *anim, 2));
|
||||
if (fy >= 0.0) {
|
||||
if (anim->attribute == Size)
|
||||
fy /= sz.height();
|
||||
if (!anim->isOneDimensional()) {
|
||||
f[1] *= fy;
|
||||
t[1] += geometryCompensation( anim->meta & AnimationEffect::Vertical, fy ) * sz.height();
|
||||
} else if ( ((anim->meta & AnimationEffect::Vertical)>>1) != (anim->meta & AnimationEffect::Horizontal) ) {
|
||||
f[1] *= fx;
|
||||
t[1] += geometryCompensation( anim->meta & AnimationEffect::Vertical, fx ) * sz.height();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
region_creation:
|
||||
if (createRegion) {
|
||||
const QRect geo = entry.key()->expandedGeometry();
|
||||
if (rects.isEmpty())
|
||||
rects << geo;
|
||||
QList<QRect>::const_iterator r, rEnd = rects.constEnd();
|
||||
for ( r = rects.constBegin(); r != rEnd; ++r) { // transform
|
||||
const_cast<QRect*>(&(*r))->setSize(QSize(qRound(r->width()*f[0]), qRound(r->height()*f[1])));
|
||||
const_cast<QRect*>(&(*r))->translate(t[0], t[1]); // "const_cast" - don't do that at home, kids ;-)
|
||||
}
|
||||
QRect rect = rects.at(0);
|
||||
if (rects.count() > 1) {
|
||||
for ( r = rects.constBegin() + 1; r != rEnd; ++r) // unite
|
||||
rect |= *r;
|
||||
const int dx = 110*(rect.width() - geo.width())/100 + 1 - rect.width() + geo.width();
|
||||
const int dy = 110*(rect.height() - geo.height())/100 + 1 - rect.height() + geo.height();
|
||||
rect.adjust(-dx,-dy,dx,dy); // fix pot. overshoot
|
||||
}
|
||||
*layerRect = rect;
|
||||
}
|
||||
}
|
||||
d->m_damageDirty = false;
|
||||
}
|
||||
|
||||
void AnimationEffect::_expandedGeometryChanged(KWin::EffectWindow *w, const QRect &old)
|
||||
{
|
||||
Q_D(AnimationEffect);
|
||||
AniMap::const_iterator entry = d->m_animations.constFind(w);
|
||||
if (entry != d->m_animations.constEnd()) {
|
||||
*const_cast<QRect*>(&(entry->second)) = QRect();
|
||||
updateLayerRepaints();
|
||||
if (!entry->second.isNull()) // actually got updated, ie. is in use - ensure it get's a repaint
|
||||
w->addLayerRepaint(entry->second);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationEffect::_windowClosed( EffectWindow* w )
|
||||
{
|
||||
|
@ -495,6 +672,7 @@ void AnimationEffect::_windowClosed( EffectWindow* w )
|
|||
void AnimationEffect::_windowDeleted( EffectWindow* w )
|
||||
{
|
||||
Q_D(AnimationEffect);
|
||||
d->m_zombies.removeAll( w ); // TODO this line is a workaround for a bug in KWin 4.8.0 & 4.8.1
|
||||
d->m_animations.remove( w );
|
||||
}
|
||||
|
||||
|
|
|
@ -167,13 +167,15 @@ protected:
|
|||
private:
|
||||
float interpolated( const AniData&, int i = 0 ) const;
|
||||
float progress( const AniData& ) const;
|
||||
void updateLayerRepaints();
|
||||
private Q_SLOTS:
|
||||
void init();
|
||||
void triggerRepaint();
|
||||
void _windowClosed( KWin::EffectWindow* w );
|
||||
void _windowDeleted( KWin::EffectWindow* w );
|
||||
void _expandedGeometryChanged(KWin::EffectWindow *w, const QRect &old);
|
||||
private:
|
||||
typedef QMap< EffectWindow*, QList<AniData> > AniMap;
|
||||
typedef QMap< EffectWindow*, QPair<QList<AniData>, QRect> > AniMap;
|
||||
AnimationEffectPrivate * const d_ptr;
|
||||
Q_DECLARE_PRIVATE(AnimationEffect)
|
||||
};
|
||||
|
|
|
@ -307,6 +307,7 @@ WINDOW_HELPER(QPoint, pos, "pos")
|
|||
WINDOW_HELPER(QSize, size, "size")
|
||||
WINDOW_HELPER(int, screen, "screen")
|
||||
WINDOW_HELPER(QRect, geometry, "geometry")
|
||||
WINDOW_HELPER(QRect, expandedGeometry, "visibleRect")
|
||||
WINDOW_HELPER(QRect, rect, "rect")
|
||||
WINDOW_HELPER(int, desktop, "desktop")
|
||||
WINDOW_HELPER(bool, isDesktop, "desktopWindow")
|
||||
|
|
|
@ -954,6 +954,13 @@ Q_SIGNALS:
|
|||
* @since 4.7
|
||||
**/
|
||||
void windowGeometryShapeChanged(KWin::EffectWindow *w, const QRect &old);
|
||||
/**
|
||||
* Signal emitted when the padding of a window changed. (eg. shadow size)
|
||||
* @param w The window whose geometry changed
|
||||
* @param old The previous expandedGeometry()
|
||||
* @since 4.9
|
||||
**/
|
||||
void windowPaddingChanged(KWin::EffectWindow *w, const QRect &old);
|
||||
/**
|
||||
* Signal emitted when the windows opacity is changed.
|
||||
* @param w The window whose opacity level is changed.
|
||||
|
@ -1097,6 +1104,7 @@ class KWIN_EXPORT EffectWindow : public QObject
|
|||
Q_OBJECT
|
||||
Q_PROPERTY(bool alpha READ hasAlpha CONSTANT)
|
||||
Q_PROPERTY(QRect geometry READ geometry)
|
||||
Q_PROPERTY(QRect expandedGeometry READ expandedGeometry)
|
||||
Q_PROPERTY(int height READ height)
|
||||
Q_PROPERTY(qreal opacity READ opacity)
|
||||
Q_PROPERTY(QPoint pos READ pos)
|
||||
|
@ -1332,6 +1340,12 @@ public:
|
|||
*/
|
||||
QSize basicUnit() const;
|
||||
QRect geometry() const;
|
||||
/**
|
||||
* Geometry of the window including decoration and potentially shadows.
|
||||
* May be different from geometry() if the window has a shadow.
|
||||
* @since 4.9
|
||||
*/
|
||||
QRect expandedGeometry() const;
|
||||
virtual QRegion shape() const = 0;
|
||||
int screen() const;
|
||||
/** @internal Do not use */
|
||||
|
@ -1344,6 +1358,7 @@ public:
|
|||
bool isUserMove() const;
|
||||
bool isUserResize() const;
|
||||
QRect iconGeometry() const;
|
||||
|
||||
/**
|
||||
* Geometry of the actual window contents inside the whole (including decorations) window.
|
||||
*/
|
||||
|
|
|
@ -369,6 +369,7 @@ bool Toplevel::isOnScreen(int screen) const
|
|||
void Toplevel::getShadow()
|
||||
{
|
||||
QRect dirtyRect; // old & new shadow region
|
||||
const QRect oldVisibleRect = visibleRect();
|
||||
if (hasShadow()) {
|
||||
dirtyRect = shadow()->shadowRegion().boundingRect();
|
||||
effectWindow()->sceneWindow()->shadow()->updateShadow();
|
||||
|
@ -377,6 +378,8 @@ void Toplevel::getShadow()
|
|||
}
|
||||
if (hasShadow())
|
||||
dirtyRect |= shadow()->shadowRegion().boundingRect();
|
||||
if (oldVisibleRect != visibleRect())
|
||||
emit paddingChanged(this, oldVisibleRect);
|
||||
if (dirtyRect.isValid()) {
|
||||
dirtyRect.translate(pos());
|
||||
addLayerRepaint(dirtyRect);
|
||||
|
|
|
@ -49,6 +49,7 @@ class Toplevel
|
|||
Q_PROPERTY(bool alpha READ hasAlpha CONSTANT)
|
||||
Q_PROPERTY(qulonglong frameId READ frameId)
|
||||
Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged)
|
||||
Q_PROPERTY(QRect visibleRect READ visibleRect)
|
||||
Q_PROPERTY(int height READ height)
|
||||
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged)
|
||||
Q_PROPERTY(QPoint pos READ pos)
|
||||
|
@ -285,6 +286,7 @@ signals:
|
|||
void propertyNotify(KWin::Toplevel* toplevel, long a);
|
||||
void geometryChanged();
|
||||
void geometryShapeChanged(KWin::Toplevel* toplevel, const QRect& old);
|
||||
void paddingChanged(KWin::Toplevel* toplevel, const QRect& old);
|
||||
void windowClosed(KWin::Toplevel* toplevel, KWin::Deleted* deleted);
|
||||
void windowShown(KWin::Toplevel* toplevel);
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue