File indexing completed on 2024-12-08 04:58:27

0001 /*
0002     SPDX-FileCopyrightText: 2016 Smith AR <audoban@openmailbox.org>
0003     SPDX-FileCopyrightText: 2016 Michail Vourlakos <mvourlakos@gmail.com>
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef VISIBILITYMANAGER_H
0008 #define VISIBILITYMANAGER_H
0009 
0010 #include <array>
0011 
0012 // local
0013 #include <coretypes.h>
0014 #include "../plasma/quick/containmentview.h"
0015 
0016 // Qt
0017 #include <QObject>
0018 #include <QTimer>
0019 
0020 // Plasma
0021 #include <Plasma/Containment>
0022 
0023 
0024 namespace Latte {
0025 class Corona;
0026 class View;
0027 namespace ViewPart {
0028 class FloatingGapWindow;
0029 class ScreenEdgeGhostWindow;
0030 }
0031 namespace WindowSystem {
0032 class AbstractWindowInterface;
0033 }
0034 }
0035 
0036 namespace Latte {
0037 namespace ViewPart {
0038 
0039 class VisibilityManager : public QObject
0040 {
0041     Q_OBJECT
0042     Q_PROPERTY(bool hidingIsBlocked READ hidingIsBlocked NOTIFY hidingIsBlockedChanged)
0043 
0044     Q_PROPERTY(Latte::Types::Visibility mode READ mode WRITE setMode NOTIFY modeChanged)
0045     Q_PROPERTY(bool raiseOnDesktop READ raiseOnDesktop WRITE setRaiseOnDesktop NOTIFY raiseOnDesktopChanged)
0046     Q_PROPERTY(bool raiseOnActivity READ raiseOnActivity WRITE setRaiseOnActivity NOTIFY raiseOnActivityChanged)    
0047     Q_PROPERTY(bool isHidden READ isHidden WRITE setIsHidden NOTIFY isHiddenChanged)
0048     Q_PROPERTY(bool isShownFully READ isShownFully WRITE setIsShownFully NOTIFY isShownFullyChanged)
0049     Q_PROPERTY(bool isBelowLayer READ isBelowLayer NOTIFY isBelowLayerChanged)    
0050     Q_PROPERTY(bool isSidebar READ isSidebar NOTIFY isSidebarChanged)
0051     Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged)
0052 
0053     //! Floating Gap Window to identify mouse between the screenEdge and the view when it does not accept any other
0054     //! user input
0055     Q_PROPERTY(bool isFloatingGapWindowEnabled READ isFloatingGapWindowEnabled WRITE setIsFloatingGapWindowEnabled NOTIFY isFloatingGapWindowEnabledChanged)
0056 
0057     //! KWin Edges Support Options
0058     Q_PROPERTY(bool enableKWinEdges READ enableKWinEdges WRITE setEnableKWinEdges NOTIFY enableKWinEdgesChanged)
0059     Q_PROPERTY(bool supportsKWinEdges READ supportsKWinEdges NOTIFY supportsKWinEdgesChanged)
0060 
0061     Q_PROPERTY(int timerShow READ timerShow WRITE setTimerShow NOTIFY timerShowChanged)
0062     Q_PROPERTY(int timerHide READ timerHide WRITE setTimerHide NOTIFY timerHideChanged)
0063 
0064     //! Struts
0065     Q_PROPERTY(int strutsThickness READ strutsThickness WRITE setStrutsThickness NOTIFY strutsThicknessChanged)
0066 
0067 public:
0068     static const QRect ISHIDDENMASK;
0069 
0070     explicit VisibilityManager(PlasmaQuick::ContainmentView *view);
0071     virtual ~VisibilityManager();
0072 
0073     Latte::Types::Visibility mode() const;
0074     void setMode(Latte::Types::Visibility mode);
0075 
0076     void applyActivitiesToHiddenWindows(const QStringList &activities);
0077 
0078     bool raiseOnDesktop() const;
0079     void setRaiseOnDesktop(bool enable);
0080 
0081     bool raiseOnActivity() const;
0082     void setRaiseOnActivity(bool enable);
0083 
0084     bool isBelowLayer() const;
0085 
0086     bool isHidden() const;
0087     void setIsHidden(bool isHidden);
0088 
0089     bool isShownFully() const;
0090     void setIsShownFully(bool fully);
0091 
0092     bool hidingIsBlocked() const;
0093 
0094     bool containsMouse() const;
0095 
0096     bool isFloatingGapWindowEnabled() const;
0097     void setIsFloatingGapWindowEnabled(bool enabled);
0098 
0099     int timerShow() const;
0100     void setTimerShow(int msec);
0101 
0102     int timerHide() const;
0103     void setTimerHide(int msec);
0104 
0105     bool isSidebar() const;
0106     bool hasBlockHidingEvent(const QString &type);
0107 
0108     //! KWin Edges Support functions
0109     bool enableKWinEdges() const;
0110     void setEnableKWinEdges(bool enable);
0111 
0112     bool supportsKWinEdges() const;
0113 
0114     //! Struts
0115     int strutsThickness() const;
0116     void setStrutsThickness(int thickness);
0117 
0118     //! Used mostly to show / hide Sidebars
0119     void toggleHiddenState();
0120 
0121 public slots:
0122     Q_INVOKABLE void hide();
0123     Q_INVOKABLE void show();
0124 
0125     Q_INVOKABLE void setViewOnBackLayer();
0126     Q_INVOKABLE void setViewOnFrontLayer();
0127 
0128     Q_INVOKABLE void addBlockHidingEvent(const QString &type);
0129     Q_INVOKABLE void removeBlockHidingEvent(const QString &type);
0130 
0131     void initViewFlags();
0132 
0133 signals:
0134     void mustBeShown();
0135     void mustBeHide();
0136 
0137     void slideOutFinished();
0138     void slideInFinished();
0139 
0140     void frameExtentsCleared();
0141     void modeChanged();
0142     void raiseOnDesktopChanged();
0143     void raiseOnActivityChanged();
0144     void isBelowLayerChanged();
0145     void isFloatingGapWindowEnabledChanged();
0146     void isHiddenChanged();
0147     void isSidebarChanged();
0148     void isShownFullyChanged();
0149     void hidingIsBlockedChanged();
0150     void containsMouseChanged();
0151     void strutsThicknessChanged();
0152     void timerShowChanged();
0153     void timerHideChanged();
0154 
0155     //! KWin Edges Support signals
0156     void enableKWinEdgesChanged();
0157     void supportsKWinEdgesChanged();
0158 
0159 private slots:
0160     void saveConfig();
0161     void restoreConfig();
0162 
0163     void setIsBelowLayer(bool below);
0164 
0165     void onHeadThicknessChanged();
0166     void onHidingIsBlockedChanged();
0167     void onIsFloatingGapWindowEnabledChanged();
0168 
0169     void publishFrameExtents(bool forceUpdate = false); //! direct
0170 
0171     //! KWin Edges Support functions
0172     void updateKWinEdgesSupport();
0173 
0174     void updateSidebarState();
0175 
0176 private:
0177     void setContainsMouse(bool contains);
0178 
0179     void raiseView(bool raise);
0180     void raiseViewTemporarily();
0181 
0182     //! KWin Edges Support functions
0183     void createEdgeGhostWindow();
0184     void deleteEdgeGhostWindow();
0185     void updateGhostWindowState();
0186 
0187     //! Floating Gap Support functions
0188     void createFloatingGapWindow();
0189     void deleteFloatingGapWindow();
0190     bool supportsFloatingGap() const;
0191 
0192     void updateStrutsBasedOnLayoutsAndActivities(bool forceUpdate = false);
0193     void viewEventManager(QEvent *ev);
0194 
0195     void checkMouseInFloatingArea();
0196 
0197     bool windowContainsMouse();
0198 
0199     QRect acceptableStruts();
0200 
0201 private slots:
0202     void dodgeAllWindows();
0203     void dodgeActive();
0204     void dodgeMaximized();
0205     void updateHiddenState();
0206 
0207     void updateStrutsAfterTimer();
0208 
0209     bool isValidMode() const;
0210 
0211 private:
0212     void startTimerHide(const int &msec = 0);
0213 
0214     bool canSetStrut() const;
0215 
0216 private:
0217     WindowSystem::AbstractWindowInterface *m_wm;
0218     Types::Visibility m_mode{Types::None};
0219     std::array<QMetaObject::Connection, 6> m_connections;
0220 
0221     QTimer m_timerShow;
0222     QTimer m_timerHide;
0223     QTimer m_timerPublishFrameExtents;
0224     //! This timer is very important because it blocks how fast struts are updated.
0225     //! By using this timer we help the window manager in order to correspond to new
0226     //! struts (for example changing windows maximized state or geometry) without
0227     //! createing binding loops between the app and the window manager.
0228     //! That was reproducable in a floating panel when we were dragging the active window.
0229     QTimer m_timerBlockStrutsUpdate;
0230 
0231     bool m_isBelowLayer{false};
0232     bool m_isHidden{false};
0233     bool m_isFloatingGapWindowEnabled{false};
0234     bool m_isSidebar{false};
0235     bool m_isShownFully{false};
0236     bool m_dragEnter{false};
0237     bool m_containsMouse{false};
0238     bool m_raiseTemporarily{false};
0239     bool m_raiseOnDesktopChange{false};
0240     bool m_raiseOnActivityChange{false};
0241     bool m_hideNow{false};
0242 
0243     //! valid on demand sidebar hidden state in order to be checked after slide-ins/outs
0244     bool m_isRequestedShownSidebarOnDemand{false};
0245 
0246     int m_frameExtentsHeadThicknessGap{0};
0247     int m_timerHideInterval{700};
0248     Plasma::Types::Location m_frameExtentsLocation{Plasma::Types::BottomEdge};
0249 
0250     int m_strutsThickness{0};
0251 
0252     QStringList m_blockHidingEvents;
0253 
0254     QRect m_publishedStruts;
0255     QRect m_lastMask;
0256 
0257     //! KWin Edges
0258     bool m_enableKWinEdgesFromUser{true};
0259     std::array<QMetaObject::Connection, 1> m_connectionsKWinEdges;
0260     ScreenEdgeGhostWindow *m_edgeGhostWindow{nullptr};
0261 
0262     //! Floating Gap
0263     FloatingGapWindow *m_floatingGapWindow{nullptr};
0264 
0265     Latte::Corona *m_corona{nullptr};
0266     Latte::View *m_latteView{nullptr};
0267 
0268 };
0269 
0270 }
0271 }
0272 #endif // VISIBILITYMANAGER_H