783c7ae0cf1fc263446f7114f068df03466310e4
- Author
- outfoxxed <outfoxxed@outfoxxed.me>
- Committer
- outfoxxed <outfoxxed@outfoxxed.me>
- Date
Message
Diff
This diff is truncated to protect this page.
1diff --git a/README.md b/README.md
2index 701c8167c190f9556115f394dcf0e5da47706274..bd96816bea6a0989fcce902bae7243f780f469a8 100644
3--- a/README.md
4+++ b/README.md
5@@ -317,6 +317,8 @@ plugin {
6 - `hy3:movewindow, <l | u | d | r | left | down | up | right>, [once], [visible]` - move a window left, up, down, or right
7 - `once` - only move directly to the neighboring group, without moving into any of its subgroups
8 - `visible` - only move between visible nodes, not hidden tabs
9+ - `hy3:movetoworkspace, <workspace>, [follow]` - move the active node to the given workspace
10+ - `follow` - change focus to the given workspace when moving the selected node
11 - `hy3:killactive` - close all windows in the focused node
12 - `hy3:changefocus, <top | bottom | raise | lower | tab | tabnode>`
13 - `top` - focus all nodes in the workspace
14diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
15index d29d801ff7cd0845f594a0c0866d1b1971316b4b..bca5224ae5f9878c7c7260386b242f6ff58c0a80 100644
16--- a/src/Hy3Layout.cpp
17+++ b/src/Hy3Layout.cpp
18@@ -94,12 +94,47 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) {
19 return;
20 }
21
22- auto* monitor = g_pCompositor->getMonitorFromID(window->m_iMonitorID);
23+ this->nodes.push_back({
24+ .parent = nullptr,
25+ .data = window,
26+ .workspace_id = window->m_iWorkspaceID,
27+ .layout = this,
28+ });
29+
30+ this->insertNode(this->nodes.back());
31+}
32+
33+void Hy3Layout::insertNode(Hy3Node& node) {
34+ if (node.parent != nullptr) {
35+ hy3_log(
36+ ERR,
37+ "insertNode called for node {:x} which already has a parent ({:x})",
38+ (uintptr_t) &node,
39+ (uintptr_t) node.parent
40+ );
41+ return;
42+ }
43+
44+ auto* workspace = g_pCompositor->getWorkspaceByID(node.workspace_id);
45+
46+ if (workspace == nullptr) {
47+ hy3_log(
48+ ERR,
49+ "insertNode called for node {:x} with invalid workspace id {}",
50+ (uintptr_t) &node,
51+ node.workspace_id
52+ );
53+ return;
54+ }
55+
56+ node.reparenting = true;
57+
58+ auto* monitor = g_pCompositor->getMonitorFromID(workspace->m_iMonitorID);
59
60 Hy3Node* opening_into;
61 Hy3Node* opening_after = nullptr;
62
63- auto* root = this->getWorkspaceRootGroup(window->m_iWorkspaceID);
64+ auto* root = this->getWorkspaceRootGroup(node.workspace_id);
65
66 if (root != nullptr) {
67 opening_after = root->getFocusedNode();
68@@ -112,27 +147,36 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) {
69 }
70
71 if (opening_after == nullptr) {
72- if (g_pCompositor->m_pLastWindow != nullptr && !g_pCompositor->m_pLastWindow->m_bIsFloating
73- && g_pCompositor->m_pLastWindow != window
74- && g_pCompositor->m_pLastWindow->m_iWorkspaceID == window->m_iWorkspaceID
75+ if (g_pCompositor->m_pLastWindow != nullptr
76+ && g_pCompositor->m_pLastWindow->m_iWorkspaceID == node.workspace_id
77+ && !g_pCompositor->m_pLastWindow->m_bIsFloating
78+ && (node.data.type == Hy3NodeType::Window
79+ || g_pCompositor->m_pLastWindow != node.data.as_window)
80 && g_pCompositor->m_pLastWindow->m_bIsMapped)
81 {
82 opening_after = this->getNodeFromWindow(g_pCompositor->m_pLastWindow);
83 } else {
84- opening_after = this->getNodeFromWindow(
85- g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal())
86- );
87+ auto* mouse_window =
88+ g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal());
89+
90+ if (mouse_window != nullptr && mouse_window->m_iWorkspaceID == node.workspace_id) {
91+ opening_after = this->getNodeFromWindow(mouse_window);
92+ }
93 }
94 }
95
96- if (opening_after != nullptr && opening_after->workspace_id != window->m_iWorkspaceID) {
97+ if (opening_after != nullptr
98+ && ((node.data.type == Hy3NodeType::Group
99+ && (opening_after == &node || node.data.as_group.hasChild(opening_after)))
100+ || opening_after->reparenting))
101+ {
102 opening_after = nullptr;
103 }
104
105 if (opening_after != nullptr) {
106 opening_into = opening_after->parent;
107 } else {
108- if ((opening_into = this->getWorkspaceRootGroup(window->m_iWorkspaceID)) == nullptr) {
109+ if ((opening_into = this->getWorkspaceRootGroup(node.workspace_id)) == nullptr) {
110 static const auto* tab_first_window =
111 &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tab_first_window")->intValue;
112
113@@ -140,7 +184,7 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) {
114 .data = Hy3GroupLayout::SplitH,
115 .position = monitor->vecPosition + monitor->vecReservedTopLeft,
116 .size = monitor->vecSize - monitor->vecReservedTopLeft - monitor->vecReservedBottomRight,
117- .workspace_id = window->m_iWorkspaceID,
118diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp
119index a165dcedfc7c5d070d1a64147d2714ca75a41986..9409be8df029da446cca43cdf6f7be8bb03bb6d4 100644
120--- a/src/Hy3Layout.hpp
121+++ b/src/Hy3Layout.hpp
122@@ -91,6 +91,7 @@ public:
123 virtual void onEnable();
124 virtual void onDisable();
125
126+ void insertNode(Hy3Node& node);
127 void makeGroupOnWorkspace(int workspace, Hy3GroupLayout, GroupEphemeralityOption);
128 void makeOppositeGroupOnWorkspace(int workspace, GroupEphemeralityOption);
129 void changeGroupOnWorkspace(int workspace, Hy3GroupLayout);
130@@ -108,6 +109,7 @@ public:
131 void shiftNode(Hy3Node&, ShiftDirection, bool once, bool visible);
132 void shiftWindow(int workspace, ShiftDirection, bool once, bool visible);
133 void shiftFocus(int workspace, ShiftDirection, bool visible);
134+ void moveNodeToWorkspace(int origin, std::string wsname, bool follow);
135 void changeFocus(int workspace, FocusShift);
136 void focusTab(int workspace, TabFocus target, TabFocusMousePriority, bool wrap_scroll, int index);
137 void setNodeSwallow(int workspace, SetSwallowOption);
138diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp
139index 99c2b47b98306087229e71f9d298864daaf42ff0..35fd75294cab4943c663245c2d22f0cebff4c641 100644
140--- a/src/Hy3Node.cpp
141+++ b/src/Hy3Node.cpp
142@@ -759,6 +759,7 @@ Hy3Node* Hy3Node::removeFromParentRecursive(Hy3Node** expand_actor) {
143 }
144 }
145
146+ this->parent = nullptr;
147 return parent;
148 }
149
150diff --git a/src/Hy3Node.hpp b/src/Hy3Node.hpp
151index 4b17d824100c3a5b4e90890cc0f433984947a79e..bd25556f106e4ddd43b0c0f3baaa482f20998619 100644
152--- a/src/Hy3Node.hpp
153+++ b/src/Hy3Node.hpp
154@@ -79,6 +79,7 @@ public:
155
156 struct Hy3Node {
157 Hy3Node* parent = nullptr;
158+ bool reparenting = false;
159 Hy3NodeData data;
160 Vector2D position;
161 Vector2D size;
162diff --git a/src/dispatchers.cpp b/src/dispatchers.cpp
163index f4d663ce574065082edfdaf0ff25c513a238aba9..3d721bc62ca624f284001c66a4d846fe77f906c4 100644
164--- a/src/dispatchers.cpp
165+++ b/src/dispatchers.cpp
166@@ -119,6 +119,20 @@ void dispatch_movefocus(std::string value) {
167 }
168 }
169
170+void dispatch_move_to_workspace(std::string value) {
171+ int origin_workspace = workspace_for_action();
172+ if (origin_workspace == -1) return;
173+
174+ auto args = CVarList(value);
175+
176+ auto workspace = args[0];
177+ if (workspace == "") return;
178+
179+ bool follow = args[1] == "follow";
180+
181+ g_Hy3Layout->moveNodeToWorkspace(origin_workspace, workspace, follow);
182+}
183+
184 void dispatch_changefocus(std::string arg) {
185 int workspace = workspace_for_action();
186 if (workspace == -1) return;
187@@ -237,6 +251,7 @@ void registerDispatchers() {
188 HyprlandAPI::addDispatcher(PHANDLE, "hy3:setephemeral", dispatch_setephemeral);
189 HyprlandAPI::addDispatcher(PHANDLE, "hy3:movefocus", dispatch_movefocus);
190 HyprlandAPI::addDispatcher(PHANDLE, "hy3:movewindow", dispatch_movewindow);
191+ HyprlandAPI::addDispatcher(PHANDLE, "hy3:movetoworkspace", dispatch_move_to_workspace);
192 HyprlandAPI::addDispatcher(PHANDLE, "hy3:changefocus", dispatch_changefocus);
193 HyprlandAPI::addDispatcher(PHANDLE, "hy3:focustab", dispatch_focustab);
194 HyprlandAPI::addDispatcher(PHANDLE, "hy3:setswallow", dispatch_setswallow);