diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index 5a7973d..134a86f 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -746,6 +746,23 @@ void Hy3Layout::makeOppositeGroupOnWorkspace(int workspace, GroupEphemeralityOpt this->makeOppositeGroupOn(node, ephemeral); } +void Hy3Layout::changeGroupOnWorkspace( + int workspace, + Hy3GroupLayout layout, + GroupEphemeralityOption ephemeral +) { + auto* node = this->getWorkspaceFocusedNode(workspace); + this->changeGroupOn(node, layout, ephemeral); +} + +void Hy3Layout::untabGroupOnWorkspace( + int workspace, + GroupEphemeralityOption ephemeral +) { + auto* node = this->getWorkspaceFocusedNode(workspace); + this->untabGroupOn(node, ephemeral); +} + void Hy3Layout::makeGroupOn( Hy3Node* node, Hy3GroupLayout layout, @@ -756,10 +773,7 @@ void Hy3Layout::makeGroupOn( if (node->parent != nullptr) { auto& group = node->parent->data.as_group; if (group.children.size() == 1) { - group.layout = layout; - group.ephemeral = ephemeral == GroupEphemeralityOption::ForceEphemeral ? true - : ephemeral == GroupEphemeralityOption::Ephemeral ? group.ephemeral - : false; + group.updateLayout(layout, ephemeral); node->parent->recalcSizePosRecursive(); return; } @@ -768,26 +782,57 @@ void Hy3Layout::makeGroupOn( node->intoGroup(layout, ephemeral); } -void Hy3Layout::makeOppositeGroupOn(Hy3Node* node, GroupEphemeralityOption ephemeral) { +void Hy3Layout::makeOppositeGroupOn( + Hy3Node* node, + GroupEphemeralityOption ephemeral +) { if (node == nullptr) return; if (node->parent == nullptr) { node->intoGroup(Hy3GroupLayout::SplitH, ephemeral); - } 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; - group.ephemeral = ephemeral == GroupEphemeralityOption::ForceEphemeral ? true - : ephemeral == GroupEphemeralityOption::Ephemeral ? group.ephemeral - : false; - node->parent->recalcSizePosRecursive(); - } else { - node->intoGroup(layout, ephemeral); - } + return; } + + auto& group = node->parent->data.as_group; + auto layout + = group.layout == Hy3GroupLayout::SplitH ? Hy3GroupLayout::SplitV : Hy3GroupLayout::SplitH; + + if (group.children.size() == 1) { + group.updateLayout(layout, ephemeral); + node->parent->recalcSizePosRecursive(); + return; + } + + node->intoGroup(layout, ephemeral); +} + +void Hy3Layout::changeGroupOn( + Hy3Node* node, + Hy3GroupLayout layout, + GroupEphemeralityOption ephemeral +) { + if (node == nullptr) return; + + if (node->parent == nullptr) { + makeGroupOn(node, layout, ephemeral); + return; + } + + auto& group = node->parent->data.as_group; + group.updateLayout(layout, ephemeral); + node->parent->recalcSizePosRecursive(); +} + +void Hy3Layout::untabGroupOn(Hy3Node* node, GroupEphemeralityOption ephemeral) { + if (node == nullptr) return; + + if (node->parent == nullptr) return; + + auto& group = node->parent->data.as_group; + + if (group.layout != Hy3GroupLayout::Tabbed) return; + + changeGroupOn(node, group.previous_nontab_layout, ephemeral); } void Hy3Layout::shiftWindow(int workspace, ShiftDirection direction, bool once) { diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp index ee91b23..ace2ffe 100644 --- a/src/Hy3Layout.hpp +++ b/src/Hy3Layout.hpp @@ -90,8 +90,12 @@ public: void makeGroupOnWorkspace(int workspace, Hy3GroupLayout, GroupEphemeralityOption); void makeOppositeGroupOnWorkspace(int workspace, GroupEphemeralityOption); + void changeGroupOnWorkspace(int workspace, Hy3GroupLayout, GroupEphemeralityOption); + void untabGroupOnWorkspace(int workspace, GroupEphemeralityOption); void makeGroupOn(Hy3Node*, Hy3GroupLayout, GroupEphemeralityOption); void makeOppositeGroupOn(Hy3Node*, GroupEphemeralityOption); + void changeGroupOn(Hy3Node*, Hy3GroupLayout, GroupEphemeralityOption); + void untabGroupOn(Hy3Node*, GroupEphemeralityOption); void shiftWindow(int workspace, ShiftDirection, bool once); void shiftFocus(int workspace, ShiftDirection, bool visible); void changeFocus(int workspace, FocusShift); diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp index 9e68cc2..084d6a5 100644 --- a/src/Hy3Node.cpp +++ b/src/Hy3Node.cpp @@ -8,10 +8,15 @@ // Hy3GroupData // -Hy3GroupData::Hy3GroupData(Hy3GroupLayout layout): layout(layout) {} +Hy3GroupData::Hy3GroupData(Hy3GroupLayout layout): layout(layout) { + if (layout != Hy3GroupLayout::Tabbed) { + this->previous_nontab_layout = layout; + } +} Hy3GroupData::Hy3GroupData(Hy3GroupData&& from) { this->layout = from.layout; + this->previous_nontab_layout = from.previous_nontab_layout; this->children = std::move(from.children); this->group_focused = from.group_focused; this->expand_focused = from.expand_focused; @@ -52,6 +57,29 @@ void Hy3GroupData::collapseExpansions() { } } +void Hy3GroupData::updateLayout( + Hy3GroupLayout layout, + GroupEphemeralityOption ephemeral +) { + this->layout = layout; + + if (layout != Hy3GroupLayout::Tabbed) { + this->previous_nontab_layout = layout; + } + + switch (ephemeral) { + case GroupEphemeralityOption::ForceEphemeral: + this->ephemeral = true; + break; + case GroupEphemeralityOption::Standard: + this->ephemeral = false; + break; + case GroupEphemeralityOption::Ephemeral: + // this->ephemeral stays the same + break; + } +} + // Hy3NodeData // Hy3NodeData::Hy3NodeData(): Hy3NodeData((CWindow*) nullptr) {} diff --git a/src/Hy3Node.hpp b/src/Hy3Node.hpp index 29d84f0..6f38276 100644 --- a/src/Hy3Node.hpp +++ b/src/Hy3Node.hpp @@ -29,6 +29,7 @@ enum class ExpandFocusType { struct Hy3GroupData { Hy3GroupLayout layout = Hy3GroupLayout::SplitH; + Hy3GroupLayout previous_nontab_layout = Hy3GroupLayout::SplitH; std::list children; bool group_focused = true; Hy3Node* focused_child = nullptr; @@ -42,6 +43,7 @@ struct Hy3GroupData { bool hasChild(Hy3Node* child); void collapseExpansions(); + void updateLayout(Hy3GroupLayout layout, GroupEphemeralityOption ephemeral); private: Hy3GroupData(Hy3GroupData&&); diff --git a/src/dispatchers.cpp b/src/dispatchers.cpp index d6568e4..04b3c11 100644 --- a/src/dispatchers.cpp +++ b/src/dispatchers.cpp @@ -43,6 +43,35 @@ void dispatch_makegroup(std::string value) { } } +void dispatch_changegroup(std::string value) { + int workspace = workspace_for_action(); + if (workspace == -1) return; + + auto args = CVarList(value); + + GroupEphemeralityOption ephemeral = GroupEphemeralityOption::Standard; + if (args[1] == "ephemeral") { + ephemeral = GroupEphemeralityOption::Ephemeral; + } else if (args[1] == "force_ephemeral") { + ephemeral = GroupEphemeralityOption::ForceEphemeral; + } + + if (args[0] == "h") { + g_Hy3Layout->changeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitH, ephemeral); + } else if (args[0] == "v") { + g_Hy3Layout->changeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitV, ephemeral); + } else if (args[0] == "tab") { + g_Hy3Layout->changeGroupOnWorkspace(workspace, Hy3GroupLayout::Tabbed, ephemeral); + } else if (args[0] == "untab") { + g_Hy3Layout->untabGroupOnWorkspace(workspace, ephemeral); + } + // TODO + //else if (args[0] == "opposite") { + // g_Hy3Layout->makeOppositeGroupOnWorkspace(workspace, ephemeral); + //} +} + + std::optional parseShiftArg(std::string arg) { if (arg == "l" || arg == "left") return ShiftDirection::Left; else if (arg == "r" || arg == "right") return ShiftDirection::Right; @@ -188,6 +217,7 @@ void dispatch_debug(std::string arg) { void registerDispatchers() { HyprlandAPI::addDispatcher(PHANDLE, "hy3:makegroup", dispatch_makegroup); + HyprlandAPI::addDispatcher(PHANDLE, "hy3:changegroup", dispatch_changegroup); HyprlandAPI::addDispatcher(PHANDLE, "hy3:movefocus", dispatch_movefocus); HyprlandAPI::addDispatcher(PHANDLE, "hy3:movewindow", dispatch_movewindow); HyprlandAPI::addDispatcher(PHANDLE, "hy3:changefocus", dispatch_changefocus);