diff --git a/autotests/integration/effects/slidingpopups_test.cpp b/autotests/integration/effects/slidingpopups_test.cpp --- a/autotests/integration/effects/slidingpopups_test.cpp +++ b/autotests/integration/effects/slidingpopups_test.cpp @@ -222,10 +222,6 @@ // sliding popups should be active QVERIFY(windowAddedSpy.wait()); QTRY_VERIFY(slidingPoupus->isActive()); - QEXPECT_FAIL("scale, slide", "bug 336866", Continue); - QEXPECT_FAIL("fade, slide", "bug 336866", Continue); - QEXPECT_FAIL("wobblywindows, slide", "bug 336866", Continue); - QEXPECT_FAIL("slide, wobblywindows", "bug 336866", Continue); QVERIFY(!otherEffect->isActive()); // wait till effect ends @@ -246,8 +242,6 @@ // again we should have the sliding popups active QVERIFY(slidingPoupus->isActive()); - QEXPECT_FAIL("wobblywindows, slide", "bug 336866", Continue); - QEXPECT_FAIL("slide, wobblywindows", "bug 336866", Continue); QVERIFY(!otherEffect->isActive()); QVERIFY(windowDeletedSpy.wait()); @@ -347,10 +341,6 @@ // sliding popups should be active QCOMPARE(windowAddedSpy.count(), 1); QTRY_VERIFY(slidingPoupus->isActive()); - QEXPECT_FAIL("scale, slide", "bug 336866", Continue); - QEXPECT_FAIL("fade, slide", "bug 336866", Continue); - QEXPECT_FAIL("wobblywindows, slide", "bug 336866", Continue); - QEXPECT_FAIL("slide, wobblywindows", "bug 336866", Continue); QVERIFY(!otherEffect->isActive()); // wait till effect ends @@ -371,8 +361,6 @@ // again we should have the sliding popups active QVERIFY(slidingPoupus->isActive()); - QEXPECT_FAIL("wobblywindows, slide", "bug 336866", Continue); - QEXPECT_FAIL("slide, wobblywindows", "bug 336866", Continue); QVERIFY(!otherEffect->isActive()); QVERIFY(windowDeletedSpy.wait()); diff --git a/effects.cpp b/effects.cpp --- a/effects.cpp +++ b/effects.cpp @@ -1688,6 +1688,7 @@ dataMap[ role ] = data; else dataMap.remove(role); + emit effects->windowDataChanged(this, role); } QVariant EffectWindowImpl::data(int role) const diff --git a/effects/fade/package/contents/code/main.js b/effects/fade/package/contents/code/main.js --- a/effects/fade/package/contents/code/main.js +++ b/effects/fade/package/contents/code/main.js @@ -43,12 +43,12 @@ }); effects.windowAdded.connect(function(w) { if (fadeWindows && isFadeWindow(w)) { - effect.animate(w, Effect.Opacity, fadeInTime, 1.0, 0.0); + w.fadeInWindowTypeAnimation = effect.animate(w, Effect.Opacity, fadeInTime, 1.0, 0.0); } }); effects.windowClosed.connect(function(w) { if (fadeWindows && isFadeWindow(w)) { - animate({ + w.fadeOutWindowTypeAnimation = animate({ window: w, duration: fadeOutTime, animations: [{ @@ -59,3 +59,20 @@ }); } }); +effects.windowDataChanged.connect(function (window, role) { + if (role == Effect.WindowAddedGrabRole) { + if (effect.isGrabbed(window, Effect.WindowAddedGrabRole)) { + if (window.fadeInWindowTypeAnimation !== undefined) { + cancel(window.fadeInWindowTypeAnimation); + window.fadeInWindowTypeAnimation = undefined; + } + } + } else if (role == Effect.WindowClosedGrabRole) { + if (effect.isGrabbed(window, Effect.WindowClosedGrabRole)) { + if (window.fadeOutWindowTypeAnimation !== undefined) { + cancel(window.fadeOutWindowTypeAnimation); + window.fadeOutWindowTypeAnimation = undefined; + } + } + } +}); diff --git a/effects/scalein/package/contents/code/main.js b/effects/scalein/package/contents/code/main.js --- a/effects/scalein/package/contents/code/main.js +++ b/effects/scalein/package/contents/code/main.js @@ -34,7 +34,7 @@ }, scaleIn: function (window) { "use strict"; - animate({ + window.scaleInWindowTypeAnimation = animate({ window: window, duration: scaleInEffect.duration, curve: QEasingCurve.InOutQuad, @@ -56,10 +56,22 @@ } scaleInEffect.scaleIn(window); }, + dataChanged: function (window, role) { + "use strict"; + if (role == Effect.WindowAddedGrabRole) { + if (effect.isGrabbed(window, Effect.WindowAddedGrabRole)) { + if (window.scaleInWindowTypeAnimation !== undefined) { + cancel(window.scaleInWindowTypeAnimation); + window.scaleInWindowTypeAnimation = undefined; + } + } + } + }, init: function () { "use strict"; effect.configChanged.connect(scaleInEffect.loadConfig); effects.windowAdded.connect(scaleInEffect.added); + effects.windowDataChanged.connect(scaleInEffect.dataChanged); } }; scaleInEffect.init(); diff --git a/effects/slidingpopups/slidingpopups.cpp b/effects/slidingpopups/slidingpopups.cpp --- a/effects/slidingpopups/slidingpopups.cpp +++ b/effects/slidingpopups/slidingpopups.cpp @@ -305,7 +305,6 @@ mAppearingWindows.insert(w, new QTimeLine(mWindowsData[ w ].fadeInDuration, this)); mAppearingWindows[ w ]->setCurveShape(QTimeLine::EaseInOutCurve); - // Tell other windowAdded() and windowClosed() effects to ignore this window w->setData(WindowAddedGrabRole, QVariant::fromValue(static_cast(this))); w->setData(WindowClosedGrabRole, QVariant::fromValue(static_cast(this))); w->setData(WindowForceBlurRole, true); diff --git a/effects/wobblywindows/wobblywindows.h b/effects/wobblywindows/wobblywindows.h --- a/effects/wobblywindows/wobblywindows.h +++ b/effects/wobblywindows/wobblywindows.h @@ -136,6 +136,7 @@ private: + void cancelWindowGrab(KWin::EffectWindow *w, int grabRole); void startMovedResized(EffectWindow* w); void stepMovedResized(EffectWindow* w); bool updateWindowWobblyDatas(EffectWindow* w, qreal time); diff --git a/effects/wobblywindows/wobblywindows.cpp b/effects/wobblywindows/wobblywindows.cpp --- a/effects/wobblywindows/wobblywindows.cpp +++ b/effects/wobblywindows/wobblywindows.cpp @@ -153,6 +153,8 @@ connect(effects, SIGNAL(windowStepUserMovedResized(KWin::EffectWindow*,QRect)), this, SLOT(slotWindowStepUserMovedResized(KWin::EffectWindow*,QRect))); connect(effects, SIGNAL(windowFinishUserMovedResized(KWin::EffectWindow*)), this, SLOT(slotWindowFinishUserMovedResized(KWin::EffectWindow*))); connect(effects, SIGNAL(windowMaximizedStateChanged(KWin::EffectWindow*,bool,bool)), this, SLOT(slotWindowMaximizeStateChanged(KWin::EffectWindow*,bool,bool))); + + connect(effects, &EffectsHandler::windowDataChanged, this, &WobblyWindowsEffect::cancelWindowGrab); } WobblyWindowsEffect::~WobblyWindowsEffect() @@ -472,7 +474,7 @@ void WobblyWindowsEffect::slotWindowAdded(EffectWindow* w) { - if (m_openEffectEnabled && w->data(WindowAddedGrabRole).value() != this) { + if (m_openEffectEnabled && w->data(WindowAddedGrabRole).value() == nullptr) { if (windows.contains(w)) { // could this happen ?? WindowWobblyInfos& wwi = windows[w]; @@ -499,7 +501,7 @@ if (windows.isEmpty()) effects->addRepaintFull(); } - } else if (m_closeEffectEnabled && w->data(WindowAddedGrabRole).value() != this) { + } else if (m_closeEffectEnabled && w->data(WindowClosedGrabRole).value() == nullptr) { WindowWobblyInfos new_wwi; initWobblyInfo(new_wwi, w->geometry()); wobblyCloseInit(new_wwi, w); @@ -1200,6 +1202,31 @@ wwi.buffer = tmp; } + +void WobblyWindowsEffect::cancelWindowGrab(KWin::EffectWindow *w, int grabRole) +{ + if (grabRole == WindowAddedGrabRole) { + if (w->data(WindowAddedGrabRole).value() != this) { + auto it = windows.find(w); + if (it != windows.end()) { + freeWobblyInfo(it.value()); + windows.erase(it); + } + } + } else if (grabRole == WindowClosedGrabRole) { + if (w->data(WindowClosedGrabRole).value() != this) { + auto it = windows.find(w); + if (it != windows.end()) { + if (it.value().status == Closing) { + w->unrefWindow(); + } + freeWobblyInfo(it.value()); + windows.erase(it); + } + } + } +} + bool WobblyWindowsEffect::isActive() const { return !windows.isEmpty(); diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -1537,6 +1537,21 @@ **/ void windowHidden(KWin::EffectWindow *w); + /** + * This signal gets emitted when the data on EffectWindow @p w for @p role changed. + * + * An Effect can connect to this signal to read the new value and react on it. + * E.g. an Effect which does not operate on windows grabbed by another Effect wants + * to cancel the already scheduled animation if another Effect adds a grab. + * + * @param w The EffectWindow for which the data changed + * @param role The data role which changed + * @see EffectWindow::setData + * @see EffectWindow::data + * @since 5.8.4 + **/ + void windowDataChanged(KWin::EffectWindow *w, int role); + protected: QVector< EffectPair > loaded_effects; //QHash< QString, EffectFactory* > effect_factories; @@ -2017,6 +2032,9 @@ /** * Can be used to by effects to store arbitrary data in the EffectWindow. + * + * Invoking this method will emit the signal EffectsHandler::windowDataChanged. + * @see EffectsHandler::windowDataChanged */ Q_SCRIPTABLE virtual void setData(int role, const QVariant &data) = 0; Q_SCRIPTABLE virtual QVariant data(int role) const = 0;