Diff
1diff --git a/README.md b/README.md
2index 492151308c9f72cbc7bc63383891eab338ad5a02..f698cb07eb0331b9a2f7703a72223bb44941ea9e 100644
3--- a/README.md
4+++ b/README.md
5@@ -91,10 +91,11 @@ plugin {
6
7 ### Dispatcher list
8 - `hy3:makegroup, <h | v | opposite | tab>` - make a vertical / horizontal split or tab group
9- - `hy3:movefocus, <l | u | d | r | left | down | up | right>` - move the focus left, up, down, or right
10+ - `hy3:movefocus, <l | u | d | r | left | down | up | right> [, visible]` - move the focus left, up, down, or right
11+ - `visible` - only move between visible nodes, not hidden tabs
12 - `hy3:movewindow, <l | u | d | r | left | down | up | right> [, once]` - move a window left, up, down, or right
13 - `once` - only move directly to the neighboring group, without moving into any of its subgroups
14- - `hy3:changefocus <top | bottom | raise | lower | tab | tabnode>`
15+ - `hy3:changefocus, <top | bottom | raise | lower | tab | tabnode>`
16 - `top` - focus all nodes in the workspace
17 - `bottom` - focus the single root selection window
18 - `raise` - raise focus one level
19diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
20index e984437f7f37b8287ed9dc7a0727d108325faecf..beb4448056b6af40f81e8efb64d28a628184aa33 100644
21--- a/src/Hy3Layout.cpp
22+++ b/src/Hy3Layout.cpp
23@@ -1385,13 +1385,13 @@ void Hy3Layout::makeOppositeGroupOn(Hy3Node* node) {
24 }
25 }
26
27-void Hy3Layout::shiftFocus(int workspace, ShiftDirection direction) {
28+void Hy3Layout::shiftFocus(int workspace, ShiftDirection direction, bool visible) {
29 auto* node = this->getWorkspaceFocusedNode(workspace);
30 Debug::log(LOG, "ShiftFocus %p %d", node, direction);
31 if (node == nullptr) return;
32
33 Hy3Node* target;
34- if ((target = this->shiftOrGetFocus(*node, direction, false, false))) {
35+ if ((target = this->shiftOrGetFocus(*node, direction, false, false, visible))) {
36 target->focus();
37 while (target->parent != nullptr) target = target->parent;
38 target->recalcSizePosRecursive();
39@@ -1403,7 +1403,7 @@ void Hy3Layout::shiftWindow(int workspace, ShiftDirection direction, bool once)
40 Debug::log(LOG, "ShiftWindow %p %d", node, direction);
41 if (node == nullptr) return;
42
43- this->shiftOrGetFocus(*node, direction, true, once);
44+ this->shiftOrGetFocus(*node, direction, true, once, false);
45 }
46
47 bool shiftIsForward(ShiftDirection direction) {
48@@ -1419,8 +1419,13 @@ bool shiftMatchesLayout(Hy3GroupLayout layout, ShiftDirection direction) {
49 || (layout != Hy3GroupLayout::SplitV && !shiftIsVertical(direction));
50 }
51
52-Hy3Node*
53-Hy3Layout::shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, bool shift, bool once) {
54+Hy3Node* Hy3Layout::shiftOrGetFocus(
55+ Hy3Node& node,
56+ ShiftDirection direction,
57+ bool shift,
58+ bool once,
59+ bool visible
60+) {
61 auto* break_origin = &node;
62 auto* break_parent = break_origin->parent;
63
64@@ -1433,7 +1438,9 @@ Hy3Layout::shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, bool shift,
65
66 auto& group = break_parent->data.as_group; // must be a group in order to be a parent
67
68- if (shiftMatchesLayout(group.layout, direction)) {
69+ if (shiftMatchesLayout(group.layout, direction)
70+ && (!visible || group.layout != Hy3GroupLayout::Tabbed))
71+ {
72 // group has the correct orientation
73
74 if (once && shift && has_broken_once) break;
75diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp
76index dee25d790372cb4d56c24c1cd0bb1d0e0702ee90..c534e5adb6aee33152e139355033b4fbfff96229 100644
77--- a/src/Hy3Layout.hpp
78+++ b/src/Hy3Layout.hpp
79@@ -144,7 +144,7 @@ public:
80 void makeGroupOn(Hy3Node*, Hy3GroupLayout);
81 void makeOppositeGroupOn(Hy3Node*);
82 void shiftWindow(int, ShiftDirection, bool);
83- void shiftFocus(int, ShiftDirection);
84+ void shiftFocus(int, ShiftDirection, bool);
85 void changeFocus(int, FocusShift);
86 void focusTab(int);
87
88@@ -175,7 +175,7 @@ private:
89 // if shift is true, shift the window in the given direction, returning
90 // nullptr, if shift is false, return the window in the given direction or
91 // nullptr. if once is true, only one group will be broken out of / into
92- Hy3Node* shiftOrGetFocus(Hy3Node&, ShiftDirection, bool, bool);
93+ Hy3Node* shiftOrGetFocus(Hy3Node&, ShiftDirection, bool, bool, bool);
94
95 friend struct Hy3Node;
96 };
97diff --git a/src/main.cpp b/src/main.cpp
98index 909365191455eaa41b4af1c8c38bb6881383820e..05daae311d93066b22256118d3fb539001b47c9c 100644
99--- a/src/main.cpp
100+++ b/src/main.cpp
101@@ -70,12 +70,14 @@ void dispatch_movewindow(std::string value) {
102 }
103 }
104
105-void dispatch_movefocus(std::string arg) {
106+void dispatch_movefocus(std::string value) {
107 int workspace = workspace_for_action();
108 if (workspace == -1) return;
109
110- if (auto shift = parseShiftArg(arg)) {
111- g_Hy3Layout->shiftFocus(workspace, shift.value());
112+ auto args = CVarList(value);
113+
114+ if (auto shift = parseShiftArg(args[0])) {
115+ g_Hy3Layout->shiftFocus(workspace, shift.value(), args[1] == "visible");
116 }
117 }
118