File indexing completed on 2024-11-10 04:57:09
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2007 Lubos Lunak <l.lunak@kde.org> 0006 SPDX-FileCopyrightText: 2008 Lucas Murray <lmurray@undefinedfire.com> 0007 SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 */ 0011 0012 #pragma once 0013 0014 // kwineffects 0015 #include "effect/effect.h" 0016 #include "effect/effectwindow.h" 0017 #include "plugins/slide/springmotion.h" 0018 0019 namespace KWin 0020 { 0021 0022 /* 0023 * How it Works: 0024 * 0025 * This effect doesn't change the current desktop, only recieves changes from the VirtualDesktopManager. 0026 * The only visually aparent inputs are desktopChanged() and desktopChanging(). 0027 * 0028 * When responding to desktopChanging(), the draw position is only affected by what's recieved from there. 0029 * After desktopChanging() is done, or without desktopChanging() having been called at all, desktopChanged() is called. 0030 * The desktopChanged() function configures the m_startPos and m_endPos for the animation, and the duration. 0031 * 0032 * m_currentPosition and everything else not labeled "drawCoordinate" uses desktops as a unit. 0033 * Exmp: 1.2 means the dekstop at index 1 shifted over by .2 desktops. 0034 * All coords must be positive. 0035 * 0036 * For the wrapping effect, the render loop has to handle desktop coordinates larger than the total grid's width. 0037 * 1. It uses modulus to keep the desktop coords in the range [0, gridWidth]. 0038 * 2. It will draw the desktop at index 0 at index gridWidth if it has to. 0039 * I will not draw any thing farther outside the range than that. 0040 * 0041 * I've put an explanation of all the important private vars down at the bottom. 0042 * 0043 * Good luck :) 0044 */ 0045 0046 class SlideEffect : public Effect 0047 { 0048 Q_OBJECT 0049 Q_PROPERTY(int horizontalGap READ horizontalGap) 0050 Q_PROPERTY(int verticalGap READ verticalGap) 0051 Q_PROPERTY(bool slideBackground READ slideBackground) 0052 0053 public: 0054 SlideEffect(); 0055 ~SlideEffect() override; 0056 0057 void reconfigure(ReconfigureFlags) override; 0058 0059 void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override; 0060 void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion ®ion, Output *screen) override; 0061 void postPaintScreen() override; 0062 0063 void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override; 0064 void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override; 0065 0066 bool isActive() const override; 0067 int requestedEffectChainPosition() const override; 0068 0069 static bool supported(); 0070 0071 int horizontalGap() const; 0072 int verticalGap() const; 0073 bool slideBackground() const; 0074 0075 private Q_SLOTS: 0076 void desktopChanged(VirtualDesktop *old, VirtualDesktop *current, EffectWindow *with); 0077 void desktopChanging(VirtualDesktop *old, QPointF desktopOffset, EffectWindow *with); 0078 void desktopChangingCancelled(); 0079 void windowAdded(EffectWindow *w); 0080 void windowDeleted(EffectWindow *w); 0081 0082 private: 0083 QPoint getDrawCoords(QPointF pos, Output *screen); 0084 bool isTranslated(const EffectWindow *w) const; 0085 bool willBePainted(const EffectWindow *w) const; 0086 bool shouldElevate(const EffectWindow *w) const; 0087 QPointF moveInsideDesktopGrid(QPointF p); 0088 QPointF constrainToDrawableRange(QPointF p); 0089 QPointF forcePositivePosition(QPointF p) const; 0090 void optimizePath(); // Find the best path to target desktop 0091 0092 void startAnimation(VirtualDesktop *old, VirtualDesktop *current, EffectWindow *movingWindow = nullptr); 0093 void prepareSwitching(); 0094 void finishedSwitching(); 0095 0096 private: 0097 int m_hGap; 0098 int m_vGap; 0099 bool m_slideBackground; 0100 0101 enum class State { 0102 Inactive, 0103 ActiveAnimation, 0104 ActiveGesture, 0105 }; 0106 0107 State m_state = State::Inactive; 0108 SpringMotion m_motionX; 0109 SpringMotion m_motionY; 0110 0111 // When the desktop isn't desktopChanging(), these two variables are used to control the animation path. 0112 // They use desktops as a unit. 0113 QPointF m_startPos; 0114 QPointF m_endPos; 0115 0116 EffectWindow *m_movingWindow = nullptr; 0117 std::chrono::milliseconds m_lastPresentTime = std::chrono::milliseconds::zero(); 0118 QPointF m_currentPosition; // Should always be kept up to date with where on the grid we're seeing. 0119 0120 struct 0121 { 0122 bool wrap; 0123 QList<VirtualDesktop *> visibleDesktops; 0124 } m_paintCtx; 0125 0126 struct WindowData 0127 { 0128 EffectWindowVisibleRef visibilityRef; 0129 }; 0130 0131 QList<EffectWindow *> m_elevatedWindows; 0132 QHash<EffectWindow *, WindowData> m_windowData; 0133 }; 0134 0135 inline int SlideEffect::horizontalGap() const 0136 { 0137 return m_hGap; 0138 } 0139 0140 inline int SlideEffect::verticalGap() const 0141 { 0142 return m_vGap; 0143 } 0144 0145 inline bool SlideEffect::slideBackground() const 0146 { 0147 return m_slideBackground; 0148 } 0149 0150 inline bool SlideEffect::isActive() const 0151 { 0152 return m_state != State::Inactive; 0153 } 0154 0155 inline int SlideEffect::requestedEffectChainPosition() const 0156 { 0157 return 50; 0158 } 0159 0160 } // namespace KWin