mirror of
https://github.com/Trensa-Organization/hy3.git
synced 2025-03-15 18:53:40 +01:00
Merge pull request #21 from sekhat/feature/change-group
Add a changegroup and setephemeral dispatchers
This commit is contained in:
commit
a15a058250
6 changed files with 160 additions and 21 deletions
|
@ -215,6 +215,10 @@ plugin {
|
||||||
- `hy3:makegroup, <h | v | opposite | tab>, [ephemeral | force_ephemeral]` - make a vertical / horizontal split or tab group
|
- `hy3:makegroup, <h | v | opposite | tab>, [ephemeral | force_ephemeral]` - make a vertical / horizontal split or tab group
|
||||||
- `ephemeral` - the group will be removed once it contains only one node. does not affect existing groups.
|
- `ephemeral` - the group will be removed once it contains only one node. does not affect existing groups.
|
||||||
- `force_ephemeral` - same as ephemeral, but converts existing single windows groups.
|
- `force_ephemeral` - same as ephemeral, but converts existing single windows groups.
|
||||||
|
- `hy3:changegroup, <h | v | tab | untab | opposite>` - change the group the node belongs to, to a different layout
|
||||||
|
- `untab` will untab the group if it was previously tabbed
|
||||||
|
- `opposite` will toggle between horizontal and vertical layouts if the group is not tabbed.
|
||||||
|
- `hy3:setephemeral, <true | false>` - change the ephemerality of the group the node belongs to
|
||||||
- `hy3:movefocus, <l | u | d | r | left | down | up | right>, [visible]` - move the focus left, up, down, or right
|
- `hy3:movefocus, <l | u | d | r | left | down | up | right>, [visible]` - move the focus left, up, down, or right
|
||||||
- `visible` - only move between visible nodes, not hidden tabs
|
- `visible` - only move between visible nodes, not hidden tabs
|
||||||
- `hy3:movewindow, <l | u | d | r | left | down | up | right>, [once]` - move a window left, up, down, or right
|
- `hy3:movewindow, <l | u | d | r | left | down | up | right>, [once]` - move a window left, up, down, or right
|
||||||
|
|
|
@ -748,6 +748,34 @@ void Hy3Layout::makeOppositeGroupOnWorkspace(int workspace, GroupEphemeralityOpt
|
||||||
this->makeOppositeGroupOn(node, ephemeral);
|
this->makeOppositeGroupOn(node, ephemeral);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Hy3Layout::changeGroupOnWorkspace(int workspace, Hy3GroupLayout layout) {
|
||||||
|
auto* node = this->getWorkspaceFocusedNode(workspace);
|
||||||
|
if (node == nullptr) return;
|
||||||
|
|
||||||
|
this->changeGroupOn(*node, layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hy3Layout::untabGroupOnWorkspace(int workspace) {
|
||||||
|
auto* node = this->getWorkspaceFocusedNode(workspace);
|
||||||
|
if (node == nullptr) return;
|
||||||
|
|
||||||
|
this->untabGroupOn(*node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hy3Layout::changeGroupToOppositeOnWorkspace(int workspace) {
|
||||||
|
auto* node = this->getWorkspaceFocusedNode(workspace);
|
||||||
|
if (node == nullptr) return;
|
||||||
|
|
||||||
|
this->changeGroupToOppositeOn(*node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hy3Layout::changeGroupEphemeralityOnWorkspace(int workspace, bool ephemeral) {
|
||||||
|
auto* node = this->getWorkspaceFocusedNode(workspace);
|
||||||
|
if (node == nullptr) return;
|
||||||
|
|
||||||
|
this->changeGroupEphemeralityOn(*node, ephemeral);
|
||||||
|
}
|
||||||
|
|
||||||
void Hy3Layout::makeGroupOn(
|
void Hy3Layout::makeGroupOn(
|
||||||
Hy3Node* node,
|
Hy3Node* node,
|
||||||
Hy3GroupLayout layout,
|
Hy3GroupLayout layout,
|
||||||
|
@ -758,10 +786,8 @@ void Hy3Layout::makeGroupOn(
|
||||||
if (node->parent != nullptr) {
|
if (node->parent != nullptr) {
|
||||||
auto& group = node->parent->data.as_group;
|
auto& group = node->parent->data.as_group;
|
||||||
if (group.children.size() == 1) {
|
if (group.children.size() == 1) {
|
||||||
group.layout = layout;
|
group.setLayout(layout);
|
||||||
group.ephemeral = ephemeral == GroupEphemeralityOption::ForceEphemeral ? true
|
group.setEphemeral(ephemeral);
|
||||||
: ephemeral == GroupEphemeralityOption::Ephemeral ? group.ephemeral
|
|
||||||
: false;
|
|
||||||
node->parent->recalcSizePosRecursive();
|
node->parent->recalcSizePosRecursive();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -775,21 +801,62 @@ void Hy3Layout::makeOppositeGroupOn(Hy3Node* node, GroupEphemeralityOption ephem
|
||||||
|
|
||||||
if (node->parent == nullptr) {
|
if (node->parent == nullptr) {
|
||||||
node->intoGroup(Hy3GroupLayout::SplitH, ephemeral);
|
node->intoGroup(Hy3GroupLayout::SplitH, ephemeral);
|
||||||
} else {
|
return;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& group = node->parent->data.as_group;
|
||||||
|
auto layout
|
||||||
|
= group.layout == Hy3GroupLayout::SplitH ? Hy3GroupLayout::SplitV : Hy3GroupLayout::SplitH;
|
||||||
|
|
||||||
|
if (group.children.size() == 1) {
|
||||||
|
group.setLayout(layout);
|
||||||
|
group.setEphemeral(ephemeral);
|
||||||
|
node->parent->recalcSizePosRecursive();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->intoGroup(layout, ephemeral);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hy3Layout::changeGroupOn(Hy3Node& node, Hy3GroupLayout layout) {
|
||||||
|
if (node.parent == nullptr) {
|
||||||
|
makeGroupOn(&node, layout, GroupEphemeralityOption::Ephemeral);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& group = node.parent->data.as_group;
|
||||||
|
group.setLayout(layout);
|
||||||
|
node.parent->recalcSizePosRecursive();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hy3Layout::untabGroupOn(Hy3Node& node) {
|
||||||
|
if (node.parent == nullptr) return;
|
||||||
|
|
||||||
|
auto& group = node.parent->data.as_group;
|
||||||
|
if (group.layout != Hy3GroupLayout::Tabbed) return;
|
||||||
|
|
||||||
|
changeGroupOn(node, group.previous_nontab_layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hy3Layout::changeGroupToOppositeOn(Hy3Node& node) {
|
||||||
|
if (node.parent == nullptr) return;
|
||||||
|
|
||||||
|
auto& group = node.parent->data.as_group;
|
||||||
|
|
||||||
|
if (group.layout == Hy3GroupLayout::Tabbed) return;
|
||||||
|
group.setLayout(
|
||||||
|
group.layout == Hy3GroupLayout::SplitH ? Hy3GroupLayout::SplitV : Hy3GroupLayout::SplitH
|
||||||
|
);
|
||||||
|
node.parent->recalcSizePosRecursive();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hy3Layout::changeGroupEphemeralityOn(Hy3Node& node, bool ephemeral) {
|
||||||
|
if (node.parent == nullptr) return;
|
||||||
|
|
||||||
|
auto& group = node.parent->data.as_group;
|
||||||
|
group.setEphemeral(
|
||||||
|
ephemeral ? GroupEphemeralityOption::ForceEphemeral : GroupEphemeralityOption::Standard
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::shiftWindow(int workspace, ShiftDirection direction, bool once) {
|
void Hy3Layout::shiftWindow(int workspace, ShiftDirection direction, bool once) {
|
||||||
|
@ -799,7 +866,7 @@ void Hy3Layout::shiftWindow(int workspace, ShiftDirection direction, bool once)
|
||||||
|
|
||||||
if (once && node->parent != nullptr && node->parent->data.as_group.children.size() == 1) {
|
if (once && node->parent != nullptr && node->parent->data.as_group.children.size() == 1) {
|
||||||
if (node->parent->parent == nullptr) {
|
if (node->parent->parent == nullptr) {
|
||||||
node->parent->data.as_group.layout = Hy3GroupLayout::SplitH;
|
node->parent->data.as_group.setLayout(Hy3GroupLayout::SplitH);
|
||||||
node->parent->recalcSizePosRecursive();
|
node->parent->recalcSizePosRecursive();
|
||||||
} else {
|
} else {
|
||||||
auto* node2 = node->parent;
|
auto* node2 = node->parent;
|
||||||
|
@ -1424,7 +1491,9 @@ Hy3Node* Hy3Layout::shiftOrGetFocus(
|
||||||
if (group.layout != Hy3GroupLayout::Tabbed && group.children.size() == 2
|
if (group.layout != Hy3GroupLayout::Tabbed && group.children.size() == 2
|
||||||
&& std::find(group.children.begin(), group.children.end(), &node) != group.children.end())
|
&& std::find(group.children.begin(), group.children.end(), &node) != group.children.end())
|
||||||
{
|
{
|
||||||
group.layout = shiftIsVertical(direction) ? Hy3GroupLayout::SplitV : Hy3GroupLayout::SplitH;
|
group.setLayout(
|
||||||
|
shiftIsVertical(direction) ? Hy3GroupLayout::SplitV : Hy3GroupLayout::SplitH
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// wrap the root group in another group
|
// wrap the root group in another group
|
||||||
this->nodes.push_back({
|
this->nodes.push_back({
|
||||||
|
|
|
@ -90,8 +90,16 @@ public:
|
||||||
|
|
||||||
void makeGroupOnWorkspace(int workspace, Hy3GroupLayout, GroupEphemeralityOption);
|
void makeGroupOnWorkspace(int workspace, Hy3GroupLayout, GroupEphemeralityOption);
|
||||||
void makeOppositeGroupOnWorkspace(int workspace, GroupEphemeralityOption);
|
void makeOppositeGroupOnWorkspace(int workspace, GroupEphemeralityOption);
|
||||||
|
void changeGroupOnWorkspace(int workspace, Hy3GroupLayout);
|
||||||
|
void untabGroupOnWorkspace(int workspace);
|
||||||
|
void changeGroupToOppositeOnWorkspace(int workspace);
|
||||||
|
void changeGroupEphemeralityOnWorkspace(int workspace, bool ephemeral);
|
||||||
void makeGroupOn(Hy3Node*, Hy3GroupLayout, GroupEphemeralityOption);
|
void makeGroupOn(Hy3Node*, Hy3GroupLayout, GroupEphemeralityOption);
|
||||||
void makeOppositeGroupOn(Hy3Node*, GroupEphemeralityOption);
|
void makeOppositeGroupOn(Hy3Node*, GroupEphemeralityOption);
|
||||||
|
void changeGroupOn(Hy3Node&, Hy3GroupLayout);
|
||||||
|
void untabGroupOn(Hy3Node&);
|
||||||
|
void changeGroupToOppositeOn(Hy3Node&);
|
||||||
|
void changeGroupEphemeralityOn(Hy3Node&, bool ephemeral);
|
||||||
void shiftWindow(int workspace, ShiftDirection, bool once);
|
void shiftWindow(int workspace, ShiftDirection, bool once);
|
||||||
void shiftFocus(int workspace, ShiftDirection, bool visible);
|
void shiftFocus(int workspace, ShiftDirection, bool visible);
|
||||||
void changeFocus(int workspace, FocusShift);
|
void changeFocus(int workspace, FocusShift);
|
||||||
|
|
|
@ -8,10 +8,15 @@
|
||||||
|
|
||||||
// Hy3GroupData //
|
// 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) {
|
Hy3GroupData::Hy3GroupData(Hy3GroupData&& from) {
|
||||||
this->layout = from.layout;
|
this->layout = from.layout;
|
||||||
|
this->previous_nontab_layout = from.previous_nontab_layout;
|
||||||
this->children = std::move(from.children);
|
this->children = std::move(from.children);
|
||||||
this->group_focused = from.group_focused;
|
this->group_focused = from.group_focused;
|
||||||
this->expand_focused = from.expand_focused;
|
this->expand_focused = from.expand_focused;
|
||||||
|
@ -52,6 +57,24 @@ void Hy3GroupData::collapseExpansions() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Hy3GroupData::setLayout(Hy3GroupLayout layout) {
|
||||||
|
this->layout = layout;
|
||||||
|
|
||||||
|
if (layout != Hy3GroupLayout::Tabbed) {
|
||||||
|
this->previous_nontab_layout = layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hy3GroupData::setEphemeral(GroupEphemeralityOption ephemeral) {
|
||||||
|
switch (ephemeral) {
|
||||||
|
case GroupEphemeralityOption::Standard: this->ephemeral = false; break;
|
||||||
|
case GroupEphemeralityOption::ForceEphemeral: this->ephemeral = true; break;
|
||||||
|
case GroupEphemeralityOption::Ephemeral:
|
||||||
|
// no change
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Hy3NodeData //
|
// Hy3NodeData //
|
||||||
|
|
||||||
Hy3NodeData::Hy3NodeData(): Hy3NodeData((CWindow*) nullptr) {}
|
Hy3NodeData::Hy3NodeData(): Hy3NodeData((CWindow*) nullptr) {}
|
||||||
|
|
|
@ -29,6 +29,7 @@ enum class ExpandFocusType {
|
||||||
|
|
||||||
struct Hy3GroupData {
|
struct Hy3GroupData {
|
||||||
Hy3GroupLayout layout = Hy3GroupLayout::SplitH;
|
Hy3GroupLayout layout = Hy3GroupLayout::SplitH;
|
||||||
|
Hy3GroupLayout previous_nontab_layout = Hy3GroupLayout::SplitH;
|
||||||
std::list<Hy3Node*> children;
|
std::list<Hy3Node*> children;
|
||||||
bool group_focused = true;
|
bool group_focused = true;
|
||||||
Hy3Node* focused_child = nullptr;
|
Hy3Node* focused_child = nullptr;
|
||||||
|
@ -42,6 +43,8 @@ struct Hy3GroupData {
|
||||||
|
|
||||||
bool hasChild(Hy3Node* child);
|
bool hasChild(Hy3Node* child);
|
||||||
void collapseExpansions();
|
void collapseExpansions();
|
||||||
|
void setLayout(Hy3GroupLayout layout);
|
||||||
|
void setEphemeral(GroupEphemeralityOption ephemeral);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Hy3GroupData(Hy3GroupData&&);
|
Hy3GroupData(Hy3GroupData&&);
|
||||||
|
|
|
@ -43,6 +43,36 @@ 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);
|
||||||
|
|
||||||
|
if (args[0] == "h") {
|
||||||
|
g_Hy3Layout->changeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitH);
|
||||||
|
} else if (args[0] == "v") {
|
||||||
|
g_Hy3Layout->changeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitV);
|
||||||
|
} else if (args[0] == "tab") {
|
||||||
|
g_Hy3Layout->changeGroupOnWorkspace(workspace, Hy3GroupLayout::Tabbed);
|
||||||
|
} else if (args[0] == "untab") {
|
||||||
|
g_Hy3Layout->untabGroupOnWorkspace(workspace);
|
||||||
|
} else if (args[0] == "opposite") {
|
||||||
|
g_Hy3Layout->changeGroupToOppositeOnWorkspace(workspace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispatch_setephemeral(std::string value) {
|
||||||
|
int workspace = workspace_for_action();
|
||||||
|
if (workspace == -1) return;
|
||||||
|
|
||||||
|
auto args = CVarList(value);
|
||||||
|
|
||||||
|
bool ephemeral = args[0] == "true";
|
||||||
|
|
||||||
|
g_Hy3Layout->changeGroupEphemeralityOnWorkspace(workspace, ephemeral);
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<ShiftDirection> parseShiftArg(std::string arg) {
|
std::optional<ShiftDirection> parseShiftArg(std::string arg) {
|
||||||
if (arg == "l" || arg == "left") return ShiftDirection::Left;
|
if (arg == "l" || arg == "left") return ShiftDirection::Left;
|
||||||
else if (arg == "r" || arg == "right") return ShiftDirection::Right;
|
else if (arg == "r" || arg == "right") return ShiftDirection::Right;
|
||||||
|
@ -188,6 +218,8 @@ void dispatch_debug(std::string arg) {
|
||||||
|
|
||||||
void registerDispatchers() {
|
void registerDispatchers() {
|
||||||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:makegroup", dispatch_makegroup);
|
HyprlandAPI::addDispatcher(PHANDLE, "hy3:makegroup", dispatch_makegroup);
|
||||||
|
HyprlandAPI::addDispatcher(PHANDLE, "hy3:changegroup", dispatch_changegroup);
|
||||||
|
HyprlandAPI::addDispatcher(PHANDLE, "hy3:setephemeral", dispatch_setephemeral);
|
||||||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:movefocus", dispatch_movefocus);
|
HyprlandAPI::addDispatcher(PHANDLE, "hy3:movefocus", dispatch_movefocus);
|
||||||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:movewindow", dispatch_movewindow);
|
HyprlandAPI::addDispatcher(PHANDLE, "hy3:movewindow", dispatch_movewindow);
|
||||||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:changefocus", dispatch_changefocus);
|
HyprlandAPI::addDispatcher(PHANDLE, "hy3:changefocus", dispatch_changefocus);
|
||||||
|
|
Loading…
Add table
Reference in a new issue