1 /* 2 SPDX-FileCopyrightText: 2016 Smith AR <audoban@openmailbox.org> 3 SPDX-FileCopyrightText: 2016 Michail Vourlakos <mvourlakos@gmail.com> 4 SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 7 #ifndef VISIBILITYMANAGER_H 8 #define VISIBILITYMANAGER_H 9 10 #include <array> 11 12 // local 13 #include <coretypes.h> 14 #include "../plasma/quick/containmentview.h" 15 16 #include <array> 17 18 // Qt 19 #include <QObject> 20 #include <QTimer> 21 22 // Plasma 23 #include <Plasma/Containment> 24 25 26 namespace Latte { 27 class Corona; 28 class View; 29 namespace ViewPart { 30 class FloatingGapWindow; 31 class ScreenEdgeGhostWindow; 32 } 33 namespace WindowSystem { 34 class AbstractWindowInterface; 35 } 36 } 37 38 namespace Latte { 39 namespace ViewPart { 40 41 class VisibilityManager : public QObject 42 { 43 Q_OBJECT 44 Q_PROPERTY(bool hidingIsBlocked READ hidingIsBlocked NOTIFY hidingIsBlockedChanged) 45 46 Q_PROPERTY(Latte::Types::Visibility mode READ mode WRITE setMode NOTIFY modeChanged) 47 Q_PROPERTY(bool raiseOnDesktop READ raiseOnDesktop WRITE setRaiseOnDesktop NOTIFY raiseOnDesktopChanged) 48 Q_PROPERTY(bool raiseOnActivity READ raiseOnActivity WRITE setRaiseOnActivity NOTIFY raiseOnActivityChanged) 49 Q_PROPERTY(bool isHidden READ isHidden WRITE setIsHidden NOTIFY isHiddenChanged) 50 Q_PROPERTY(bool isShownFully READ isShownFully WRITE setIsShownFully NOTIFY isShownFullyChanged) 51 Q_PROPERTY(bool isBelowLayer READ isBelowLayer NOTIFY isBelowLayerChanged) 52 Q_PROPERTY(bool isSidebar READ isSidebar NOTIFY isSidebarChanged) 53 Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged) 54 55 //! Floating Gap Window to identify mouse between the screenEdge and the view when it does not accept any other 56 //! user input 57 Q_PROPERTY(bool isFloatingGapWindowEnabled READ isFloatingGapWindowEnabled WRITE setIsFloatingGapWindowEnabled NOTIFY isFloatingGapWindowEnabledChanged) 58 59 //! KWin Edges Support Options 60 Q_PROPERTY(bool enableKWinEdges READ enableKWinEdges WRITE setEnableKWinEdges NOTIFY enableKWinEdgesChanged) 61 Q_PROPERTY(bool supportsKWinEdges READ supportsKWinEdges NOTIFY supportsKWinEdgesChanged) 62 63 Q_PROPERTY(int timerShow READ timerShow WRITE setTimerShow NOTIFY timerShowChanged) 64 Q_PROPERTY(int timerHide READ timerHide WRITE setTimerHide NOTIFY timerHideChanged) 65 66 //! Struts 67 Q_PROPERTY(int strutsThickness READ strutsThickness WRITE setStrutsThickness NOTIFY strutsThicknessChanged) 68 69 public: 70 static const QRect ISHIDDENMASK; 71 72 explicit VisibilityManager(PlasmaQuick::ContainmentView *view); 73 virtual ~VisibilityManager(); 74 75 Latte::Types::Visibility mode() const; 76 void setMode(Latte::Types::Visibility mode); 77 78 void applyActivitiesToHiddenWindows(const QStringList &activities); 79 80 bool raiseOnDesktop() const; 81 void setRaiseOnDesktop(bool enable); 82 83 bool raiseOnActivity() const; 84 void setRaiseOnActivity(bool enable); 85 86 bool isBelowLayer() const; 87 88 bool isHidden() const; 89 void setIsHidden(bool isHidden); 90 91 bool isShownFully() const; 92 void setIsShownFully(bool fully); 93 94 bool hidingIsBlocked() const; 95 96 bool containsMouse() const; 97 98 bool isFloatingGapWindowEnabled() const; 99 void setIsFloatingGapWindowEnabled(bool enabled); 100 101 int timerShow() const; 102 void setTimerShow(int msec); 103 104 int timerHide() const; 105 void setTimerHide(int msec); 106 107 bool isSidebar() const; 108 bool hasBlockHidingEvent(const QString &type); 109 110 //! KWin Edges Support functions 111 bool enableKWinEdges() const; 112 void setEnableKWinEdges(bool enable); 113 114 bool supportsKWinEdges() const; 115 116 //! Struts 117 int strutsThickness() const; 118 void setStrutsThickness(int thickness); 119 120 //! Used mostly to show / hide Sidebars 121 void toggleHiddenState(); 122 123 public slots: 124 Q_INVOKABLE void hide(); 125 Q_INVOKABLE void show(); 126 127 Q_INVOKABLE void setViewOnBackLayer(); 128 Q_INVOKABLE void setViewOnFrontLayer(); 129 130 Q_INVOKABLE void addBlockHidingEvent(const QString &type); 131 Q_INVOKABLE void removeBlockHidingEvent(const QString &type); 132 133 void initViewFlags(); 134 135 signals: 136 void mustBeShown(); 137 void mustBeHide(); 138 139 void slideOutFinished(); 140 void slideInFinished(); 141 142 void frameExtentsCleared(); 143 void modeChanged(); 144 void raiseOnDesktopChanged(); 145 void raiseOnActivityChanged(); 146 void isBelowLayerChanged(); 147 void isFloatingGapWindowEnabledChanged(); 148 void isHiddenChanged(); 149 void isSidebarChanged(); 150 void isShownFullyChanged(); 151 void hidingIsBlockedChanged(); 152 void containsMouseChanged(); 153 void strutsThicknessChanged(); 154 void timerShowChanged(); 155 void timerHideChanged(); 156 157 //! KWin Edges Support signals 158 void enableKWinEdgesChanged(); 159 void supportsKWinEdgesChanged(); 160 161 private slots: 162 void saveConfig(); 163 void restoreConfig(); 164 165 void setIsBelowLayer(bool below); 166 167 void onHeadThicknessChanged(); 168 void onHidingIsBlockedChanged(); 169 void onIsFloatingGapWindowEnabledChanged(); 170 171 void publishFrameExtents(bool forceUpdate = false); //! direct 172 173 //! KWin Edges Support functions 174 void updateKWinEdgesSupport(); 175 176 void updateSidebarState(); 177 178 private: 179 void setContainsMouse(bool contains); 180 181 void raiseView(bool raise); 182 void raiseViewTemporarily(); 183 184 //! KWin Edges Support functions 185 void createEdgeGhostWindow(); 186 void deleteEdgeGhostWindow(); 187 void updateGhostWindowState(); 188 189 //! Floating Gap Support functions 190 void createFloatingGapWindow(); 191 void deleteFloatingGapWindow(); 192 bool supportsFloatingGap() const; 193 194 void updateStrutsBasedOnLayoutsAndActivities(bool forceUpdate = false); 195 void viewEventManager(QEvent *ev); 196 197 void checkMouseInFloatingArea(); 198 199 bool windowContainsMouse(); 200 201 QRect acceptableStruts(); 202 203 private slots: 204 void dodgeAllWindows(); 205 void dodgeActive(); 206 void dodgeMaximized(); 207 void updateHiddenState(); 208 209 void updateStrutsAfterTimer(); 210 211 bool isValidMode() const; 212 213 private: 214 void startTimerHide(const int &msec = 0); 215 216 bool canSetStrut() const; 217 218 private: 219 WindowSystem::AbstractWindowInterface *m_wm; 220 Types::Visibility m_mode{Types::None}; 221 std::array<QMetaObject::Connection, 6> m_connections; 222 223 QTimer m_timerShow; 224 QTimer m_timerHide; 225 QTimer m_timerPublishFrameExtents; 226 //! This timer is very important because it blocks how fast struts are updated. 227 //! By using this timer we help the window manager in order to correspond to new 228 //! struts (for example changing windows maximized state or geometry) without 229 //! createing binding loops between the app and the window manager. 230 //! That was reproducable in a floating panel when we were dragging the active window. 231 QTimer m_timerBlockStrutsUpdate; 232 233 bool m_isBelowLayer{false}; 234 bool m_isHidden{false}; 235 bool m_isFloatingGapWindowEnabled{false}; 236 bool m_isSidebar{false}; 237 bool m_isShownFully{false}; 238 bool m_dragEnter{false}; 239 bool m_containsMouse{false}; 240 bool m_raiseTemporarily{false}; 241 bool m_raiseOnDesktopChange{false}; 242 bool m_raiseOnActivityChange{false}; 243 bool m_hideNow{false}; 244 245 //! valid on demand sidebar hidden state in order to be checked after slide-ins/outs 246 bool m_isRequestedShownSidebarOnDemand{false}; 247 248 int m_frameExtentsHeadThicknessGap{0}; 249 int m_timerHideInterval{700}; 250 Plasma::Types::Location m_frameExtentsLocation{Plasma::Types::BottomEdge}; 251 252 int m_strutsThickness{0}; 253 254 QStringList m_blockHidingEvents; 255 256 QRect m_publishedStruts; 257 QRect m_lastMask; 258 259 //! KWin Edges 260 bool m_enableKWinEdgesFromUser{true}; 261 std::array<QMetaObject::Connection, 1> m_connectionsKWinEdges; 262 ScreenEdgeGhostWindow *m_edgeGhostWindow{nullptr}; 263 264 //! Floating Gap 265 FloatingGapWindow *m_floatingGapWindow{nullptr}; 266 267 Latte::Corona *m_corona{nullptr}; 268 Latte::View *m_latteView{nullptr}; 269 270 }; 271 272 } 273 } 274 #endif // VISIBILITYMANAGER_H 275