18#include "slideconfig.h"
31 this, &SlideEffect::desktopChanged);
33 this, &SlideEffect::desktopChanging);
35 this, &SlideEffect::desktopChangingCancelled);
37 this, &SlideEffect::windowAdded);
39 this, &SlideEffect::windowDeleted);
41 this, &SlideEffect::finishedSwitching);
43 this, &SlideEffect::finishedSwitching);
45 this, &SlideEffect::finishedSwitching);
47 this, &SlideEffect::finishedSwitching);
64 SlideConfig::self()->read();
67 const qreal dampingRatio = 1.1;
72 m_hGap = SlideConfig::horizontalGap();
73 m_vGap = SlideConfig::verticalGap();
74 m_slideBackground = SlideConfig::slideBackground();
80 QRegion r = QRect(pos, screenSize);
82 r += (r & QRect(-w, 0, w, h)).translated(w, 0);
83 r += (r & QRect(w, 0, w, h)).translated(-w, 0);
85 r += (r & QRect(0, -h, w, h)).translated(0, h);
86 r += (r & QRect(0, h, w, h)).translated(0, -h);
88 r += (r & QRect(-w, -h, w, h)).translated(w, h);
89 r += (r & QRect(w, -h, w, h)).translated(-w, h);
90 r += (r & QRect(w, h, w, h)).translated(-w, -h);
91 r += (r & QRect(-w, h, w, h)).translated(w, -h);
98 std::chrono::milliseconds timeDelta = std::chrono::milliseconds::zero();
99 if (m_lastPresentTime.count()) {
100 timeDelta = presentTime - m_lastPresentTime;
102 m_lastPresentTime = presentTime;
104 if (m_state == State::ActiveAnimation) {
108 m_currentPosition.setX(m_motionX.
position() / virtualSpaceSize.width());
109 m_currentPosition.setY(m_motionY.
position() / virtualSpaceSize.height());
117 m_paintCtx.visibleDesktops.clear();
118 m_paintCtx.visibleDesktops.reserve(4);
119 bool includedX =
false, includedY =
false;
122 if (coords.x() % w == (int)(m_currentPosition.x()) % w) {
124 }
else if (coords.x() % w == ((int)(m_currentPosition.x()) + 1) % w) {
127 if (coords.y() % h == (int)(m_currentPosition.y()) % h) {
129 }
else if (coords.y() % h == ((int)(m_currentPosition.y()) + 1) % h) {
133 if (includedX && includedY) {
134 m_paintCtx.visibleDesktops << desktop;
149QPoint SlideEffect::getDrawCoords(QPointF pos,
Output *screen)
152 c.setX(pos.x() * (screen->
geometry().width() + m_hGap));
153 c.setY(pos.y() * (screen->
geometry().height() + m_vGap));
161bool SlideEffect::isTranslated(
const EffectWindow *w)
const
163 if (w->isOnAllDesktops()) {
164 if (w->isDesktop()) {
165 return m_slideBackground;
168 }
else if (w == m_movingWindow) {
177bool SlideEffect::willBePainted(
const EffectWindow *w)
const
179 if (w->isOnAllDesktops()) {
182 if (w == m_movingWindow) {
185 for (VirtualDesktop *desktop : std::as_const(m_paintCtx.
visibleDesktops)) {
186 if (w->isOnDesktop(desktop)) {
201 if (!willBePainted(w)) {
205 if (!isTranslated(w)) {
213 QPointF drawPosition = forcePositivePosition(m_currentPosition);
214 drawPosition = m_paintCtx.wrap ? constrainToDrawableRange(drawPosition) : drawPosition;
217 const bool wrappingX = drawPosition.x() > gridWidth - 1;
218 const bool wrappingY = drawPosition.y() > gridHeight - 1;
222 for (
VirtualDesktop *desktop : std::as_const(m_paintCtx.visibleDesktops)) {
229 desktopTranslation = QPointF(desktopTranslation.x() + gridWidth, desktopTranslation.y());
232 desktopTranslation = QPointF(desktopTranslation.x(), desktopTranslation.y() + gridHeight);
235 for (
Output *screen : screens) {
236 QPoint drawTranslation = getDrawCoords(desktopTranslation, screen);
237 data += drawTranslation;
239 const QRect screenArea = screen->
geometry();
240 const QRect damage = screenArea.translated(drawTranslation).intersected(screenArea);
243 renderTarget, viewport, w, mask,
245 region.intersected(damage),
249 data += QPoint(-drawTranslation.x(), -drawTranslation.y());
256 if (m_state == State::ActiveAnimation && !m_motionX.
isMoving() && !m_motionY.
isMoving()) {
267QPointF SlideEffect::forcePositivePosition(QPointF p)
const
278bool SlideEffect::shouldElevate(
const EffectWindow *w)
const
291void SlideEffect::startAnimation(VirtualDesktop *old, VirtualDesktop *current, EffectWindow *movingWindow)
293 if (m_state == State::Inactive) {
297 m_state = State::ActiveAnimation;
298 m_movingWindow = movingWindow;
300 m_startPos = m_currentPosition;
307 m_motionX.
setAnchor(m_endPos.x() * virtualSpaceSize.width());
308 m_motionX.
setPosition(m_startPos.x() * virtualSpaceSize.width());
309 m_motionY.
setAnchor(m_endPos.y() * virtualSpaceSize.height());
310 m_motionY.
setPosition(m_startPos.y() * virtualSpaceSize.height());
316void SlideEffect::prepareSwitching()
319 m_windowData.reserve(windows.count());
321 for (EffectWindow *w : windows) {
322 m_windowData[w] = WindowData{
326 if (shouldElevate(w)) {
328 m_elevatedWindows << w;
335void SlideEffect::finishedSwitching()
337 if (m_state == State::Inactive) {
341 for (EffectWindow *w : windows) {
346 for (EffectWindow *w : std::as_const(m_elevatedWindows)) {
349 m_elevatedWindows.clear();
351 m_windowData.clear();
352 m_movingWindow =
nullptr;
353 m_state = State::Inactive;
354 m_lastPresentTime = std::chrono::milliseconds::zero();
359void SlideEffect::desktopChanged(VirtualDesktop *old, VirtualDesktop *current, EffectWindow *with)
366 startAnimation(old, current, with);
369void SlideEffect::desktopChanging(VirtualDesktop *old, QPointF desktopOffset, EffectWindow *with)
375 if (m_state == State::Inactive) {
379 m_state = State::ActiveGesture;
380 m_movingWindow = with;
384 m_currentPosition.setX(gridPos.x() + desktopOffset.x());
385 m_currentPosition.setY(gridPos.y() + desktopOffset.y());
388 m_currentPosition = forcePositivePosition(m_currentPosition);
390 m_currentPosition = moveInsideDesktopGrid(m_currentPosition);
397void SlideEffect::desktopChangingCancelled()
406QPointF SlideEffect::moveInsideDesktopGrid(QPointF p)
423void SlideEffect::windowAdded(EffectWindow *w)
425 if (m_state == State::Inactive) {
428 if (shouldElevate(w)) {
430 m_elevatedWindows << w;
435 m_windowData[w] = WindowData{
440void SlideEffect::windowDeleted(EffectWindow *w)
442 if (m_state == State::Inactive) {
445 if (w == m_movingWindow) {
446 m_movingWindow =
nullptr;
448 m_elevatedWindows.removeAll(w);
449 m_windowData.remove(w);
457void SlideEffect::optimizePath()
463 if (m_startPos.x() >= w && m_endPos.x() >= w) {
464 m_startPos.setX(fmod(m_startPos.x(), w));
465 m_endPos.setX(fmod(m_endPos.x(), w));
467 if (m_startPos.y() >= h && m_endPos.y() >= h) {
468 m_startPos.setY(fmod(m_startPos.y(), h));
469 m_endPos.setY(fmod(m_endPos.y(), h));
475 if (std::abs((m_startPos.x() - m_endPos.x())) > w / 2.0) {
476 if (m_startPos.x() < m_endPos.x()) {
477 while (m_startPos.x() < m_endPos.x()) {
478 m_startPos.setX(m_startPos.x() + w);
481 while (m_endPos.x() < m_startPos.x()) {
482 m_endPos.setX(m_endPos.x() + w);
486 if (m_startPos.x() >= w && m_endPos.x() >= w) {
487 m_startPos.setX(fmod(m_startPos.x(), w));
488 m_endPos.setX(fmod(m_endPos.x(), w));
493 if (std::abs((m_endPos.y() - m_startPos.y())) > (
double)h / (
double)2) {
494 if (m_startPos.y() < m_endPos.y()) {
495 while (m_startPos.y() < m_endPos.y()) {
496 m_startPos.setY(m_startPos.y() + h);
499 while (m_endPos.y() < m_startPos.y()) {
500 m_endPos.setY(m_endPos.y() + h);
504 if (m_startPos.y() >= h && m_endPos.y() >= h) {
505 m_startPos.setY(fmod(m_startPos.y(), h));
506 m_endPos.setY(fmod(m_endPos.y(), h));
517QPointF SlideEffect::constrainToDrawableRange(QPointF p)
526#include "moc_slide.cpp"
Representation of a window used by/for Effect classes.
Q_SCRIPTABLE bool isOnDesktop(KWin::VirtualDesktop *desktop) const
@ PAINT_DISABLED_BY_DESKTOP
void screenAdded(KWin::Output *screen)
void windowDeleted(KWin::EffectWindow *w)
bool animationsSupported() const
QPoint desktopGridCoords(VirtualDesktop *desktop) const
void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion ®ion, Output *screen)
void screenRemoved(KWin::Output *screen)
void desktopChanging(KWin::VirtualDesktop *currentDesktop, QPointF offset, KWin::EffectWindow *with)
bool hasActiveFullScreenEffect
QList< EffectWindow * > stackingOrder
Q_SCRIPTABLE void setElevatedWindow(KWin::EffectWindow *w, bool set)
void setActiveFullScreenEffect(Effect *e)
void desktopRemoved(KWin::VirtualDesktop *desktop)
void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data)
KWin::VirtualDesktop * currentDesktop
void desktopAdded(KWin::VirtualDesktop *desktop)
bool optionRollOverDesktops
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
QList< Output * > screens() const
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
void desktopChanged(KWin::VirtualDesktop *oldDesktop, KWin::VirtualDesktop *newDesktop, KWin::EffectWindow *with)
void desktopChangingCancelled()
QList< KWin::VirtualDesktop * > desktops
KSharedConfigPtr config() const
qreal animationTimeFactor
void windowAdded(KWin::EffectWindow *w)
Q_SCRIPTABLE void addRepaintFull()
Effect * activeFullScreenEffect() const
void reconfigure(ReconfigureFlags) override
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override
void postPaintScreen() override
void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override
QList< VirtualDesktop * > visibleDesktops
void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion ®ion, Output *screen) override
void advance(std::chrono::milliseconds delta)
void setPosition(qreal position)
void setAnchor(qreal anchor)
@ PAINT_SCREEN_TRANSFORMED
@ PAINT_SCREEN_BACKGROUND_FIRST
@ WindowForceBackgroundContrastRole
For fullscreen effects to enforce the background contrast,.
@ WindowForceBlurRole
For fullscreen effects to enforce blurring of windows,.
QRegion buildClipRegion(const QPoint &pos, int w, int h)