Add split opposite mode

Also fix multiple likely segfaults
This commit is contained in:
outfoxxed 2023-05-04 03:10:06 -07:00
parent e07477c8a9
commit 443081ab24
No known key found for this signature in database
GPG key ID: 4C88A185FB89301E
4 changed files with 70 additions and 23 deletions

View file

@ -32,7 +32,7 @@ In your hyprland config replace the following dispatchers:
You can use `hy3:makegroup` to create a new split. You can use `hy3:makegroup` to create a new split.
### Dispatcher list ### Dispatcher list
- `hy3:makegroup, <h | v>` - make a vertical or horizontal split - `hy3:makegroup, <h | v | opposite>` - make a vertical or horizontal split
- `hy3:movefocus, <l | u | d | r>` - move the focus left, up, down, or right - `hy3:movefocus, <l | u | d | r>` - move the focus left, up, down, or right
- `hy3:movewindow, <l | u | d | r>` - move a window left, up, down, or right - `hy3:movewindow, <l | u | d | r>` - move a window left, up, down, or right
- `hy3:raisefocus` - raise the active focus one level - `hy3:raisefocus` - raise the active focus one level

View file

@ -352,6 +352,24 @@ Hy3Node* Hy3Node::removeFromParentRecursive() {
return parent; return parent;
} }
Hy3Node* Hy3Node::intoGroup(Hy3GroupLayout layout) {
this->layout->nodes.push_back({
.parent = this,
.data = this->data,
.workspace_id = this->workspace_id,
.layout = this->layout,
});
auto* node = &this->layout->nodes.back();
this->data = layout;
this->data.as_group.children.push_back(node);
this->data.as_group.lastFocusedChild = node;
this->recalcSizePosRecursive();
return node;
}
bool Hy3GroupData::hasChild(Hy3Node* node) { bool Hy3GroupData::hasChild(Hy3Node* node) {
Debug::log(LOG, "Searching for child %p of %p", this, node); Debug::log(LOG, "Searching for child %p of %p", this, node);
for (auto child: this->children) { for (auto child: this->children) {
@ -655,6 +673,7 @@ void Hy3Layout::onWindowRemovedTiling(CWindow* window) {
CWindow* Hy3Layout::getNextWindowCandidate(CWindow* window) { CWindow* Hy3Layout::getNextWindowCandidate(CWindow* window) {
auto* node = this->getWorkspaceFocusedNode(window->m_iWorkspaceID); auto* node = this->getWorkspaceFocusedNode(window->m_iWorkspaceID);
if (node == nullptr) return nullptr;
switch (node->data.type) { switch (node->data.type) {
case Hy3NodeData::Window: case Hy3NodeData::Window:
@ -1059,32 +1078,52 @@ void Hy3Layout::onDisable() {
this->nodes.clear(); this->nodes.clear();
} }
void Hy3Layout::makeGroupOn(int workspace, Hy3GroupLayout layout) { void Hy3Layout::makeGroupOnWorkspace(int workspace, Hy3GroupLayout layout) {
auto* node = this->getWorkspaceFocusedNode(workspace); auto* node = this->getWorkspaceFocusedNode(workspace);
this->makeGroupOn(node, layout);
}
void Hy3Layout::makeOppositeGroupOnWorkspace(int workspace) {
auto* node = this->getWorkspaceFocusedNode(workspace);
this->makeOppositeGroupOn(node);
}
void Hy3Layout::makeGroupOn(Hy3Node* node, Hy3GroupLayout layout) {
if (node == nullptr) return; if (node == nullptr) return;
if (node->parent->data.as_group.children.size() == 1 if (node->parent != nullptr) {
&& (node->parent->data.as_group.layout == Hy3GroupLayout::SplitH auto& group = node->parent->data.as_group;
|| node->parent->data.as_group.layout == Hy3GroupLayout::SplitV)) if (group.children.size() == 1
{ && (group.layout == Hy3GroupLayout::SplitH
node->parent->data.as_group.layout = layout; || group.layout == Hy3GroupLayout::SplitV))
node->parent->recalcSizePosRecursive(); {
return; group.layout = layout;
node->parent->recalcSizePosRecursive();
return;
}
} }
this->nodes.push_back({ node->intoGroup(layout);
.parent = node, }
.data = node->data,
.workspace_id = node->workspace_id,
.layout = this,
});
node->data = layout; void Hy3Layout::makeOppositeGroupOn(Hy3Node* node) {
node->data.as_group.children.push_back(&this->nodes.back()); if (node == nullptr) return;
node->data.as_group.lastFocusedChild = &this->nodes.back();
node->recalcSizePosRecursive();
return; if (node->parent == nullptr) {
node->intoGroup(Hy3GroupLayout::SplitH);
} else {
auto& group = node->parent->data.as_group;
auto layout = group.layout == Hy3GroupLayout::SplitH
? Hy3GroupLayout::SplitV
: Hy3GroupLayout::SplitH;
if (group.children.size() == 1) {
group.layout = layout;
node->parent->recalcSizePosRecursive();
} else {
node->intoGroup(layout);
}
}
} }
Hy3Node* shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, bool shift); Hy3Node* shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, bool shift);

View file

@ -85,6 +85,9 @@ struct Hy3Node {
// the only child and recursing if the parent was the only child of it's parent. // the only child and recursing if the parent was the only child of it's parent.
Hy3Node* removeFromParentRecursive(); Hy3Node* removeFromParentRecursive();
// Replace this node with a group, returning this node's new address.
Hy3Node* intoGroup(Hy3GroupLayout);
static void swapData(Hy3Node&, Hy3Node&); static void swapData(Hy3Node&, Hy3Node&);
}; };
@ -110,7 +113,10 @@ public:
virtual void onEnable(); virtual void onEnable();
virtual void onDisable(); virtual void onDisable();
void makeGroupOn(int, Hy3GroupLayout); void makeGroupOnWorkspace(int, Hy3GroupLayout);
void makeOppositeGroupOnWorkspace(int);
void makeGroupOn(Hy3Node*, Hy3GroupLayout);
void makeOppositeGroupOn(Hy3Node*);
void shiftWindow(int, ShiftDirection); void shiftWindow(int, ShiftDirection);
void shiftFocus(int, ShiftDirection); void shiftFocus(int, ShiftDirection);
void raiseFocus(int); void raiseFocus(int);

View file

@ -40,9 +40,11 @@ void dispatch_makegroup(std::string arg) {
if (workspace < 0) return; if (workspace < 0) return;
if (arg == "h") { if (arg == "h") {
g_Hy3Layout->makeGroupOn(workspace, Hy3GroupLayout::SplitH); g_Hy3Layout->makeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitH);
} else if (arg == "v") { } else if (arg == "v") {
g_Hy3Layout->makeGroupOn(workspace, Hy3GroupLayout::SplitV); g_Hy3Layout->makeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitV);
} else if (arg == "opposite") {
g_Hy3Layout->makeOppositeGroupOnWorkspace(workspace);
} }
} }