Hy3Layout.hpp
6571 bytes
1#pragma once
2
3#include <hyprland/src/desktop/DesktopTypes.hpp>
4class Hy3Layout;
5
6enum class GroupEphemeralityOption {
7 Ephemeral,
8 Standard,
9 ForceEphemeral,
10};
11
12#include <set>
13
14#include <hyprland/src/layout/algorithm/TiledAlgorithm.hpp>
15#include <hyprland/src/layout/algorithm/Algorithm.hpp>
16#include <hyprland/src/layout/space/Space.hpp>
17#include <hyprland/src/output/Monitor.hpp>
18#include <hyprland/src/layout/target/Target.hpp>
19#include <hyprland/src/layout/LayoutManager.hpp>
20#include <hyprland/src/helpers/signal/Signal.hpp>
21#include <hyprland/src/event/EventBus.hpp>
22
23enum class ShiftDirection {
24 Left,
25 Up,
26 Down,
27 Right,
28};
29inline static constexpr char getShiftDirectionChar(ShiftDirection direction) {
30 return direction == ShiftDirection::Left ? 'l'
31 : direction == ShiftDirection::Up ? 'u'
32 : direction == ShiftDirection::Down ? 'd'
33 : 'r';
34}
35
36inline static Math::eDirection shiftToMathDirection(ShiftDirection direction) {
37 switch (direction) {
38 case ShiftDirection::Left: return Math::DIRECTION_LEFT;
39 case ShiftDirection::Right: return Math::DIRECTION_RIGHT;
40 case ShiftDirection::Up: return Math::DIRECTION_UP;
41 case ShiftDirection::Down: return Math::DIRECTION_DOWN;
42 }
43 return Math::DIRECTION_DEFAULT;
44}
45
46enum class Axis { None, Horizontal, Vertical };
47
48#include "Hy3Node.hpp"
49#include "TabGroup.hpp"
50
51enum class FocusShift {
52 Top,
53 Bottom,
54 Raise,
55 Lower,
56 Tab,
57 TabNode,
58};
59
60enum class TabFocus {
61 MouseLocation,
62 Left,
63 Right,
64 Index,
65};
66
67enum class TabFocusMousePriority {
68 Ignore,
69 Prioritize,
70 Require,
71};
72
73enum class TabLockMode {
74 Lock,
75 Unlock,
76 Toggle,
77};
78
79enum class SetSwallowOption {
80 NoSwallow,
81 Swallow,
82 Toggle,
83};
84
85enum class ExpandOption {
86 Expand,
87 Shrink,
88 Base,
89 Maximize,
90 Fullscreen,
91};
92
93enum class ExpandFullscreenOption {
94 MaximizeOnly,
95 MaximizeIntermediate,
96 MaximizeAsFullscreen,
97};
98
99PHLWORKSPACE workspace_for_action(bool allow_fullscreen = false);
100
101class Hy3Layout: public Layout::ITiledAlgorithm {
102public:
103 Hy3Layout();
104 ~Hy3Layout() override;
105
106 // ITiledAlgorithm / IModeAlgorithm overrides
107 void newTarget(SP<Layout::ITarget> target) override;
108 void movedTarget(SP<Layout::ITarget> target, std::optional<Vector2D> focalPoint = std::nullopt) override;
109 void removeTarget(SP<Layout::ITarget> target) override;
110 void resizeTarget(const Vector2D& delta, SP<Layout::ITarget> target, Layout::eRectCorner corner = Layout::CORNER_NONE) override;
111 void recalculate(Layout::eRecalculateReason reason) override;
112 void recalcGeometry(bool no_animation = false);
113 void swapTargets(SP<Layout::ITarget> a, SP<Layout::ITarget> b) override;
114 void moveTargetInDirection(SP<Layout::ITarget> t, Math::eDirection dir, bool silent) override;
115 Config::ErrorResult layoutMsg(const std::string_view& sv) override;
116 std::optional<Vector2D> predictSizeForNewTarget() override;
117 SP<Layout::ITarget> getNextCandidate(SP<Layout::ITarget> old) override;
118
119 // Hy3-specific public methods
120 void insertNode(UP<Hy3Node> node, std::optional<Vector2D> focalPoint = std::nullopt);
121 void onWindowFocusChange(PHLWINDOW window);
122 void updateGroupBorderColors();
123
124 void makeGroupOnWorkspace(
125 const CWorkspace* workspace,
126 Hy3GroupLayout,
127 GroupEphemeralityOption,
128 bool toggle
129 );
130 void makeOppositeGroupOnWorkspace(const CWorkspace* workspace, GroupEphemeralityOption);
131 void changeGroupOnWorkspace(const CWorkspace* workspace, Hy3GroupLayout);
132 void untabGroupOnWorkspace(const CWorkspace* workspace);
133 void toggleTabGroupOnWorkspace(const CWorkspace* workspace);
134 void changeGroupToOppositeOnWorkspace(const CWorkspace* workspace);
135 void changeGroupEphemeralityOnWorkspace(const CWorkspace* workspace, bool ephemeral);
136 void makeGroupOn(Hy3Node&, Hy3GroupLayout, GroupEphemeralityOption);
137 void makeOppositeGroupOn(Hy3Node&, GroupEphemeralityOption);
138 void changeGroupOn(Hy3Node&, Hy3GroupLayout);
139 void untabGroupOn(Hy3Node&);
140 void toggleTabGroupOn(Hy3Node&);
141 void changeGroupToOppositeOn(Hy3Node&);
142 void changeGroupEphemeralityOn(Hy3Node&, bool ephemeral);
143 void shiftNode(Hy3Node&, ShiftDirection, bool once, bool visible);
144 void shiftWindow(const CWorkspace* workspace, ShiftDirection, bool once, bool visible);
145 void shiftFocus(const CWorkspace* workspace, ShiftDirection, bool visible, bool warp);
146 void toggleFocusLayer(const CWorkspace* workspace, bool warp);
147 bool shiftMonitor(Hy3Node&, ShiftDirection, bool follow);
148 Hy3Node* focusMonitor(ShiftDirection);
149
150 void warpCursor();
151 void moveNodeToWorkspace(CWorkspace* origin, std::string wsname, bool follow, bool warp);
152 void changeFocus(const CWorkspace* workspace, FocusShift);
153 void focusTab(
154 const CWorkspace* workspace,
155 TabFocus target,
156 TabFocusMousePriority,
157 bool wrap_scroll,
158 int index
159 );
160 void setNodeSwallow(const CWorkspace* workspace, SetSwallowOption);
161 void killFocusedNode(const CWorkspace* workspace);
162 void expand(const CWorkspace* workspace, ExpandOption, ExpandFullscreenOption);
163 void setTabLock(const CWorkspace* workspace, TabLockMode);
164 void equalize(const CWorkspace* workspace, bool recursive = false);
165 static void warpCursorToBox(const Vector2D& pos, const Vector2D& size);
166 static void warpCursorWithFocus(const Vector2D& pos, bool force = false);
167 static std::string debugNodes();
168
169 bool shouldRenderSelected(const Desktop::View::CWindow*);
170 PHLWINDOW findTiledWindowCandidate(const Desktop::View::CWindow* from);
171 PHLWINDOW findFloatingWindowCandidate(const Desktop::View::CWindow* from);
172
173 Hy3Node* getWorkspaceRootGroup(const CWorkspace* workspace);
174 Hy3Node* getWorkspaceFocusedNode(
175 const CWorkspace* workspace,
176 bool ignore_group_focus = false,
177 bool stop_at_expanded = false
178 );
179
180 Hy3Node* getNodeFromWindow(const Desktop::View::CWindow*);
181 Hy3Node* getNodeFromTarget(SP<Layout::ITarget> target);
182
183 PHLWORKSPACE workspace();
184 PHLMONITORREF monitor();
185
186 UP<Hy3RootNode> root;
187
188private:
189 // if shift is true, shift the window in the given direction, returning
190 // nullptr, if shift is false, return the window in the given direction or
191 // nullptr. if once is true, only one group will be broken out of / into
192 Hy3Node* shiftOrGetFocus(Hy3Node&, ShiftDirection, bool shift, bool once, bool visible);
193
194 void updateAutotileWorkspaces();
195 bool shouldAutotileWorkspace(const CWorkspace* workspace);
196
197 // Per-instance event listeners
198 CHyprSignalListener m_windowActiveListener;
199 CHyprSignalListener m_mouseButtonListener;
200
201 struct {
202 std::string raw_workspaces;
203 bool workspace_blacklist;
204 std::set<int> workspaces;
205 } autotile;
206
207 friend struct Hy3Node;
208};