mirror of
https://github.com/Trensa-Organization/hy3.git
synced 2025-03-15 18:53: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.
|
- `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.
|
- `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
|
- `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
|
- `hy3:debugnodes` - print the node tree into the hyprland log
|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|
|
@ -16,6 +16,59 @@ std::unique_ptr<HOOK_CALLBACK_FN> urgentHookPtr
|
||||||
std::unique_ptr<HOOK_CALLBACK_FN> tickHookPtr
|
std::unique_ptr<HOOK_CALLBACK_FN> tickHookPtr
|
||||||
= std::make_unique<HOOK_CALLBACK_FN>(Hy3Layout::tickHook);
|
= 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) {
|
void Hy3Layout::onWindowCreatedTiling(CWindow* window) {
|
||||||
if (window->m_bIsFloating) return;
|
if (window->m_bIsFloating) return;
|
||||||
|
|
||||||
|
@ -938,6 +991,18 @@ hastab:
|
||||||
tab_node->recalcSizePosRecursive();
|
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) {
|
void Hy3Layout::killFocusedNode(int workspace) {
|
||||||
if (g_pCompositor->m_pLastWindow != nullptr && g_pCompositor->m_pLastWindow->m_bIsFloating) {
|
if (g_pCompositor->m_pLastWindow != nullptr && g_pCompositor->m_pLastWindow->m_bIsFloating) {
|
||||||
g_pCompositor->closeWindow(g_pCompositor->m_pLastWindow);
|
g_pCompositor->closeWindow(g_pCompositor->m_pLastWindow);
|
||||||
|
|
|
@ -44,8 +44,15 @@ enum class TabFocusMousePriority {
|
||||||
Require,
|
Require,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class SetSwallowOption {
|
||||||
|
NoSwallow,
|
||||||
|
Swallow,
|
||||||
|
Toggle,
|
||||||
|
};
|
||||||
|
|
||||||
class Hy3Layout: public IHyprLayout {
|
class Hy3Layout: public IHyprLayout {
|
||||||
public:
|
public:
|
||||||
|
virtual void onWindowCreated(CWindow*);
|
||||||
virtual void onWindowCreatedTiling(CWindow*);
|
virtual void onWindowCreatedTiling(CWindow*);
|
||||||
virtual void onWindowRemovedTiling(CWindow*);
|
virtual void onWindowRemovedTiling(CWindow*);
|
||||||
virtual void onWindowFocusChange(CWindow*);
|
virtual void onWindowFocusChange(CWindow*);
|
||||||
|
@ -75,6 +82,7 @@ public:
|
||||||
void shiftFocus(int workspace, ShiftDirection, bool visible);
|
void shiftFocus(int workspace, ShiftDirection, bool visible);
|
||||||
void changeFocus(int workspace, FocusShift);
|
void changeFocus(int workspace, FocusShift);
|
||||||
void focusTab(int workspace, TabFocus target, TabFocusMousePriority, bool wrap_scroll, int index);
|
void focusTab(int workspace, TabFocus target, TabFocusMousePriority, bool wrap_scroll, int index);
|
||||||
|
void setNodeSwallow(int workspace, SetSwallowOption);
|
||||||
void killFocusedNode(int workspace);
|
void killFocusedNode(int workspace);
|
||||||
|
|
||||||
bool shouldRenderSelected(CWindow*);
|
bool shouldRenderSelected(CWindow*);
|
||||||
|
|
|
@ -525,6 +525,15 @@ std::string Hy3Node::debugNode() {
|
||||||
|
|
||||||
buf << "] size ratio: ";
|
buf << "] size ratio: ";
|
||||||
buf << this->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) {
|
for (auto* child: this->data.as_group.children) {
|
||||||
buf << "\n|-";
|
buf << "\n|-";
|
||||||
if (child == nullptr) {
|
if (child == nullptr) {
|
||||||
|
|
|
@ -27,6 +27,7 @@ struct Hy3GroupData {
|
||||||
bool group_focused = true;
|
bool group_focused = true;
|
||||||
Hy3Node* focused_child = nullptr;
|
Hy3Node* focused_child = nullptr;
|
||||||
bool ephemeral = false;
|
bool ephemeral = false;
|
||||||
|
bool containment = false;
|
||||||
Hy3TabGroup* tab_bar = nullptr;
|
Hy3TabGroup* tab_bar = nullptr;
|
||||||
|
|
||||||
Hy3GroupData(Hy3GroupLayout layout);
|
Hy3GroupData(Hy3GroupLayout layout);
|
||||||
|
|
|
@ -126,6 +126,22 @@ void dispatch_focustab(std::string value) {
|
||||||
g_Hy3Layout->focusTab(workspace, focus, mouse, wrap_scroll, index);
|
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) {
|
void dispatch_killactive(std::string value) {
|
||||||
int workspace = workspace_for_action();
|
int workspace = workspace_for_action();
|
||||||
if (workspace == -1) return;
|
if (workspace == -1) return;
|
||||||
|
@ -151,6 +167,7 @@ void registerDispatchers() {
|
||||||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:movewindow", dispatch_movewindow);
|
HyprlandAPI::addDispatcher(PHANDLE, "hy3:movewindow", dispatch_movewindow);
|
||||||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:changefocus", dispatch_changefocus);
|
HyprlandAPI::addDispatcher(PHANDLE, "hy3:changefocus", dispatch_changefocus);
|
||||||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:focustab", dispatch_focustab);
|
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:killactive", dispatch_killactive);
|
||||||
HyprlandAPI::addDispatcher(PHANDLE, "hy3:debugnodes", dispatch_debug);
|
HyprlandAPI::addDispatcher(PHANDLE, "hy3:debugnodes", dispatch_debug);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue