mirror of
https://github.com/Trensa-Organization/hy3.git
synced 2025-03-15 10:43:40 +01:00
Window containment/swallowing MVP
This commit is contained in:
parent
2c8264b5dc
commit
cd3fd91b3b
6 changed files with 101 additions and 0 deletions
|
@ -116,6 +116,7 @@ plugin {
|
|||
- `prioritize_hovered` - prioritize the tab group under the mouse when multiple are stacked. use the lowest group if none is under the mouse.
|
||||
- `require_hovered` - affect the tab group under the mouse. do nothing if none are hovered.
|
||||
- `wrap` - wrap to the opposite size of the tab bar if moving off the end
|
||||
- `hy3:setswallow, <true | false | toggle>` - set the containing node's window swallow state
|
||||
- `hy3:debugnodes` - print the node tree into the hyprland log
|
||||
|
||||
## Installing
|
||||
|
|
|
@ -16,6 +16,59 @@ std::unique_ptr<HOOK_CALLBACK_FN> urgentHookPtr
|
|||
std::unique_ptr<HOOK_CALLBACK_FN> tickHookPtr
|
||||
= std::make_unique<HOOK_CALLBACK_FN>(Hy3Layout::tickHook);
|
||||
|
||||
bool performContainment(Hy3Node& node, bool contained, CWindow* window) {
|
||||
if (node.data.type == Hy3NodeType::Group) {
|
||||
auto& group = node.data.as_group;
|
||||
contained |= group.containment;
|
||||
|
||||
auto iter = node.data.as_group.children.begin();
|
||||
while (iter != node.data.as_group.children.end()) {
|
||||
switch ((*iter)->data.type) {
|
||||
case Hy3NodeType::Group: return performContainment(**iter, contained, window);
|
||||
case Hy3NodeType::Window:
|
||||
if (contained) {
|
||||
auto wpid = (*iter)->data.as_window->getPID();
|
||||
auto ppid = getPPIDof(window->getPID());
|
||||
while (ppid > 10) { // `> 10` yoinked from HL swallow
|
||||
if (ppid == wpid) {
|
||||
node.layout->nodes.push_back({
|
||||
.parent = &node,
|
||||
.data = window,
|
||||
.workspace_id = node.workspace_id,
|
||||
.layout = node.layout,
|
||||
});
|
||||
|
||||
auto& child_node = node.layout->nodes.back();
|
||||
|
||||
group.children.insert(std::next(iter), &child_node);
|
||||
child_node.markFocused();
|
||||
node.recalcSizePosRecursive();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ppid = getPPIDof(ppid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iter = std::next(iter);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Hy3Layout::onWindowCreated(CWindow* window) {
|
||||
for (auto& node: this->nodes) {
|
||||
if (node.parent == nullptr && performContainment(node, false, window)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
IHyprLayout::onWindowCreated(window);
|
||||
}
|
||||
|
||||
void Hy3Layout::onWindowCreatedTiling(CWindow* window) {
|
||||
if (window->m_bIsFloating) return;
|
||||
|
||||
|
@ -938,6 +991,18 @@ hastab:
|
|||
tab_node->recalcSizePosRecursive();
|
||||
}
|
||||
|
||||
void Hy3Layout::setNodeSwallow(int workspace, SetSwallowOption option) {
|
||||
auto* node = this->getWorkspaceFocusedNode(workspace);
|
||||
if (node == nullptr || node->parent == nullptr) return;
|
||||
|
||||
auto* containment = &node->parent->data.as_group.containment;
|
||||
switch (option) {
|
||||
case SetSwallowOption::NoSwallow: *containment = false;
|
||||
case SetSwallowOption::Swallow: *containment = true;
|
||||
case SetSwallowOption::Toggle: *containment = !*containment;
|
||||
}
|
||||
}
|
||||
|
||||
void Hy3Layout::killFocusedNode(int workspace) {
|
||||
if (g_pCompositor->m_pLastWindow != nullptr && g_pCompositor->m_pLastWindow->m_bIsFloating) {
|
||||
g_pCompositor->closeWindow(g_pCompositor->m_pLastWindow);
|
||||
|
|
|
@ -44,8 +44,15 @@ enum class TabFocusMousePriority {
|
|||
Require,
|
||||
};
|
||||
|
||||
enum class SetSwallowOption {
|
||||
NoSwallow,
|
||||
Swallow,
|
||||
Toggle,
|
||||
};
|
||||
|
||||
class Hy3Layout: public IHyprLayout {
|
||||
public:
|
||||
virtual void onWindowCreated(CWindow*);
|
||||
virtual void onWindowCreatedTiling(CWindow*);
|
||||
virtual void onWindowRemovedTiling(CWindow*);
|
||||
virtual void onWindowFocusChange(CWindow*);
|
||||
|
@ -75,6 +82,7 @@ public:
|
|||
void shiftFocus(int workspace, ShiftDirection, bool visible);
|
||||
void changeFocus(int workspace, FocusShift);
|
||||
void focusTab(int workspace, TabFocus target, TabFocusMousePriority, bool wrap_scroll, int index);
|
||||
void setNodeSwallow(int workspace, SetSwallowOption);
|
||||
void killFocusedNode(int workspace);
|
||||
|
||||
bool shouldRenderSelected(CWindow*);
|
||||
|
|
|
@ -525,6 +525,15 @@ std::string Hy3Node::debugNode() {
|
|||
|
||||
buf << "] size ratio: ";
|
||||
buf << this->size_ratio;
|
||||
|
||||
if (this->data.as_group.ephemeral) {
|
||||
buf << ", ephemeral";
|
||||
}
|
||||
|
||||
if (this->data.as_group.containment) {
|
||||
buf << ", containment";
|
||||
}
|
||||
|
||||
for (auto* child: this->data.as_group.children) {
|
||||
buf << "\n|-";
|
||||
if (child == nullptr) {
|
||||
|
|
|
@ -27,6 +27,7 @@ struct Hy3GroupData {
|
|||
bool group_focused = true;
|
||||
Hy3Node* focused_child = nullptr;
|
||||
bool ephemeral = false;
|
||||
bool containment = false;
|
||||
Hy3TabGroup* tab_bar = nullptr;
|
||||
|
||||
Hy3GroupData(Hy3GroupLayout layout);
|
||||
|
|
|
@ -126,6 +126,22 @@ void dispatch_focustab(std::string value) {
|
|||
g_Hy3Layout->focusTab(workspace, focus, mouse, wrap_scroll, index);
|
||||
}
|
||||
|
||||
void dispatch_setswallow(std::string arg) {
|
||||
int workspace = workspace_for_action();
|
||||
if (workspace == -1) return;
|
||||
|
||||
SetSwallowOption option;
|
||||
if (arg == "true") {
|
||||
option = SetSwallowOption::Swallow;
|
||||
} else if (arg == "false") {
|
||||
option = SetSwallowOption::NoSwallow;
|
||||
} else if (arg == "toggle") {
|
||||
option = SetSwallowOption::Toggle;
|
||||
} else return;
|
||||
|
||||
g_Hy3Layout->setNodeSwallow(workspace, option);
|
||||
}
|
||||
|
||||
void dispatch_killactive(std::string value) {
|
||||
int workspace = workspace_for_action();
|
||||
if (workspace == -1) return;
|
||||
|
@ -151,6 +167,7 @@ void registerDispatchers() {
|
|||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:movewindow", dispatch_movewindow);
|
||||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:changefocus", dispatch_changefocus);
|
||||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:focustab", dispatch_focustab);
|
||||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:setswallow", dispatch_setswallow);
|
||||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:killactive", dispatch_killactive);
|
||||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:debugnodes", dispatch_debug);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue