File indexing completed on 2024-11-10 04:57:13
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2008 Cédric Borgese <cedric.borgese@gmail.com> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #pragma once 0011 0012 // Include with base class for effects. 0013 #include "effect/offscreeneffect.h" 0014 0015 namespace KWin 0016 { 0017 0018 struct ParameterSet; 0019 0020 /** 0021 * Effect which wobble windows 0022 */ 0023 class WobblyWindowsEffect : public OffscreenEffect 0024 { 0025 Q_OBJECT 0026 Q_PROPERTY(qreal stiffness READ stiffness) 0027 Q_PROPERTY(qreal drag READ drag) 0028 Q_PROPERTY(qreal moveFactor READ moveFactor) 0029 Q_PROPERTY(qreal xTesselation READ xTesselation) 0030 Q_PROPERTY(qreal yTesselation READ yTesselation) 0031 Q_PROPERTY(qreal minVelocity READ minVelocity) 0032 Q_PROPERTY(qreal maxVelocity READ maxVelocity) 0033 Q_PROPERTY(qreal stopVelocity READ stopVelocity) 0034 Q_PROPERTY(qreal minAcceleration READ minAcceleration) 0035 Q_PROPERTY(qreal maxAcceleration READ maxAcceleration) 0036 Q_PROPERTY(qreal stopAcceleration READ stopAcceleration) 0037 Q_PROPERTY(bool moveWobble READ isMoveWobble) 0038 Q_PROPERTY(bool resizeWobble READ isResizeWobble) 0039 public: 0040 WobblyWindowsEffect(); 0041 ~WobblyWindowsEffect() override; 0042 0043 void reconfigure(ReconfigureFlags) override; 0044 void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override; 0045 void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override; 0046 void postPaintScreen() override; 0047 bool isActive() const override; 0048 0049 int requestedEffectChainPosition() const override 0050 { 0051 // Please notice that the Wobbly Windows effect has to be placed 0052 // after the Maximize effect in the effect chain, otherwise there 0053 // can be visual artifacts when dragging maximized windows. 0054 return 70; 0055 } 0056 0057 // Wobbly model parameters 0058 void setStiffness(qreal stiffness); 0059 void setDrag(qreal drag); 0060 void setVelocityThreshold(qreal velocityThreshold); 0061 void setMoveFactor(qreal factor); 0062 0063 struct Pair 0064 { 0065 qreal x; 0066 qreal y; 0067 }; 0068 0069 enum WindowStatus { 0070 Free, 0071 Moving, 0072 }; 0073 0074 static bool supported(); 0075 0076 // for properties 0077 qreal stiffness() const; 0078 qreal drag() const; 0079 qreal moveFactor() const; 0080 qreal xTesselation() const; 0081 qreal yTesselation() const; 0082 qreal minVelocity() const; 0083 qreal maxVelocity() const; 0084 qreal stopVelocity() const; 0085 qreal minAcceleration() const; 0086 qreal maxAcceleration() const; 0087 qreal stopAcceleration() const; 0088 bool isMoveWobble() const; 0089 bool isResizeWobble() const; 0090 0091 protected: 0092 void apply(EffectWindow *w, int mask, WindowPaintData &data, WindowQuadList &quads) override; 0093 0094 public Q_SLOTS: 0095 void slotWindowAdded(KWin::EffectWindow *w); 0096 void slotWindowStartUserMovedResized(KWin::EffectWindow *w); 0097 void slotWindowStepUserMovedResized(KWin::EffectWindow *w, const QRectF &geometry); 0098 void slotWindowFinishUserMovedResized(KWin::EffectWindow *w); 0099 void slotWindowMaximizeStateChanged(KWin::EffectWindow *w, bool horizontal, bool vertical); 0100 0101 private: 0102 void startMovedResized(EffectWindow *w); 0103 void stepMovedResized(EffectWindow *w); 0104 bool updateWindowWobblyDatas(EffectWindow *w, qreal time); 0105 0106 struct WindowWobblyInfos 0107 { 0108 QList<Pair> origin; 0109 QList<Pair> position; 0110 QList<Pair> velocity; 0111 QList<Pair> acceleration; 0112 QList<Pair> buffer; 0113 0114 // if true, the physics system moves this point based only on it "normal" destination 0115 // given by the window position, ignoring neighbour points. 0116 QList<bool> constraint; 0117 0118 unsigned int width; 0119 unsigned int height; 0120 unsigned int count; 0121 0122 QList<Pair> bezierSurface; 0123 unsigned int bezierWidth; 0124 unsigned int bezierHeight; 0125 unsigned int bezierCount; 0126 0127 WindowStatus status; 0128 bool wobblying = false; 0129 0130 // for resizing. Only sides that have moved will wobble 0131 bool can_wobble_top, can_wobble_left, can_wobble_right, can_wobble_bottom; 0132 QRectF resize_original_rect; 0133 0134 std::chrono::milliseconds clock; 0135 }; 0136 0137 QHash<const EffectWindow *, WindowWobblyInfos> windows; 0138 0139 QRegion m_updateRegion; 0140 0141 qreal m_stiffness; 0142 qreal m_drag; 0143 qreal m_move_factor; 0144 0145 // the default tesselation for windows 0146 // use qreal instead of int as I really often need 0147 // these values as real to do divisions. 0148 qreal m_xTesselation; 0149 qreal m_yTesselation; 0150 0151 qreal m_minVelocity; 0152 qreal m_maxVelocity; 0153 qreal m_stopVelocity; 0154 qreal m_minAcceleration; 0155 qreal m_maxAcceleration; 0156 qreal m_stopAcceleration; 0157 0158 bool m_moveWobble; 0159 bool m_resizeWobble; 0160 0161 void initWobblyInfo(WindowWobblyInfos &wwi, QRectF geometry) const; 0162 0163 WobblyWindowsEffect::Pair computeBezierPoint(const WindowWobblyInfos &wwi, Pair point) const; 0164 0165 static void heightRingLinearMean(QList<Pair> &data, WindowWobblyInfos &wwi); 0166 0167 void setParameterSet(const ParameterSet &pset); 0168 }; 0169 0170 } // namespace KWin