diff --git a/README.md b/README.md index a059ee6..a422339 100644 --- a/README.md +++ b/README.md @@ -341,6 +341,7 @@ plugin { - `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:debugnodes` - print the node tree into the hyprland log + - `hy3:resizenode, ` - like Hyprland `resizeactive`, but applied to the whole focused group instead of just a window - :warning: **ALPHA QUALITY** `hy3:setswallow, ` - set the containing node's window swallow state - :warning: **ALPHA QUALITY** `hy3:expand, ` - expand the current node to cover other nodes - `expand` - expand by one node diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index 14b3c9b..7cfd779 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -407,16 +407,9 @@ ShiftDirection reverse(ShiftDirection direction) { } } -void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CWindow* pWindow) { - auto window = pWindow ? pWindow : g_pCompositor->m_pLastWindow; - if (!g_pCompositor->windowValidMapped(window)) return; - - auto* node = this->getNodeFromWindow(window); - - if (node != nullptr) { - node = &node->getExpandActor(); - - auto monitor = g_pCompositor->getMonitorFromID(window->m_iMonitorID); +void executeResizeOperation(const Vector2D& delta, eRectCorner corner, Hy3Node *node, CMonitor* monitor) { + if (node == nullptr) return; + if (monitor == nullptr) return; const bool display_left = STICKS(node->position.x, monitor->vecPosition.x + monitor->vecReservedTopLeft.x); @@ -465,12 +458,12 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW : ShiftDirection::Down; } - // Find the neighboring node in each axis, which will be either above or at the - // same level as the initiating node in the layout hierarchy. These are the nodes - // which must get resized (rather than the initiator) because they are the - // highest point in the hierarchy - auto horizontal_neighbor = node->findNeighbor(target_edge_x); - auto vertical_neighbor = node->findNeighbor(target_edge_y); + // Find the neighboring node in each axis, which will be either above or at the + // same level as the initiating node in the layout hierarchy. These are the nodes + // which must get resized (rather than the initiator) because they are the + // highest point in the hierarchy + auto horizontal_neighbor = node->findNeighbor(target_edge_x); + auto vertical_neighbor = node->findNeighbor(target_edge_y); static const auto animate = ConfigValue("misc:animate_manual_resizes"); @@ -480,11 +473,28 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW horizontal_neighbor->resize(reverse(target_edge_x), resize_delta.x, *animate == 0); } - if (vertical_neighbor) { - vertical_neighbor->resize(reverse(target_edge_y), resize_delta.y, *animate == 0); - } + if (vertical_neighbor) { + vertical_neighbor->resize(reverse(target_edge_y), resize_delta.y, *animate == 0); } - } else if (window->m_bIsFloating) { + } +} + +void Hy3Layout::resizeNode(const Vector2D& delta, eRectCorner corner, Hy3Node* node) { + if(node == nullptr) return; + + auto monitor = g_pCompositor->getMonitorFromID(g_pCompositor->getWorkspaceByID(node->workspace_id)->m_iMonitorID); + executeResizeOperation(delta, corner, node, monitor); +} + +void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CWindow* pWindow) { + auto window = pWindow ? pWindow : g_pCompositor->m_pLastWindow; + if(window == nullptr || ! g_pCompositor->windowValidMapped(window)) return; + + auto* node = this->getNodeFromWindow(window); + + if (node != nullptr) { + executeResizeOperation(delta, corner, &node->getExpandActor(), g_pCompositor->getMonitorFromID(window->m_iMonitorID)); + } else if(window->m_bIsFloating) { // No parent node - is this a floating window? If so, use the same logic as the `main` layout const auto required_size = Vector2D( std::max((window->m_vRealSize.goalv() + delta).x, 20.0), diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp index 766d0bb..0eff9d4 100644 --- a/src/Hy3Layout.hpp +++ b/src/Hy3Layout.hpp @@ -117,6 +117,7 @@ public: void setNodeSwallow(int workspace, SetSwallowOption); void killFocusedNode(int workspace); void expand(int workspace, ExpandOption, ExpandFullscreenOption); + void resizeNode(const Vector2D& delta, eRectCorner corner, Hy3Node* node); bool shouldRenderSelected(CWindow*); @@ -146,7 +147,6 @@ private: void updateAutotileWorkspaces(); bool shouldAutotileWorkspace(int); - void resizeNode(Hy3Node*, Vector2D, ShiftDirection resize_edge_x, ShiftDirection resize_edge_y); struct { std::string raw_workspaces; diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp index 5eed0fc..4c833a1 100644 --- a/src/Hy3Node.cpp +++ b/src/Hy3Node.cpp @@ -926,6 +926,8 @@ void Hy3Node::resize(ShiftDirection direction, double delta, bool no_animation) neighbor->size_ratio = requested_neighbor_size_ratio; parent_node->recalcSizePosRecursive(no_animation); + } else { + hy3_log(WARN, "Requested size ratio {} or {} out of bounds, ignoring", requested_size_ratio, requested_neighbor_size_ratio); } } } diff --git a/src/dispatchers.cpp b/src/dispatchers.cpp index 667b1cf..5661a7a 100644 --- a/src/dispatchers.cpp +++ b/src/dispatchers.cpp @@ -8,6 +8,7 @@ int workspace_for_action(bool allow_fullscreen = false) { if (g_pLayoutManager->getCurrentLayout() != g_Hy3Layout.get()) return -1; + if(!g_pCompositor->m_pLastMonitor) return -1; int workspace_id = g_pCompositor->m_pLastMonitor->activeWorkspace; @@ -245,7 +246,19 @@ void dispatch_debug(std::string arg) { } } +void dispatch_resizenode(std::string value) { + int workspace = workspace_for_action(); + if (workspace == -1) return; + + auto* node = g_Hy3Layout->getWorkspaceFocusedNode(workspace, false, true); + const auto delta = g_pCompositor->parseWindowVectorArgsRelative(value, Vector2D(0, 0)); + + hy3_log(LOG, "resizeNode: node: {:x}, delta: {:X}", (uintptr_t)node, delta); + g_Hy3Layout->resizeNode(delta, CORNER_NONE, node); +} + void registerDispatchers() { + HyprlandAPI::addDispatcher(PHANDLE, "hy3:resizenode", dispatch_resizenode); HyprlandAPI::addDispatcher(PHANDLE, "hy3:makegroup", dispatch_makegroup); HyprlandAPI::addDispatcher(PHANDLE, "hy3:changegroup", dispatch_changegroup); HyprlandAPI::addDispatcher(PHANDLE, "hy3:setephemeral", dispatch_setephemeral);