File indexing completed on 2024-12-08 08:00:13

0001 /*
0002     SPDX-FileCopyrightText: 2018 Michail Vourlakos <mvourlakos@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #ifndef POSITIONER_H
0007 #define POSITIONER_H
0008 
0009 //local
0010 #include <coretypes.h>
0011 #include "../wm/abstractwindowinterface.h"
0012 #include "../wm/windowinfowrap.h"
0013 
0014 // Qt
0015 #include <QObject>
0016 #include <QPointer>
0017 #include <QScreen>
0018 #include <QTimer>
0019 
0020 // Plasma
0021 #include <Plasma/Containment>
0022 
0023 namespace Plasma {
0024 class Types;
0025 }
0026 
0027 namespace Latte {
0028 class Corona;
0029 class View;
0030 }
0031 
0032 namespace Latte {
0033 namespace ViewPart {
0034 
0035 class Positioner: public QObject
0036 {
0037     Q_OBJECT
0038 
0039     Q_PROPERTY(bool inRelocationAnimation READ inRelocationAnimation NOTIFY inRelocationAnimationChanged)
0040     Q_PROPERTY(bool inRelocationShowing READ inRelocationShowing WRITE setInRelocationShowing NOTIFY inRelocationShowingChanged)
0041     Q_PROPERTY(bool inSlideAnimation READ inSlideAnimation WRITE setInSlideAnimation NOTIFY inSlideAnimationChanged)
0042 
0043     Q_PROPERTY(bool isOffScreen READ isOffScreen NOTIFY isOffScreenChanged)
0044     Q_PROPERTY(bool isStickedOnTopEdge READ isStickedOnTopEdge WRITE setIsStickedOnTopEdge NOTIFY isStickedOnTopEdgeChanged)
0045     Q_PROPERTY(bool isStickedOnBottomEdge READ isStickedOnBottomEdge WRITE setIsStickedOnBottomEdge NOTIFY isStickedOnBottomEdgeChanged)
0046 
0047     Q_PROPERTY(int currentScreenId READ currentScreenId NOTIFY currentScreenChanged)
0048 
0049     Q_PROPERTY(QRect canvasGeometry READ canvasGeometry NOTIFY canvasGeometryChanged)
0050 
0051     //! animating window slide
0052     Q_PROPERTY(int slideOffset READ slideOffset WRITE setSlideOffset NOTIFY slideOffsetChanged)
0053     Q_PROPERTY(QString currentScreenName READ currentScreenName NOTIFY currentScreenChanged)
0054 
0055 public:
0056     Positioner(Latte::View *parent);
0057     virtual ~Positioner();
0058 
0059     int currentScreenId() const;
0060     QString currentScreenName() const;
0061 
0062     int slideOffset() const;
0063     void setSlideOffset(int offset);
0064 
0065     bool inLayoutUnloading();
0066     bool inRelocationAnimation();
0067 
0068     bool inRelocationShowing() const;
0069     void setInRelocationShowing(bool active);
0070 
0071     bool inSlideAnimation() const;
0072     void setInSlideAnimation(bool active);
0073 
0074     bool isCursorInsideView() const;
0075 
0076     bool isStickedOnTopEdge() const;
0077     void setIsStickedOnTopEdge(bool sticked);
0078 
0079     bool isStickedOnBottomEdge() const;
0080     void setIsStickedOnBottomEdge(bool sticked);
0081 
0082     bool isOffScreen() const;
0083 
0084     QRect canvasGeometry();
0085 
0086     void setScreenToFollow(QScreen *scr, bool updateScreenId = true);
0087     void setWindowOnActivities(const Latte::WindowSystem::WindowId &wid, const QStringList &activities);
0088 
0089     void reconsiderScreen();
0090 
0091     Latte::WindowSystem::WindowId trackedWindowId();
0092 
0093 public slots:
0094     Q_INVOKABLE void setNextLocation(const QString layoutName, const int screensGroup, QString screenName, int edge, int alignment);
0095     Q_INVOKABLE void slideInDuringStartup();
0096 
0097     void syncGeometry();
0098 
0099     //! direct geometry calculations without any protections or checks
0100     //! that might prevent them. It must be called with care.
0101     void immediateSyncGeometry();
0102 
0103     void slideOutDuringExit(Plasma::Types::Location location = Plasma::Types::Floating);
0104 
0105     void initDelayedSignals();
0106     void updateWaylandId();
0107 
0108 signals:
0109     void canvasGeometryChanged();
0110     void currentScreenChanged();
0111     void edgeChanged();
0112     void screenGeometryChanged();
0113     void slideOffsetChanged();
0114     void windowSizeChanged();
0115     void winIdChanged();
0116 
0117     //! these two signals are used from config ui and containment ui
0118     //! in order to orchestrate an animated hiding/showing of dock
0119     //! during changing location
0120     void hidingForRelocationStarted();
0121     void hidingForRelocationFinished();
0122     void showingAfterRelocationFinished();
0123 
0124     void startupFinished(); //called from containment qml end of startup sequence
0125 
0126     void onHideWindowsForSlidingOut();
0127     void inRelocationAnimationChanged();
0128     void inRelocationShowingChanged();
0129     void inSlideAnimationChanged();
0130     void isOffScreenChanged();
0131     void isStickedOnTopEdgeChanged();
0132     void isStickedOnBottomEdgeChanged();
0133 
0134 private slots:
0135     void onScreenChanged(QScreen *screen);
0136     void onCurrentLayoutIsSwitching(const QString &layoutName);
0137     void onLastRepositionApplyEvent();
0138     void onStartupFinished();
0139 
0140     void validateDockGeometry();
0141     void updateInRelocationAnimation();
0142     void syncLatteViews();
0143     void updateContainmentScreen();
0144 
0145 private:
0146     void init();
0147     void initSignalingForLocationChangeSliding();
0148 
0149     void updateFormFactor();
0150     void resizeWindow(QRect availableScreenRect = QRect());
0151     void updatePosition(QRect availableScreenRect = QRect());
0152     void updateCanvasGeometry(QRect availableScreenRect = QRect());
0153 
0154     void validateTopBottomBorders(QRect availableScreenRect, QRegion availableScreenRegion);
0155 
0156     void setCanvasGeometry(const QRect &geometry);
0157 
0158     bool isLastHidingRelocationEvent() const;
0159 
0160     QRect maximumNormalGeometry(QRect screenGeometry = QRect());
0161 
0162     WindowSystem::AbstractWindowInterface::Slide slideLocation(Plasma::Types::Location location);
0163 
0164 private:
0165     bool m_inDelete{false};
0166     bool m_inLayoutUnloading{false};
0167     bool m_inRelocationAnimation{false};
0168     bool m_inRelocationShowing{false};
0169     bool m_inSlideAnimation{false};
0170     bool m_inStartup{true};
0171 
0172     bool m_isStickedOnTopEdge{false};
0173     bool m_isStickedOnBottomEdge{false};
0174 
0175     int m_slideOffset{0};
0176 
0177     QRect m_canvasGeometry;
0178     //! it is used in order to enforce X11 to never miss window geometry
0179     QRect m_validGeometry;
0180     //! it is used to update geometry calculations without requesting no needed Corona calculations
0181     QRect m_lastAvailableScreenRect;
0182     QRegion m_lastAvailableScreenRegion;
0183 
0184     QPointer<Latte::View> m_view;
0185     QPointer<Latte::Corona> m_corona;
0186 
0187     QString m_screenNameToFollow;
0188     QPointer<QScreen> m_screenToFollow;
0189     QTimer m_screenSyncTimer;
0190     QTimer m_syncGeometryTimer;
0191     QTimer m_validateGeometryTimer;
0192 
0193     //!used for relocation properties group
0194     bool m_repositionFromViewSettingsWindow{false};
0195     bool m_repositionIsAnimated{false};
0196 
0197     QString m_nextLayoutName;
0198     Latte::Types::ScreensGroup m_nextScreensGroup{Latte::Types::SingleScreenGroup};
0199     QString m_nextScreenName;
0200     QScreen *m_nextScreen{nullptr};
0201     Plasma::Types::Location m_nextScreenEdge{Plasma::Types::Floating};
0202     Latte::Types::Alignment m_nextAlignment{Latte::Types::NoneAlignment};
0203 
0204     Latte::WindowSystem::WindowId m_trackedWindowId;
0205 };
0206 
0207 }
0208 }
0209 
0210 #endif