File indexing completed on 2024-07-21 04:58:17

0001 /*
0002     SPDX-FileCopyrightText: 2019 Michail Vourlakos <mvourlakos@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #ifndef WINDOWSYSTEMWINDOWSTRACKER_H
0007 #define WINDOWSYSTEMWINDOWSTRACKER_H
0008 
0009 // local
0010 #include <coretypes.h>
0011 #include "../windowinfowrap.h"
0012 
0013 // Qt
0014 #include <QObject>
0015 
0016 #include <QHash>
0017 #include <QMap>
0018 #include <QTimer>
0019 
0020 
0021 namespace Latte {
0022 class View;
0023 namespace Layout {
0024 class GenericLayout;
0025 }
0026 namespace WindowSystem {
0027 class AbstractWindowInterface;
0028 class SchemeColors;
0029 namespace Tracker {
0030 class LastActiveWindow;
0031 class TrackedLayoutInfo;
0032 class TrackedViewInfo;
0033 }
0034 }
0035 }
0036 
0037 namespace Latte {
0038 namespace WindowSystem {
0039 namespace Tracker {
0040 
0041 class Windows : public QObject {
0042     Q_OBJECT
0043 
0044 public:
0045     Windows(AbstractWindowInterface *parent);
0046     ~Windows() override;
0047 
0048     void addView(Latte::View *view);
0049     void removeView(Latte::View *view);
0050 
0051     //! Views Tracking (current screen specific)
0052     bool enabled(Latte::View *view);
0053     void setEnabled(Latte::View *view, const bool enabled);
0054 
0055     bool activeWindowMaximized(Latte::View *view) const;
0056     bool activeWindowTouching(Latte::View *view) const;
0057     bool activeWindowTouchingEdge(Latte::View *view) const;
0058     bool existsWindowActive(Latte::View *view) const;
0059     bool existsWindowMaximized(Latte::View *view) const;
0060     bool existsWindowTouching(Latte::View *view) const;
0061     bool existsWindowTouchingEdge(Latte::View *view) const;
0062     bool isTouchingBusyVerticalView(Latte::View *view) const;
0063     SchemeColors *activeWindowScheme(Latte::View *view) const;
0064     SchemeColors *touchingWindowScheme(Latte::View *view) const;
0065     LastActiveWindow *lastActiveWindow(Latte::View *view);
0066 
0067     //! Layouts Tracking (all screens)
0068     bool enabled(Latte::Layout::GenericLayout *layout);
0069     bool activeWindowMaximized(Latte::Layout::GenericLayout *layout) const;
0070     bool existsWindowActive(Latte::Layout::GenericLayout *layout) const;
0071     bool existsWindowMaximized(Latte::Layout::GenericLayout *layout) const;
0072     SchemeColors *activeWindowScheme(Latte::Layout::GenericLayout *layout) const;
0073     LastActiveWindow *lastActiveWindow(Latte::Layout::GenericLayout *layout);
0074 
0075     //! Windows management
0076     bool isValidFor(const WindowId &wid) const;
0077     QIcon iconFor(const WindowId &wid);
0078     QString appNameFor(const WindowId &wid);
0079     WindowInfoWrap infoFor(const WindowId &wid) const;
0080 
0081     AbstractWindowInterface *wm();
0082 
0083 signals:
0084     //! Views
0085     void enabledChanged(const Latte::View *view);
0086     void activeWindowMaximizedChanged(const Latte::View *view);
0087     void activeWindowTouchingChanged(const Latte::View *view);
0088     void activeWindowTouchingEdgeChanged(const Latte::View *view);
0089     void existsWindowActiveChanged(const Latte::View *view);
0090     void existsWindowMaximizedChanged(const Latte::View *view);
0091     void existsWindowTouchingChanged(const Latte::View *view);
0092     void existsWindowTouchingEdgeChanged(const Latte::View *view);
0093     void isTouchingBusyVerticalViewChanged(const Latte::View *view);
0094     void activeWindowSchemeChanged(const Latte::View *view);
0095     void touchingWindowSchemeChanged(const Latte::View *view);
0096     void informationAnnounced(const Latte::View *view);
0097 
0098     //! Layouts
0099     void enabledChangedForLayout(const Latte::Layout::GenericLayout *layout);
0100     void activeWindowMaximizedChangedForLayout(const Latte::Layout::GenericLayout *layout);
0101     void existsWindowActiveChangedForLayout(const Latte::Layout::GenericLayout *layout);
0102     void existsWindowMaximizedChangedForLayout(const Latte::Layout::GenericLayout *layout);
0103     void activeWindowSchemeChangedForLayout(const Latte::Layout::GenericLayout *layout);
0104     void informationAnnouncedForLayout(const Latte::Layout::GenericLayout *layout);
0105 
0106     //! overloading WM signals in order to update first m_windows and afterwards
0107     //! inform consumers for window changes
0108     void activeWindowChanged(const WindowId &wid);
0109     void windowChanged(const WindowId &wid);
0110     void windowRemoved(const WindowId &wid);
0111 
0112     void applicationDataChanged(const WindowId &wid);
0113 
0114 private slots:
0115     void updateScreenGeometries();
0116 
0117     void addRelevantLayout(Latte::View *view);
0118 
0119     void updateApplicationData();
0120     void updateRelevantLayouts();
0121     void updateExtraViewHints();
0122 
0123 private:
0124     void init();
0125     void initLayoutHints(Latte::Layout::GenericLayout *layout);
0126     void initViewHints(Latte::View *view);
0127     void cleanupFaultyWindows();
0128 
0129     void updateAllHints();
0130     void updateAllHintsAfterTimer();
0131 
0132     //! Views
0133     void updateHints(Latte::View *view);
0134     void updateHints(Latte::Layout::GenericLayout *layout);
0135 
0136     void setActiveWindowMaximized(Latte::View *view, bool activeMaximized);
0137     void setActiveWindowTouching(Latte::View *view, bool activeTouching);
0138     void setActiveWindowTouchingEdge(Latte::View *view, bool activeTouchingEdge);
0139     void setExistsWindowActive(Latte::View *view, bool windowActive);
0140     void setExistsWindowMaximized(Latte::View *view, bool windowMaximized);
0141     void setExistsWindowTouching(Latte::View *view, bool windowTouching);
0142     void setExistsWindowTouchingEdge(Latte::View *view, bool windowTouchingEdge);
0143     void setIsTouchingBusyVerticalView(Latte::View *view, bool viewTouching);
0144     void setActiveWindowScheme(Latte::View *view, WindowSystem::SchemeColors *scheme);
0145     void setTouchingWindowScheme(Latte::View *view, WindowSystem::SchemeColors *scheme);
0146 
0147     //! Layouts
0148     void setActiveWindowMaximized(Latte::Layout::GenericLayout *layout, bool activeMaximized);
0149     void setExistsWindowActive(Latte::Layout::GenericLayout *layout, bool windowActive);
0150     void setExistsWindowMaximized(Latte::Layout::GenericLayout *layout, bool windowMaximized);
0151     void setActiveWindowScheme(Latte::Layout::GenericLayout *layout, WindowSystem::SchemeColors *scheme);
0152 
0153     //! Windows
0154     bool intersects(Latte::View *view, const WindowInfoWrap &winfo);
0155     bool isActive(const WindowInfoWrap &winfo);
0156     bool isActiveInViewScreen(Latte::View *view, const WindowInfoWrap &winfo);
0157     bool isMaximizedInViewScreen(Latte::View *view, const WindowInfoWrap &winfo);
0158     bool isTouchingView(Latte::View *view, const WindowSystem::WindowInfoWrap &winfo);
0159     bool isTouchingViewEdge(Latte::View *view, const WindowInfoWrap &winfo);
0160     bool isTouchingViewEdge(Latte::View *view, const QRect &windowgeometry);
0161 
0162 private:
0163     //! a timer in order to not overload the views extra hints checking because it is not
0164     //! really needed that often
0165     QTimer m_extraViewHintsTimer;
0166 
0167     AbstractWindowInterface *m_wm;
0168     QHash<Latte::View *, TrackedViewInfo *> m_views;
0169     QHash<Latte::Layout::GenericLayout *, TrackedLayoutInfo *> m_layouts;
0170 
0171     //! Accept only ALWAYSVISIBLE visibility mode
0172     QList<Latte::Types::Visibility> m_ignoreModes{
0173         Latte::Types::AutoHide,
0174         Latte::Types::DodgeActive,
0175         Latte::Types::DodgeMaximized,
0176         Latte::Types::DodgeAllWindows,
0177         Latte::Types::WindowsGoBelow,
0178         Latte::Types::WindowsCanCover,
0179         Latte::Types::WindowsAlwaysCover,
0180         Latte::Types::SidebarOnDemand,
0181         Latte::Types::SidebarAutoHide
0182     };
0183 
0184     QMap<WindowId, WindowInfoWrap> m_windows;
0185 
0186     QTimer m_updateAllHintsTimer;
0187     //! Some applications delay their application name/icon identification
0188     //! such as Libreoffice that updates its StartupWMClass after
0189     //! its startup
0190     QTimer m_updateApplicationDataTimer;
0191     QList<WindowId> m_delayedApplicationData;
0192     QList<WindowId> m_initializedApplicationData;
0193 };
0194 
0195 }
0196 }
0197 }
0198 
0199 #endif