diff --git a/src/effects/slide/slide.cpp b/src/effects/slide/slide.cpp index 33c0680b9b..c9cc15c916 100644 --- a/src/effects/slide/slide.cpp +++ b/src/effects/slide/slide.cpp @@ -15,9 +15,6 @@ // KConfigSkeleton #include "slideconfig.h" -#include -#include - namespace KWin { @@ -30,27 +27,21 @@ SlideEffect::SlideEffect() connect(effects, QOverload::of(&EffectsHandler::desktopChanged), this, &SlideEffect::desktopChanged); - connect(effects, QOverload::of(&EffectsHandler::desktopChanging), - this, &SlideEffect::desktopChanging); - connect(effects, QOverload<>::of(&EffectsHandler::desktopChangingCancelled), - this, &SlideEffect::desktopChangingCancelled); connect(effects, &EffectsHandler::windowAdded, this, &SlideEffect::windowAdded); connect(effects, &EffectsHandler::windowDeleted, this, &SlideEffect::windowDeleted); connect(effects, &EffectsHandler::numberDesktopsChanged, - this, &SlideEffect::finishedSwitching); + this, &SlideEffect::stop); connect(effects, &EffectsHandler::screenAdded, - this, &SlideEffect::finishedSwitching); + this, &SlideEffect::stop); connect(effects, &EffectsHandler::screenRemoved, - this, &SlideEffect::finishedSwitching); - - m_currentPosition = effects->desktopCoords(effects->currentDesktop()); + this, &SlideEffect::stop); } SlideEffect::~SlideEffect() { - finishedSwitching(); + stop(); } bool SlideEffect::supported() @@ -62,8 +53,8 @@ void SlideEffect::reconfigure(ReconfigureFlags) { SlideConfig::self()->read(); - m_animationDuration = animationTime(500); - m_timeLine.setDuration(std::chrono::milliseconds(m_animationDuration)); + m_timeLine.setDuration( + std::chrono::milliseconds(animationTime(500))); m_hGap = SlideConfig::horizontalGap(); m_vGap = SlideConfig::verticalGap(); @@ -73,69 +64,98 @@ void SlideEffect::reconfigure(ReconfigureFlags) void SlideEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) { - std::chrono::milliseconds timeDelta = std::chrono::milliseconds::zero(); - if (m_lastPresentTime.count()) { - timeDelta = presentTime - m_lastPresentTime; - } - m_lastPresentTime = presentTime; + std::chrono::milliseconds delta = std::chrono::milliseconds::zero(); + if (m_lastPresentTime.count()) { + delta = presentTime - m_lastPresentTime; + } + m_lastPresentTime = presentTime; - m_timeLine.update(timeDelta); + m_timeLine.update(delta); - if (!m_gestureActive) { // When animating - m_currentPosition = m_startPos + (m_endPos - m_startPos) * m_timeLine.value(); - } + data.mask |= PAINT_SCREEN_TRANSFORMED + | PAINT_SCREEN_BACKGROUND_FIRST; - data.mask |= PAINT_SCREEN_TRANSFORMED - | PAINT_SCREEN_BACKGROUND_FIRST; + effects->prePaintScreen(data, presentTime); +} - effects->prePaintScreen(data, presentTime); +/** + * Wrap vector @p diff around grid @p w x @p h. + * + * Wrapping is done in such a way that magnitude of x and y component of vector + * @p diff is less than half of @p w and half of @p h, respectively. This will + * result in having the "shortest" path between two points. + * + * @param diff Vector between two points + * @param w Width of the desktop grid + * @param h Height of the desktop grid + */ +inline void wrapDiff(QPoint &diff, int w, int h) +{ + if (diff.x() > w/2) { + diff.setX(diff.x() - w); + } else if (diff.x() < -w/2) { + diff.setX(diff.x() + w); + } + + if (diff.y() > h/2) { + diff.setY(diff.y() - h); + } else if (diff.y() < -h/2) { + diff.setY(diff.y() + h); + } +} + +inline QRegion buildClipRegion(const QPoint &pos, int w, int h) +{ + const QSize screenSize = effects->virtualScreenSize(); + QRegion r = QRect(pos, screenSize); + if (effects->optionRollOverDesktops()) { + r |= (r & QRect(-w, 0, w, h)).translated(w, 0); // W + r |= (r & QRect(w, 0, w, h)).translated(-w, 0); // E + + r |= (r & QRect(0, -h, w, h)).translated(0, h); // N + r |= (r & QRect(0, h, w, h)).translated(0, -h); // S + + r |= (r & QRect(-w, -h, w, h)).translated(w, h); // NW + r |= (r & QRect(w, -h, w, h)).translated(-w, h); // NE + r |= (r & QRect(w, h, w, h)).translated(-w, -h); // SE + r |= (r & QRect(-w, h, w, h)).translated(w, -h); // SW + } + return r; } void SlideEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) { const bool wrap = effects->optionRollOverDesktops(); - const int w = effects->desktopGridWidth(); - const int h = effects->desktopGridHeight(); - bool wrappingX = false, wrappingY = false; + const int w = workspaceWidth(); + const int h = workspaceHeight(); - QPointF drawPosition = forcePositivePosition(m_currentPosition); + QPoint currentPos = m_startPos + m_diff * m_timeLine.value(); - if (wrap) { // - drawPosition = constrainToDrawableRange(drawPosition); + // When "Desktop navigation wraps around" checkbox is checked, currentPos + // can be outside the rectangle Rect{x:-w, y:-h, width:2*w, height: 2*h}, + // so we map currentPos back to the rect. + if (wrap) { + currentPos.setX(currentPos.x() % w); + currentPos.setY(currentPos.y() % h); } - //Clipping QVector visibleDesktops; visibleDesktops.reserve(4); // 4 - maximum number of visible desktops + const QRegion clipRegion = buildClipRegion(currentPos, w, h); for (int i = 1; i <= effects->numberOfDesktops(); i++) { - if (effects->desktopGridCoords(i).x() % w == (int)(m_currentPosition.x()) % w) { - visibleDesktops << i; - } else if (effects->desktopGridCoords(i).x() % w == ((int)(m_currentPosition.x()) + 1) % w) { - visibleDesktops << i; - } else if (effects->desktopGridCoords(i).y() % h == (int)(m_currentPosition.y()) % h) { - visibleDesktops << i; - } else if (effects->desktopGridCoords(i).y() % h == ((int)(m_currentPosition.y()) + 1) % h) { - visibleDesktops << i; + const QRect desktopGeo = desktopGeometry(i); + if (!clipRegion.contains(desktopGeo)) { + continue; } + visibleDesktops << i; } - //If we're wrapping, draw the desktop in the second position. - if (drawPosition.x() > w - 1) { - wrappingX = true; - } - - if (drawPosition.y() > h - 1) { - wrappingY = true; - } - - /* - * When we enter a virtual desktop that has a window in fullscreen mode, - * stacking order is fine. When we leave a virtual desktop that has - * a window in fullscreen mode, stacking order is no longer valid - * because panels are raised above the fullscreen window. Construct - * a list of fullscreen windows, so we can decide later whether - * docks should be visible on different virtual desktops. - */ + // When we enter a virtual desktop that has a window in fullscreen mode, + // stacking order is fine. When we leave a virtual desktop that has + // a window in fullscreen mode, stacking order is no longer valid + // because panels are raised above the fullscreen window. Construct + // a list of fullscreen windows, so we can decide later whether + // docks should be visible on different virtual desktops. if (m_slideDocks) { const auto windows = effects->stackingOrder(); m_paintCtx.fullscreenWindows.clear(); @@ -147,41 +167,25 @@ void SlideEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData & } } - /* - * Screen is painted in several passes. Each painting pass paints - * a single virtual desktop. There could be either 2 or 4 painting - * passes, depending how an user moves between virtual desktops. - * Windows, such as docks or keep-above windows, are painted in - * the last pass so they are above other windows. - */ + // Screen is painted in several passes. Each painting pass paints + // a single virtual desktop. There could be either 2 or 4 painting + // passes, depending how an user moves between virtual desktops. + // Windows, such as docks or keep-above windows, are painted in + // the last pass so they are above other windows. m_paintCtx.firstPass = true; const int lastDesktop = visibleDesktops.last(); for (int desktop : qAsConst(visibleDesktops)) { m_paintCtx.desktop = desktop; m_paintCtx.lastPass = (lastDesktop == desktop); - m_paintCtx.translation = QPointF(effects->desktopGridCoords(desktop)) - drawPosition;//TODO: verify - - // Decide if that first desktop should be drawn at 0 or the higher position used for wrapping. - if (effects->desktopGridCoords(desktop).x() == 0 && wrappingX) { - m_paintCtx.translation = QPointF(m_paintCtx.translation.x() + w, m_paintCtx.translation.y()); + m_paintCtx.translation = desktopCoords(desktop) - currentPos; + if (wrap) { + wrapDiff(m_paintCtx.translation, w, h); } - - if (effects->desktopGridCoords(desktop).y() == 0 && wrappingY) { - m_paintCtx.translation = QPointF(m_paintCtx.translation.x(), m_paintCtx.translation.y() + h); - } - effects->paintScreen(mask, region, data); m_paintCtx.firstPass = false; } } -QPoint SlideEffect::getDrawCoords(QPointF pos, EffectScreen *screen){ - QPoint c = QPoint(); - c.setX(pos.x() * (screen->geometry().width() + m_hGap)); - c.setY(pos.y() * (screen->geometry().height() + m_vGap)); - return c; -} - /** * Decide whether given window @p w should be transformed/translated. * @returns @c true if given window @p w should be transformed, otherwise @c false @@ -224,19 +228,15 @@ bool SlideEffect::isPainted(const EffectWindow *w) const return true; } if (w->isDesktop()) { - /* - * If desktop background is not being slided, draw it only - * in the first pass. Otherwise, desktop backgrounds from - * follow-up virtual desktops will be drawn above windows - * from previous virtual desktops. - */ + // If desktop background is not being slided, draw it only + // in the first pass. Otherwise, desktop backgrounds from + // follow-up virtual desktops will be drawn above windows + // from previous virtual desktops. return m_slideBackground || m_paintCtx.firstPass; } - /* - * In order to make sure that 'keep above' windowscreen->geometry().x()s are above - * other windows during transition to another virtual desktop, - * they should be painted in the last pass. - */ + // In order to make sure that 'keep above' windows are above + // other windows during transition to another virtual desktop, + // they should be painted in the last pass. if (w->keepAbove()) { return m_paintCtx.lastPass; } @@ -252,7 +252,6 @@ bool SlideEffect::isPainted(const EffectWindow *w) const void SlideEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) { const bool painted = isPainted(w); - if (painted) { w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP); } else { @@ -266,74 +265,96 @@ void SlideEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std: void SlideEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) { - for (EffectScreen *screen: effects->screens()) { - QPoint translation = getDrawCoords(m_paintCtx.translation, screen); - if (isTranslated(w)) { - data += translation; - } - - effects->paintWindow( - w, - mask, - // Only paint the region that intersects the current screen and desktop. - region.intersected(effects->clientArea(ScreenArea, w)).intersected(effects->clientArea(ScreenArea, screen, effects->currentDesktop())), - data); - - if (isTranslated(w)) { - // Undo the translation for the next screen. I know, it hurts me too. - data += QPoint(-translation.x(), -translation.y()); - } + if (isTranslated(w)) { + data += m_paintCtx.translation; } + effects->paintWindow(w, mask, region, data); } void SlideEffect::postPaintScreen() { - if (m_timeLine.done() && !m_gestureActive) { - finishedSwitching(); + if (m_timeLine.done()) { + stop(); } effects->addRepaintFull(); effects->postPaintScreen(); } -/* - * Negative desktop positions aren't allowed. +/** + * Get position of the top-left corner of desktop @p id within desktop grid with gaps. + * @param id ID of a virtual desktop */ -QPointF SlideEffect::forcePositivePosition(QPointF p) const +QPoint SlideEffect::desktopCoords(int id) const { - while (p.x() < 0) { - p.setX(p.x() + effects->desktopGridWidth()); - } - while (p.y() < 0) { - p.setY(p.y() + effects->desktopGridHeight()); - } - return p; + QPoint c = effects->desktopCoords(id); + const QPoint gridPos = effects->desktopGridCoords(id); + c.setX(c.x() + m_hGap * gridPos.x()); + c.setY(c.y() + m_vGap * gridPos.y()); + return c; +} + +/** + * Get geometry of desktop @p id within desktop grid with gaps. + * @param id ID of a virtual desktop + */ +QRect SlideEffect::desktopGeometry(int id) const +{ + QRect g = effects->virtualScreenGeometry(); + g.translate(desktopCoords(id)); + return g; +} + +/** + * Get width of a virtual desktop grid. + */ +int SlideEffect::workspaceWidth() const +{ + int w = effects->workspaceWidth(); + w += m_hGap * effects->desktopGridWidth(); + return w; +} + +/** + * Get height of a virtual desktop grid. + */ +int SlideEffect::workspaceHeight() const +{ + int h = effects->workspaceHeight(); + h += m_vGap * effects->desktopGridHeight(); + return h; } bool SlideEffect::shouldElevate(const EffectWindow *w) const { - /* - * Static docks(i.e. this effect doesn't slide docks) should be elevated - * so they can properly animate themselves when an user enters or leaves - * a virtual desktop with a window in fullscreen mode. - */ + // Static docks(i.e. this effect doesn't slide docks) should be elevated + // so they can properly animate themselves when an user enters or leaves + // a virtual desktop with a window in fullscreen mode. return w->isDock() && !m_slideDocks; } -/* - * This function is called when the desktop changes. - * Called AFTER the gesture is released. - * Sets up animation to round off to the new current desktop. - */ -void SlideEffect::startAnimation(int old, int current, EffectWindow *movingWindow) +void SlideEffect::start(int old, int current, EffectWindow *movingWindow) { - Q_UNUSED(old) - m_movingWindow = movingWindow; const bool wrap = effects->optionRollOverDesktops(); + const int w = workspaceWidth(); + const int h = workspaceHeight(); + + if (m_active) { + QPoint passed = m_diff * m_timeLine.value(); + QPoint currentPos = m_startPos + passed; + QPoint delta = desktopCoords(current) - desktopCoords(old); + if (wrap) { + wrapDiff(delta, w, h); + } + m_diff += delta - passed; + m_startPos = currentPos; + // TODO: Figure out how to smooth movement. + m_timeLine.reset(); + return; + } - //Handle stacking order const auto windows = effects->stackingOrder(); for (EffectWindow *w : windows) { if (shouldElevate(w)) { @@ -344,35 +365,18 @@ void SlideEffect::startAnimation(int old, int current, EffectWindow *movingWindo w->setData(WindowForceBlurRole, QVariant(true)); } - // Set up animation - m_active = true; - m_timeLine.reset(); - - m_startPos = m_currentPosition; - m_endPos = effects->desktopGridCoords(current); + m_diff = desktopCoords(current) - desktopCoords(old); if (wrap) { - optimizePath(); + wrapDiff(m_diff, w, h); } - - // Find an apropriate duration - m_timeLine.setDuration(std::chrono::milliseconds(m_animationDuration)); - - QPointF distance = m_startPos - m_endPos; - distance.setX(std::abs(distance.x())); - distance.setY(std::abs(distance.y())); - if (distance.x() < 1 && distance.y() < 1) { - if (distance.x() > distance.y()) { - m_timeLine.setDuration(std::chrono::milliseconds((int)(m_animationDuration * distance.x()))); - } else { - m_timeLine.setDuration(std::chrono::milliseconds((int)(m_animationDuration * distance.y()))); - } - } - + m_startPos = desktopCoords(old); + m_timeLine.reset(); + m_active = true; effects->setActiveFullScreenEffect(this); effects->addRepaintFull(); } -void SlideEffect::finishedSwitching() +void SlideEffect::stop() { if (!m_active) { return; @@ -393,70 +397,14 @@ void SlideEffect::finishedSwitching() m_active = false; m_lastPresentTime = std::chrono::milliseconds::zero(); effects->setActiveFullScreenEffect(nullptr); - m_currentPosition = effects->desktopGridCoords(effects->currentDesktop()); } void SlideEffect::desktopChanged(int old, int current, EffectWindow *with) { - if (effects->hasActiveFullScreenEffect() && effects->activeFullScreenEffect() != this) { - m_currentPosition = effects->desktopGridCoords(effects->currentDesktop()); + if (effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this) { return; } - - m_gestureActive = false; - startAnimation(old, current, with); -} - -void SlideEffect::desktopChanging(uint old, QPointF desktopOffset, EffectWindow *with) -{ - if (effects->hasActiveFullScreenEffect() && effects->activeFullScreenEffect() != this) { - return; - } - - m_gestureActive = true; - m_movingWindow = with; - - const bool wrap = effects->optionRollOverDesktops(); - - // Find desktop position based on animationDelta - QPoint gridPos = effects->desktopGridCoords(old); - m_currentPosition.setX(gridPos.x() + desktopOffset.x()); - m_currentPosition.setY(gridPos.y() + desktopOffset.y()); - - m_currentPosition = forcePositivePosition(m_currentPosition); - - if (!wrap) { - m_currentPosition = moveInsideDesktopGrid(m_currentPosition); - } - - m_active = true; - effects->setActiveFullScreenEffect(this); - effects->addRepaintFull(); -} - -void SlideEffect::desktopChangingCancelled() -{ - if (effects->hasActiveFullScreenEffect() && effects->activeFullScreenEffect() != this) { - return; - } - - std::cout << "Cancelled" << std::endl; - m_gestureActive = false; - startAnimation(effects->currentDesktop(), effects->currentDesktop(), nullptr); -} - -QPointF SlideEffect::moveInsideDesktopGrid(QPointF p) -{ - if (p.x() < 0) { - p.setX(0); - } else if (p.y() < 0) { - p.setY(0); - } else if (p.x() > effects->desktopGridWidth() - 1) { - p.setX(effects->desktopGridWidth() - 1); - } else if (p.y() > effects->desktopGridHeight() - 1) { - p.setY(effects->desktopGridHeight() - 1); - } - return p; + start(old, current, with); } void SlideEffect::windowAdded(EffectWindow *w) @@ -484,76 +432,4 @@ void SlideEffect::windowDeleted(EffectWindow *w) m_paintCtx.fullscreenWindows.removeAll(w); } -/* - * Find the fastest path between two desktops. - * This function decides when it's better to wrap around the grid or not. - * Only call if wrapping is enabled. - */ -void SlideEffect::optimizePath() -{ - int w = effects->desktopGridWidth(); - int h = effects->desktopGridHeight(); - - // Keep coordinates as low as possible - if(m_startPos.x() >= w && m_endPos.x() >= w) { - m_startPos.setX(fmod(m_startPos.x(), w)); - m_endPos.setX(fmod(m_endPos.x(), w)); - } - if(m_startPos.y() >= h && m_endPos.y() >= h) { - m_startPos.setY(fmod(m_startPos.y(), h)); - m_endPos.setY(fmod(m_endPos.y(), h)); - } - - /* - * Is there is a shorter possible route? - * If the x distance to be traveled is more than half the grid width, it's faster to wrap. - * To avoid negative coordinates, take the lower coordinate and raise. - */ - if (std::abs((m_startPos.x() - m_endPos.x())) > (double)w / (double)2) { - if (m_startPos.x() < m_endPos.x()) { - while (m_startPos.x() < m_endPos.x()) - m_startPos.setX(m_startPos.x() + w); - - } else { - while (m_endPos.x() < m_startPos.x()) - m_endPos.setX(m_endPos.x() + w); - } - // Keep coordinates as low as possible - if(m_startPos.x() >= w && m_endPos.x() >= w) { - m_startPos.setX(fmod(m_startPos.x(), w)); - m_endPos.setX(fmod(m_endPos.x(), w)); - } - } - - // Same for y - if (std::abs((m_endPos.y() - m_startPos.y())) > (double)h / (double)2) { - if (m_startPos.y() < m_endPos.y()) { - while (m_startPos.y() < m_endPos.y()) - m_startPos.setY(m_startPos.y() + h); - - } else { - while (m_endPos.y() < m_startPos.y()) - m_endPos.setY(m_endPos.y() + h); - } - // Keep coordinates as low as possible - if(m_startPos.y() >= h && m_endPos.y() >= h) { - m_startPos.setY(fmod(m_startPos.y(), h)); - m_endPos.setY(fmod(m_endPos.y(), h)); - } - } -} - -/* - * Takes the point and uses modulus to keep draw position within [0, desktopGridWidth] - * The render loop will draw the first desktop (0) after the last one (at position desktopGridWidth) for the wrap animation. - * This function finds the true fastest path, regardless of which direction the animation is already going; - * I was a little upset about this limitation until I realized that MacOS can't even wrap desktops :) - */ -QPointF SlideEffect::constrainToDrawableRange(QPointF p) -{ - p.setX(fmod(p.x(), effects->desktopGridWidth())); - p.setY(fmod(p.y(), effects->desktopGridHeight())); - return p; -} - } // namespace KWin diff --git a/src/effects/slide/slide.h b/src/effects/slide/slide.h index 586b27d07c..c7c7ef572e 100644 --- a/src/effects/slide/slide.h +++ b/src/effects/slide/slide.h @@ -18,31 +18,6 @@ namespace KWin { -/* - * How it Works: - * - * This effect doesn't change the current desktop, only recieves changes from the VirtualDesktopManager. - * The only visually aparent inputs are desktopChanged() and desktopChanging(). - * - * When responding to desktopChanging(), the draw position is only affected by what's recieved from there. - * After desktopChanging() is done, or without desktopChanging() having been called at all, desktopChanged() is called. - * The desktopChanged() function configures the m_startPos and m_endPos for the animation, and the duration. - * - * m_currentPosition and m_paintCtx.translation and everything else not labeled "drawCoordinate" uses desktops as a unit. - * Exmp: 1.2 means the dekstop at index 1 shifted over by .2 desktops. - * All coords must be positive. - * - * For the wrapping effect, the render loop has to handle desktop coordinates larger than the total grid's width. - * 1. It uses modulus to keep the desktop coords in the range [0, gridWidth]. - * 2. It will draw the desktop at index 0 at index gridWidth if it has to. - * I will not draw any thing farther outside the range than that. - * - * I've put an explanation of all the important private vars down at the bottom. - * - * Good luck :) - */ - - class SlideEffect : public Effect { Q_OBJECT @@ -83,49 +58,40 @@ public: private Q_SLOTS: void desktopChanged(int old, int current, EffectWindow *with); - void desktopChanging(uint old, QPointF desktopOffset, EffectWindow* with); - void desktopChangingCancelled(); void windowAdded(EffectWindow *w); void windowDeleted(EffectWindow *w); private: - QPoint getDrawCoords(QPointF pos, EffectScreen *screen); + QPoint desktopCoords(int id) const; + QRect desktopGeometry(int id) const; + int workspaceWidth() const; + int workspaceHeight() const; + bool isTranslated(const EffectWindow *w) const; bool isPainted(const EffectWindow *w) const; bool shouldElevate(const EffectWindow *w) const; - QPointF moveInsideDesktopGrid(QPointF p); - QPointF constrainToDrawableRange(QPointF p); - QPointF forcePositivePosition(QPointF p) const; - void optimizePath(); //Find the best path to target desktop - void startAnimation(int old, int current, EffectWindow *movingWindow = nullptr); - void finishedSwitching(); + void start(int old, int current, EffectWindow *movingWindow = nullptr); + void stop(); private: int m_hGap; int m_vGap; bool m_slideDocks; bool m_slideBackground; - int m_animationDuration; // Miliseconds for 1 complete desktop switch bool m_active = false; TimeLine m_timeLine; - - // When the desktop isn't desktopChanging(), these two variables are used to control the animation path. - // They use desktops as a unit. - QPointF m_startPos; - QPointF m_endPos; - + QPoint m_startPos; + QPoint m_diff; EffectWindow *m_movingWindow = nullptr; std::chrono::milliseconds m_lastPresentTime = std::chrono::milliseconds::zero(); - bool m_gestureActive = false; // If we're currently animating a gesture - QPointF m_currentPosition; // Should always be kept up to date with where on the grid we're seeing. struct { int desktop; bool firstPass; bool lastPass; - QPointF translation; //Uses desktops as units + QPoint translation; EffectWindowList fullscreenWindows; } m_paintCtx; @@ -135,7 +101,7 @@ private: inline int SlideEffect::duration() const { - return m_animationDuration; + return m_timeLine.duration().count(); } inline int SlideEffect::horizontalGap() const