Hy3Node.hpp
4515 bytes
1#pragma once
2
3struct Hy3Node;
4struct Hy3TargetNode;
5struct Hy3GroupNode;
6struct Hy3RootNode;
7enum class Hy3GroupLayout;
8
9#include <generator>
10
11#include <hyprland/src/defines.hpp>
12#include <hyprland/src/desktop/view/window/Window.hpp>
13#include <hyprland/src/layout/target/Target.hpp>
14
15#include "Hy3Layout.hpp"
16#include "TabGroup.hpp"
17
18enum class Hy3GroupLayout {
19 Root,
20 SplitH,
21 SplitV,
22 Tabbed,
23};
24
25enum class Hy3NodeType {
26 Target,
27 Group,
28};
29
30enum class ExpandFocusType {
31 NotExpanded,
32 Latch,
33 Stack,
34};
35
36enum class Ephemeral {
37 Off,
38 Staged,
39 Active,
40};
41
42enum class CollapsePolicy {
43 InvalidOnly,
44 EmptySplits,
45 SingleNodeGroups,
46};
47
48struct Hy3Node {
49 WP<Hy3Node> parent;
50 WP<Hy3Node> self; // set from owning UP at creation time
51 CBox logicalBox;
52 CBox visualBox;
53 float size_ratio = 1.0;
54 bool hidden = false;
55
56 virtual ~Hy3Node() = default;
57 Hy3Node(const Hy3Node&) = delete;
58 Hy3Node& operator=(const Hy3Node&) = delete;
59
60 template<typename T> bool is() const { return dynamic_cast<const T*>(this) != nullptr; }
61 template<typename T> T& as() { return dynamic_cast<T&>(*this); }
62 template<typename T> const T& as() const { return dynamic_cast<const T&>(*this); }
63
64 bool valid() const;
65 Hy3NodeType type() const;
66 bool is_target() const;
67 bool is_group() const;
68 Hy3GroupNode& as_group();
69 SP<Layout::ITarget> as_target();
70 PHLWINDOW as_window();
71
72 bool operator==(const Hy3Node&) const;
73 bool is_root();
74 bool is_root_group();
75 void assertNotRoot();
76 Hy3RootNode* root();
77 Hy3Layout* layout();
78
79 static UP<Hy3Node> create(SP<Layout::ITarget> target);
80 static UP<Hy3Node> create(Hy3GroupLayout group_layout);
81
82 void focus(bool warp, Desktop::eFocusReason reason);
83 void markFocused();
84 Hy3Node& getFocusedNode(bool ignore_group_focus = false, bool stop_at_expanded = false);
85 Hy3Node* findNeighbor(ShiftDirection);
86 Hy3Node* getImmediateSibling(ShiftDirection);
87 void resize(ShiftDirection, double, bool no_animation = false);
88 bool isIndirectlyFocused();
89 Hy3Node& getExpandActor();
90 Hy3Node& getPlacementActor();
91
92 void recalcSizePosRecursive(CBox offsets, bool no_animation = false);
93 void updateTabBar(bool no_animation = false);
94 void updateTabBarRecursive();
95 void updateDecos();
96
97 std::string getTitle();
98 bool isUrgent();
99 void setHidden(bool);
100
101 Hy3Node* findNodeForTabGroup(Hy3TabGroup&);
102 std::generator<Hy3Node&> ancestors();
103 std::generator<Desktop::View::CWindow&> windows(bool visibleOnly = false);
104 std::string debugNode();
105
106 Hy3Node* collapseParents(CollapsePolicy policy);
107 UP<Hy3Node> extractAndMerge(
108 Hy3Node& child,
109 Hy3Node** out_parent = nullptr,
110 CollapsePolicy policy = CollapsePolicy::EmptySplits
111 );
112
113 void insertAndMerge(
114 std::list<UP<Hy3Node>>::iterator pos,
115 UP<Hy3Node> child,
116 CollapsePolicy policy = CollapsePolicy::EmptySplits
117 );
118 void insertAndMerge(UP<Hy3Node> child, CollapsePolicy policy = CollapsePolicy::EmptySplits);
119
120 void wrap(Hy3GroupLayout, GroupEphemeralityOption, bool change = true);
121
122protected:
123 Hy3Node() = default;
124};
125
126struct Hy3TargetNode : Hy3Node {
127 WP<Layout::ITarget> target;
128};
129
130struct Hy3GroupNode : Hy3Node {
131 Hy3GroupLayout layout = Hy3GroupLayout::SplitH;
132 Hy3GroupLayout previous_nontab_layout = Hy3GroupLayout::SplitH;
133 std::list<UP<Hy3Node>> children;
134 bool group_focused = true;
135 Hy3Node* focused_child = nullptr; // non-owning observer, always valid while parent group lives
136 ExpandFocusType expand_focused = ExpandFocusType::NotExpanded;
137 Ephemeral ephemeral = Ephemeral::Off;
138 bool locked = false;
139 bool containment = false;
140 Hy3TabGroupWrapper tab_bar;
141
142 Hy3GroupNode(Hy3GroupLayout layout);
143 ~Hy3GroupNode() override = default;
144
145 bool isSplit() const { return layout == Hy3GroupLayout::SplitH || layout == Hy3GroupLayout::SplitV; }
146 bool isTab() const { return layout == Hy3GroupLayout::Tabbed; }
147
148 bool hasChild(Hy3Node& child);
149 void collapseExpansions();
150 void setLayout(Hy3GroupLayout layout);
151 void setEphemeral(GroupEphemeralityOption ephemeral);
152
153 auto findChild(Hy3Node& child) -> std::list<UP<Hy3Node>>::iterator;
154 void insertChild(std::list<UP<Hy3Node>>::iterator pos, UP<Hy3Node> child);
155 void insertChild(UP<Hy3Node> child);
156 UP<Hy3Node> extractChildRaw(std::list<UP<Hy3Node>>::iterator it);
157 UP<Hy3Node> extractChildRaw(Hy3Node& child);
158 UP<Hy3Node> replaceChild(std::list<UP<Hy3Node>>::iterator it, UP<Hy3Node> replacement);
159 UP<Hy3Node> extractChild(Hy3Node& child);
160
161 friend struct Hy3Node;
162};
163
164struct Hy3RootNode : Hy3GroupNode {
165 Hy3Layout* algo = nullptr;
166 Hy3RootNode(Hy3Layout* layout);
167};