Skip to content

Commit

Permalink
Window containment/swallowing MVP
Browse files Browse the repository at this point in the history
  • Loading branch information
outfoxxed committed Jul 20, 2023
1 parent 2c8264b commit cd3fd91
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
65 changes: 65 additions & 0 deletions src/Hy3Layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -938,6 +991,18 @@ void Hy3Layout::focusTab(
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);
Expand Down
8 changes: 8 additions & 0 deletions src/Hy3Layout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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*);
Expand Down Expand Up @@ -75,6 +82,7 @@ class Hy3Layout: public IHyprLayout {
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*);
Expand Down
9 changes: 9 additions & 0 deletions src/Hy3Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions src/Hy3Node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
17 changes: 17 additions & 0 deletions src/dispatchers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}

0 comments on commit cd3fd91

Please sign in to comment.