mirror of
https://github.com/Trensa-Organization/hy3.git
synced 2025-03-15 18:53:40 +01:00
Add once
option to movewindow
This commit is contained in:
parent
f12993ecf0
commit
f72c5d0b48
4 changed files with 41 additions and 28 deletions
|
@ -33,8 +33,9 @@ You can use `hy3:makegroup` to create a new split.
|
||||||
|
|
||||||
### Dispatcher list
|
### Dispatcher list
|
||||||
- `hy3:makegroup, <h | v | opposite>` - 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 | left | down | up | right>` - 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 | left | down | up | right> [, once]` - move a window left, up, down, or right
|
||||||
|
- `once` - only move directly to the neighboring group, without moving into any of its subgroups
|
||||||
- `hy3:raisefocus` - raise the active focus one level
|
- `hy3:raisefocus` - raise the active focus one level
|
||||||
- `hy3:debugnodes` - print the node tree into the hyprland log
|
- `hy3:debugnodes` - print the node tree into the hyprland log
|
||||||
|
|
||||||
|
|
|
@ -1127,26 +1127,24 @@ void Hy3Layout::makeOppositeGroupOn(Hy3Node* node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hy3Node* shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, bool shift);
|
|
||||||
|
|
||||||
void Hy3Layout::shiftFocus(int workspace, ShiftDirection direction) {
|
void Hy3Layout::shiftFocus(int workspace, ShiftDirection direction) {
|
||||||
auto* node = this->getWorkspaceFocusedNode(workspace);
|
auto* node = this->getWorkspaceFocusedNode(workspace);
|
||||||
Debug::log(LOG, "ShiftFocus %p %d", node, direction);
|
Debug::log(LOG, "ShiftFocus %p %d", node, direction);
|
||||||
if (node == nullptr) return;
|
if (node == nullptr) return;
|
||||||
|
|
||||||
Hy3Node* target;
|
Hy3Node* target;
|
||||||
if ((target = this->shiftOrGetFocus(*node, direction, false))) {
|
if ((target = this->shiftOrGetFocus(*node, direction, false, false))) {
|
||||||
g_pCompositor->focusWindow(target->data.as_window);
|
g_pCompositor->focusWindow(target->data.as_window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::shiftWindow(int workspace, ShiftDirection direction) {
|
void Hy3Layout::shiftWindow(int workspace, ShiftDirection direction, bool once) {
|
||||||
auto* node = this->getWorkspaceFocusedNode(workspace);
|
auto* node = this->getWorkspaceFocusedNode(workspace);
|
||||||
Debug::log(LOG, "ShiftWindow %p %d", node, direction);
|
Debug::log(LOG, "ShiftWindow %p %d", node, direction);
|
||||||
if (node == nullptr) return;
|
if (node == nullptr) return;
|
||||||
|
|
||||||
|
|
||||||
this->shiftOrGetFocus(*node, direction, true);
|
this->shiftOrGetFocus(*node, direction, true, once);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shiftIsForward(ShiftDirection direction) {
|
bool shiftIsForward(ShiftDirection direction) {
|
||||||
|
@ -1162,16 +1160,20 @@ bool shiftMatchesLayout(Hy3GroupLayout layout, ShiftDirection direction) {
|
||||||
|| (layout != Hy3GroupLayout::SplitV && !shiftIsVertical(direction));
|
|| (layout != Hy3GroupLayout::SplitV && !shiftIsVertical(direction));
|
||||||
}
|
}
|
||||||
|
|
||||||
Hy3Node* Hy3Layout::shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, bool shift) {
|
Hy3Node* Hy3Layout::shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, bool shift, bool once) {
|
||||||
auto* break_origin = &node;
|
auto* break_origin = &node;
|
||||||
auto* break_parent = break_origin->parent;
|
auto* break_parent = break_origin->parent;
|
||||||
|
|
||||||
|
auto has_broken_once = false;
|
||||||
|
|
||||||
// break parents until we hit a container oriented the same way as the shift direction
|
// break parents until we hit a container oriented the same way as the shift direction
|
||||||
while (true) {
|
while (true) {
|
||||||
if (break_parent == nullptr) return nullptr;
|
if (break_parent == nullptr) return nullptr;
|
||||||
|
|
||||||
auto& group = break_parent->data.as_group; // must be a group in order to be a parent
|
auto& group = break_parent->data.as_group; // must be a group in order to be a parent
|
||||||
|
|
||||||
|
if (has_broken_once) break;
|
||||||
|
|
||||||
if (shiftMatchesLayout(group.layout, direction)) {
|
if (shiftMatchesLayout(group.layout, direction)) {
|
||||||
// group has the correct orientation
|
// group has the correct orientation
|
||||||
|
|
||||||
|
@ -1182,6 +1184,8 @@ Hy3Node* Hy3Layout::shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, boo
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
has_broken_once = true;
|
||||||
|
|
||||||
if (break_parent->parent == nullptr) {
|
if (break_parent->parent == nullptr) {
|
||||||
if (!shift) return nullptr;
|
if (!shift) return nullptr;
|
||||||
|
|
||||||
|
@ -1233,7 +1237,7 @@ Hy3Node* Hy3Layout::shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, boo
|
||||||
if (shiftIsForward(direction)) iter = std::next(iter);
|
if (shiftIsForward(direction)) iter = std::next(iter);
|
||||||
else iter = std::prev(iter);
|
else iter = std::prev(iter);
|
||||||
|
|
||||||
if ((*iter)->data.type == Hy3NodeData::Window) {
|
if ((*iter)->data.type == Hy3NodeData::Window || (shift && once && has_broken_once)) {
|
||||||
if (shift) {
|
if (shift) {
|
||||||
if (target_group == node.parent) {
|
if (target_group == node.parent) {
|
||||||
if (shiftIsForward(direction)) insert = std::next(iter);
|
if (shiftIsForward(direction)) insert = std::next(iter);
|
||||||
|
@ -1270,6 +1274,12 @@ Hy3Node* Hy3Layout::shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, boo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shift && once) {
|
||||||
|
if (shift_after) insert = std::next(iter);
|
||||||
|
else insert = iter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ((*iter)->data.type == Hy3NodeData::Window) {
|
if ((*iter)->data.type == Hy3NodeData::Window) {
|
||||||
if (shift) {
|
if (shift) {
|
||||||
if (shift_after) insert = std::next(iter);
|
if (shift_after) insert = std::next(iter);
|
||||||
|
|
|
@ -117,7 +117,7 @@ public:
|
||||||
void makeOppositeGroupOnWorkspace(int);
|
void makeOppositeGroupOnWorkspace(int);
|
||||||
void makeGroupOn(Hy3Node*, Hy3GroupLayout);
|
void makeGroupOn(Hy3Node*, Hy3GroupLayout);
|
||||||
void makeOppositeGroupOn(Hy3Node*);
|
void makeOppositeGroupOn(Hy3Node*);
|
||||||
void shiftWindow(int, ShiftDirection);
|
void shiftWindow(int, ShiftDirection, bool);
|
||||||
void shiftFocus(int, ShiftDirection);
|
void shiftFocus(int, ShiftDirection);
|
||||||
void raiseFocus(int);
|
void raiseFocus(int);
|
||||||
|
|
||||||
|
@ -140,7 +140,8 @@ private:
|
||||||
|
|
||||||
// if shift is true, shift the window in the given direction, returning nullptr,
|
// if shift is true, shift the window in the given direction, returning nullptr,
|
||||||
// if shift is false, return the window in the given direction or nullptr.
|
// if shift is false, return the window in the given direction or nullptr.
|
||||||
Hy3Node* shiftOrGetFocus(Hy3Node&, ShiftDirection, bool);
|
// if once is true, only one group will be broken out of / into
|
||||||
|
Hy3Node* shiftOrGetFocus(Hy3Node&, ShiftDirection, bool, bool);
|
||||||
|
|
||||||
friend struct Hy3Node;
|
friend struct Hy3Node;
|
||||||
};
|
};
|
||||||
|
|
35
src/main.cpp
35
src/main.cpp
|
@ -1,3 +1,5 @@
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include <hyprland/src/plugins/PluginAPI.hpp>
|
#include <hyprland/src/plugins/PluginAPI.hpp>
|
||||||
#include <hyprland/src/Compositor.hpp>
|
#include <hyprland/src/Compositor.hpp>
|
||||||
|
|
||||||
|
@ -48,18 +50,23 @@ void dispatch_makegroup(std::string arg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispatch_movewindow(std::string arg) {
|
std::optional<ShiftDirection> parseShiftArg(std::string arg) {
|
||||||
|
if (arg == "l" || arg == "left") return ShiftDirection::Left;
|
||||||
|
else if (arg == "r" || arg == "right") return ShiftDirection::Right;
|
||||||
|
else if (arg == "u" || arg == "up") return ShiftDirection::Up;
|
||||||
|
else if (arg == "d" || arg == "down") return ShiftDirection::Down;
|
||||||
|
else return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispatch_movewindow(std::string value) {
|
||||||
int workspace = workspace_for_action();
|
int workspace = workspace_for_action();
|
||||||
if (workspace < 0) return;
|
if (workspace < 0) return;
|
||||||
|
|
||||||
if (arg == "l") {
|
auto args = CVarList(value);
|
||||||
g_Hy3Layout->shiftWindow(workspace, ShiftDirection::Left);
|
|
||||||
} else if (arg == "u") {
|
if (auto shift = parseShiftArg(args[0])) {
|
||||||
g_Hy3Layout->shiftWindow(workspace, ShiftDirection::Up);
|
auto once = args[1] == "once";
|
||||||
} else if (arg == "d") {
|
g_Hy3Layout->shiftWindow(workspace, shift.value(), once);
|
||||||
g_Hy3Layout->shiftWindow(workspace, ShiftDirection::Down);
|
|
||||||
} else if (arg == "r") {
|
|
||||||
g_Hy3Layout->shiftWindow(workspace, ShiftDirection::Right);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,14 +74,8 @@ void dispatch_movefocus(std::string arg) {
|
||||||
int workspace = workspace_for_action();
|
int workspace = workspace_for_action();
|
||||||
if (workspace < 0) return;
|
if (workspace < 0) return;
|
||||||
|
|
||||||
if (arg == "l") {
|
if (auto shift = parseShiftArg(arg)) {
|
||||||
g_Hy3Layout->shiftFocus(workspace, ShiftDirection::Left);
|
g_Hy3Layout->shiftFocus(workspace, shift.value());
|
||||||
} else if (arg == "u") {
|
|
||||||
g_Hy3Layout->shiftFocus(workspace, ShiftDirection::Up);
|
|
||||||
} else if (arg == "d") {
|
|
||||||
g_Hy3Layout->shiftFocus(workspace, ShiftDirection::Down);
|
|
||||||
} else if (arg == "r") {
|
|
||||||
g_Hy3Layout->shiftFocus(workspace, ShiftDirection::Right);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue