aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Compositor.hpp
blob: f17d86e54416a3febd72c9c0561820abaf4261ab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#pragma once

#include <memory>
#include <deque>
#include <list>
#include <sys/resource.h>

#include "defines.hpp"
#include "debug/Log.hpp"
#include "events/Events.hpp"
#include "config/ConfigManager.hpp"
#include "managers/ThreadManager.hpp"
#include "managers/XWaylandManager.hpp"
#include "managers/input/InputManager.hpp"
#include "managers/LayoutManager.hpp"
#include "managers/KeybindManager.hpp"
#include "managers/AnimationManager.hpp"
#include "managers/EventManager.hpp"
#include "managers/ProtocolManager.hpp"
#include "managers/SessionLockManager.hpp"
#include "managers/HookSystemManager.hpp"
#include "debug/HyprDebugOverlay.hpp"
#include "debug/HyprNotificationOverlay.hpp"
#include "helpers/Monitor.hpp"
#include "desktop/Workspace.hpp"
#include "desktop/Window.hpp"
#include "render/Renderer.hpp"
#include "render/OpenGL.hpp"
#include "hyprerror/HyprError.hpp"
#include "plugins/PluginSystem.hpp"
#include "helpers/Watchdog.hpp"

#include <aquamarine/backend/Backend.hpp>
#include <aquamarine/output/Output.hpp>

class CWLSurfaceResource;

enum eManagersInitStage {
    STAGE_PRIORITY = 0,
    STAGE_BASICINIT,
    STAGE_LATE
};

class CCompositor {
  public:
    CCompositor();
    ~CCompositor();

    wl_display*                                m_sWLDisplay;
    wl_event_loop*                             m_sWLEventLoop;
    int                                        m_iDRMFD       = -1;
    bool                                       m_bInitialized = false;
    SP<Aquamarine::CBackend>                   m_pAqBackend;

    std::string                                m_szHyprTempDataRoot = "";

    std::string                                m_szWLDisplaySocket   = "";
    std::string                                m_szInstanceSignature = "";
    std::string                                m_szInstancePath      = "";
    std::string                                m_szCurrentSplash     = "error";

    std::vector<SP<CMonitor>>                  m_vMonitors;
    std::vector<SP<CMonitor>>                  m_vRealMonitors; // for all monitors, even those turned off
    std::vector<PHLWINDOW>                     m_vWindows;
    std::vector<PHLLS>                         m_vLayers;
    std::vector<PHLWORKSPACE>                  m_vWorkspaces;
    std::vector<PHLWINDOWREF>                  m_vWindowsFadingOut;
    std::vector<PHLLSREF>                      m_vSurfacesFadingOut;

    std::unordered_map<std::string, MONITORID> m_mMonitorIDMap;

    void                                       initServer(std::string socketName, int socketFd);
    void                                       startCompositor();
    void                                       stopCompositor();
    void                                       cleanup();
    void                                       createLockFile();
    void                                       removeLockFile();
    void                                       bumpNofile();
    void                                       restoreNofile();

    WP<CWLSurfaceResource>                     m_pLastFocus;
    PHLWINDOWREF                               m_pLastWindow;
    WP<CMonitor>                               m_pLastMonitor;

    std::vector<PHLWINDOWREF>                  m_vWindowFocusHistory; // first element is the most recently focused.

    bool                                       m_bReadyToProcess = false;
    bool                                       m_bSessionActive  = true;
    bool                                       m_bDPMSStateON    = true;
    bool                                       m_bUnsafeState    = false; // unsafe state is when there is no monitors.
    bool                                       m_bNextIsUnsafe   = false;
    CMonitor*                                  m_pUnsafeOutput   = nullptr; // fallback output for the unsafe state
    bool                                       m_bIsShuttingDown = false;
    bool                                       m_bDesktopEnvSet  = false;
    bool                                       m_bEnableXwayland = true;

    // ------------------------------------------------- //

    CMonitor*              getMonitorFromID(const MONITORID&);
    CMonitor*              getMonitorFromName(const std::string&);
    CMonitor*              getMonitorFromDesc(const std::string&);
    CMonitor*              getMonitorFromCursor();
    CMonitor*              getMonitorFromVector(const Vector2D&);
    void                   removeWindowFromVectorSafe(PHLWINDOW);
    void                   focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr);
    void                   focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
    bool                   monitorExists(CMonitor*);
    PHLWINDOW              vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr);
    SP<CWLSurfaceResource> vectorToLayerSurface(const Vector2D&, std::vector<PHLLSREF>*, Vector2D*, PHLLS*);
    SP<CWLSurfaceResource> vectorToLayerPopupSurface(const Vector2D&, CMonitor* monitor, Vector2D*, PHLLS*);
    SP<CWLSurfaceResource> vectorWindowToSurface(const Vector2D&, PHLWINDOW, Vector2D& sl);
    Vector2D               vectorToSurfaceLocal(const Vector2D&, PHLWINDOW, SP<CWLSurfaceResource>);
    CMonitor*              getMonitorFromOutput(SP<Aquamarine::IOutput>);
    CMonitor*              getRealMonitorFromOutput(SP<Aquamarine::IOutput>);
    PHLWINDOW              getWindowFromSurface(SP<CWLSurfaceResource>);
    PHLWINDOW              getWindowFromHandle(uint32_t);
    bool                   isWorkspaceVisible(PHLWORKSPACE);
    bool                   isWorkspaceVisibleNotCovered(PHLWORKSPACE);
    PHLWORKSPACE           getWorkspaceByID(const WORKSPACEID&);
    PHLWORKSPACE           getWorkspaceByName(const std::string&);
    PHLWORKSPACE           getWorkspaceByString(const std::string&);
    void                   sanityCheckWorkspaces();
    void                   updateWorkspaceWindowDecos(const WORKSPACEID&);
    void                   updateWorkspaceWindowData(const WORKSPACEID&);
    int                    getWindowsOnWorkspace(const WORKSPACEID& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
    int                    getGroupsOnWorkspace(const WORKSPACEID& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
    PHLWINDOW              getUrgentWindow();
    bool                   hasUrgentWindowOnWorkspace(const WORKSPACEID&);
    PHLWINDOW              getFirstWindowOnWorkspace(const WORKSPACEID&);
    PHLWINDOW              getTopLeftWindowOnWorkspace(const WORKSPACEID&);
    PHLWINDOW              getFullscreenWindowOnWorkspace(const WORKSPACEID&);
    bool                   isWindowActive(PHLWINDOW);
    void                   changeWindowZOrder(PHLWINDOW, bool);
    void                   cleanupFadingOut(const MONITORID& monid);
    PHLWINDOW              getWindowInDirection(PHLWINDOW, char);
    PHLWINDOW              getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
    PHLWINDOW              getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
    WORKSPACEID            getNextAvailableNamedWorkspace();
    bool                   isPointOnAnyMonitor(const Vector2D&);
    bool                   isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);
    CMonitor*              getMonitorInDirection(const char&);
    CMonitor*              getMonitorInDirection(CMonitor*, const char&);
    void                   updateAllWindowsAnimatedDecorationValues();
    void                   updateWorkspaceWindows(const WORKSPACEID& id);
    void                   updateWindowAnimatedDecorationValues(PHLWINDOW);
    MONITORID              getNextAvailableMonitorID(std::string const& name);
    void                   moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false);
    void                   swapActiveWorkspaces(CMonitor*, CMonitor*);
    CMonitor*              getMonitorFromString(const std::string&);
    bool                   workspaceIDOutOfBounds(const WORKSPACEID&);
    void                   setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
    void                   setWindowFullscreenClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
    void                   setWindowFullscreenState(const PHLWINDOW PWINDOW, const sFullscreenState state);
    void                   changeWindowFullscreenModeInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON);
    void                   changeWindowFullscreenModeClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON);
    void                   updateFullscreenFadeOnWorkspace(PHLWORKSPACE);
    PHLWINDOW              getX11Parent(PHLWINDOW);
    void                   scheduleFrameForMonitor(CMonitor*, Aquamarine::IOutput::scheduleFrameReason reason = Aquamarine::IOutput::AQ_SCHEDULE_CLIENT_UNKNOWN);
    void                   addToFadingOutSafe(PHLLS);
    void                   removeFromFadingOutSafe(PHLLS);
    void                   addToFadingOutSafe(PHLWINDOW);
    PHLWINDOW              getWindowByRegex(const std::string&);
    void                   warpCursorTo(const Vector2D&, bool force = false);
    PHLLS                  getLayerSurfaceFromSurface(SP<CWLSurfaceResource>);
    void                   closeWindow(PHLWINDOW);
    Vector2D               parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
    void                   forceReportSizesToWindowsOnWorkspace(const WORKSPACEID&);
    PHLWORKSPACE           createNewWorkspace(const WORKSPACEID&, const MONITORID&, const std::string& name = "",
                                              bool isEmpty = true); // will be deleted next frame if left empty and unfocused!
    void                   renameWorkspace(const WORKSPACEID&, const std::string& name = "");
    void                   setActiveMonitor(CMonitor*);
    bool                   isWorkspaceSpecial(const WORKSPACEID&);
    WORKSPACEID            getNewSpecialID();
    void                   performUserChecks();
    void                   moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWorkspace);
    PHLWINDOW              getForceFocus();
    void                   arrangeMonitors();
    void                   enterUnsafeState();
    void                   leaveUnsafeState();
    void                   setPreferredScaleForSurface(SP<CWLSurfaceResource> pSurface, double scale);
    void                   setPreferredTransformForSurface(SP<CWLSurfaceResource> pSurface, wl_output_transform transform);
    void                   updateSuspendedStates();
    PHLWINDOW              windowForCPointer(CWindow*);
    void                   onNewMonitor(SP<Aquamarine::IOutput> output);

    std::string            explicitConfigPath;

  private:
    void             initAllSignals();
    void             removeAllSignals();
    void             cleanEnvironment();
    void             setRandomSplash();
    void             initManagers(eManagersInitStage stage);
    void             prepareFallbackOutput();

    uint64_t         m_iHyprlandPID    = 0;
    wl_event_source* m_critSigSource   = nullptr;
    rlimit           m_sOriginalNofile = {0};
};

inline std::unique_ptr<CCompositor> g_pCompositor;