diff --git a/README.md b/README.md index 4921513..f698cb0 100644 --- a/README.md +++ b/README.md @@ -91,10 +91,11 @@ plugin { ### Dispatcher list - `hy3:makegroup, ` - make a vertical / horizontal split or tab group - - `hy3:movefocus, ` - move the focus left, up, down, or right + - `hy3:movefocus, [, visible]` - move the focus left, up, down, or right + - `visible` - only move between visible nodes, not hidden tabs - `hy3:movewindow, [, 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:changefocus ` + - `hy3:changefocus, ` - `top` - focus all nodes in the workspace - `bottom` - focus the single root selection window - `raise` - raise focus one level diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index e984437..beb4448 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -1385,13 +1385,13 @@ void Hy3Layout::makeOppositeGroupOn(Hy3Node* node) { } } -void Hy3Layout::shiftFocus(int workspace, ShiftDirection direction) { +void Hy3Layout::shiftFocus(int workspace, ShiftDirection direction, bool visible) { auto* node = this->getWorkspaceFocusedNode(workspace); Debug::log(LOG, "ShiftFocus %p %d", node, direction); if (node == nullptr) return; Hy3Node* target; - if ((target = this->shiftOrGetFocus(*node, direction, false, false))) { + if ((target = this->shiftOrGetFocus(*node, direction, false, false, visible))) { target->focus(); while (target->parent != nullptr) target = target->parent; target->recalcSizePosRecursive(); @@ -1403,7 +1403,7 @@ void Hy3Layout::shiftWindow(int workspace, ShiftDirection direction, bool once) Debug::log(LOG, "ShiftWindow %p %d", node, direction); if (node == nullptr) return; - this->shiftOrGetFocus(*node, direction, true, once); + this->shiftOrGetFocus(*node, direction, true, once, false); } bool shiftIsForward(ShiftDirection direction) { @@ -1419,8 +1419,13 @@ bool shiftMatchesLayout(Hy3GroupLayout layout, ShiftDirection direction) { || (layout != Hy3GroupLayout::SplitV && !shiftIsVertical(direction)); } -Hy3Node* -Hy3Layout::shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, bool shift, bool once) { +Hy3Node* Hy3Layout::shiftOrGetFocus( + Hy3Node& node, + ShiftDirection direction, + bool shift, + bool once, + bool visible +) { auto* break_origin = &node; auto* break_parent = break_origin->parent; @@ -1433,7 +1438,9 @@ Hy3Layout::shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, bool shift, auto& group = break_parent->data.as_group; // must be a group in order to be a parent - if (shiftMatchesLayout(group.layout, direction)) { + if (shiftMatchesLayout(group.layout, direction) + && (!visible || group.layout != Hy3GroupLayout::Tabbed)) + { // group has the correct orientation if (once && shift && has_broken_once) break; diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp index dee25d7..c534e5a 100644 --- a/src/Hy3Layout.hpp +++ b/src/Hy3Layout.hpp @@ -144,7 +144,7 @@ public: void makeGroupOn(Hy3Node*, Hy3GroupLayout); void makeOppositeGroupOn(Hy3Node*); void shiftWindow(int, ShiftDirection, bool); - void shiftFocus(int, ShiftDirection); + void shiftFocus(int, ShiftDirection, bool); void changeFocus(int, FocusShift); void focusTab(int); @@ -175,7 +175,7 @@ private: // 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 once is true, only one group will be broken out of / into - Hy3Node* shiftOrGetFocus(Hy3Node&, ShiftDirection, bool, bool); + Hy3Node* shiftOrGetFocus(Hy3Node&, ShiftDirection, bool, bool, bool); friend struct Hy3Node; }; diff --git a/src/main.cpp b/src/main.cpp index 9093651..05daae3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -70,12 +70,14 @@ void dispatch_movewindow(std::string value) { } } -void dispatch_movefocus(std::string arg) { +void dispatch_movefocus(std::string value) { int workspace = workspace_for_action(); if (workspace == -1) return; - if (auto shift = parseShiftArg(arg)) { - g_Hy3Layout->shiftFocus(workspace, shift.value()); + auto args = CVarList(value); + + if (auto shift = parseShiftArg(args[0])) { + g_Hy3Layout->shiftFocus(workspace, shift.value(), args[1] == "visible"); } }