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