From 78a423075cc1a97db7e3b84623f7f7e68d75237b Mon Sep 17 00:00:00 2001 From: Olekoop Date: Sat, 16 Dec 2023 16:58:24 +0100 Subject: [PATCH 01/27] Add option to center window title --- README.md | 3 +++ src/TabGroup.cpp | 4 ++++ src/main.cpp | 1 + 3 files changed, 8 insertions(+) diff --git a/README.md b/README.md index 0867132..24f04f0 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,9 @@ plugin { # render the window title on the bar render_text = # default: true + # center the window title + text_center = # default: false + # font to render the window title with text_font = # default: Sans diff --git a/src/TabGroup.cpp b/src/TabGroup.cpp index 217b88e..7888984 100644 --- a/src/TabGroup.cpp +++ b/src/TabGroup.cpp @@ -128,6 +128,7 @@ void Hy3TabBarEntry::prepareTexture(float scale, CBox& box) { // clang-format off static const auto* s_rounding = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:rounding")->intValue; static const auto* render_text = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:render_text")->intValue; + static const auto* text_center = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:text_center")->intValue; static const auto* text_font = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:text_font")->strValue; static const auto* text_height = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:text_height")->intValue; static const auto* text_padding = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:text_padding")->intValue; @@ -224,6 +225,9 @@ void Hy3TabBarEntry::prepareTexture(float scale, CBox& box) { PangoLayout* layout = pango_cairo_create_layout(cairo); pango_layout_set_text(layout, this->window_title.c_str(), -1); + if (*text_center) + pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); + PangoFontDescription* font_desc = pango_font_description_from_string(text_font->c_str()); pango_font_description_set_size(font_desc, *text_height * scale * PANGO_SCALE); pango_layout_set_font_description(layout, font_desc); diff --git a/src/main.cpp b/src/main.cpp index b0820f4..aebe592 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,6 +44,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { CONF("tabs:from_top", int, 0); CONF("tabs:rounding", int, 3); CONF("tabs:render_text", int, 1); + CONF("tabs:text_center", int, 0); CONF("tabs:text_font", str, "Sans"); CONF("tabs:text_height", int, 8); CONF("tabs:text_padding", int, 3); From 2f28dc810c0e1f42763a1f14fb011c4fce6db8be Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Mon, 1 Jan 2024 20:57:46 -0800 Subject: [PATCH 02/27] Rewrite installation instructions Add hyprpm, deprecate AUR, prioritize stable releases for Nix. --- README.md | 70 +++++++++++++++++++++++++++++----------- compile_commands_bear.sh | 2 +- hyprload.toml | 2 +- hyprpm.toml | 13 ++++++++ src/main.cpp | 2 +- 5 files changed, 67 insertions(+), 22 deletions(-) create mode 100644 hyprpm.toml diff --git a/README.md b/README.md index 24f04f0..54aed39 100644 --- a/README.md +++ b/README.md @@ -65,12 +65,13 @@ Assuming you use hyprland's home manager module, you can easily integrate hy3 by inputs.nixpkgs.follows = "nixpkgs"; }; - hyprland.url = "github:hyprwm/Hyprland"; - # or "github:hyprwm/Hyprland?ref=v{version}" for a release version of hyprland + hyprland.url = "github:hyprwm/Hyprland?ref=v{version}"; # where {version} is the hyprland release version + # or "github:hyprwm/Hyprland" to follow the development branch hy3 = { - url = "github:outfoxxed/hy3"; - # or "github:outfoxxed/hy3?ref=hl{version}" for a release version of hyprland + url = "github:outfoxxed/hy3?ref=hl{version}"; # where {version} is the hyprland release version + # or "github:outfoxxed/hy3" to follow the development branch. + # (you may encounter issues if you dont do the same for hyprland) inputs.hyprland.follows = "hyprland"; }; }; @@ -108,11 +109,55 @@ wayland.windowManager.hyprland = { }; ``` +### hyprpm +Hyprland now has a dedicated plugin manager, which should be used when your package manager +isn't capable of locking hy3 builds to the correct hyprland version. + +To install hy3 via hyprpm run + +```sh +hyprpm add https://github.com/outfoxxed/hy3 +``` + +To update hy3 (and all other plugins), run + +```sh +hyprpm update +``` + +(See [the wiki](https://wiki.hyprland.org/Plugins/Using-Plugins/) for details.) + +> [!WARNING] +> When you are running a tagged hyprland version hyprpm will build against hy3's +> corrosponding release. However if you are running an untagged build (aka `-git`) hyprpm +> will build against hy3's *latest* commit. This means **if you are running an out of date +> untagged build of hyprland, hyprpm may pick an incompatible revision of hy3**. +> +> To fix this problem you will either need to update hyprland or manually build the correct +> version of hy3. + +### Manual +Install hyprland, including its headers and pkg-config file, then run the following commands: + +```sh +cmake -DCMAKE_BUILD_TYPE=Release -B build +cmake --build build +``` + +The plugin will be located at `build/libhy3.so`, and you can load it normally +(See [the hyprland wiki](https://wiki.hyprland.org/Plugins/Using-Plugins/#installing--using-plugins) for details.) + +Note that the hyprland headers and pkg-config file **MUST be installed correctly, for the target version of hyprland**. + ### Arch (AUR) -> [!IMPORTANT] +> [!NOTE] +> This method of installation is deprecated and you should use *hyprpm* instead, +> as it is simpler and less error prone. + +> [!CAUTION] > Pacman is not very reliable when it comes to building packages in the correct order. -> If hy3 fails to load or build, crashes randomly or behaves oddly (commonly dispatchers stop working) +> If you get a notification saying *hy3 was compiled for a different version of hyprland* > then your packages likely updated in the wrong order, or you have hyprland headers in `/usr/local`. > > To fix this, remove `/usr/include/hyprland`, `/usr/local/include/hyprland`, `/usr/share/pkgconfig/hyprland.pc` and `/usr/local/share/pkgconfig/hyprland.pc`, @@ -131,19 +176,6 @@ You can enable it in your hyprland configuration by adding the following line an plugin = /usr/lib/libhy3.so ``` -### Manual -Install hyprland, including its headers and pkg-config file, then run the following commands: - -```sh -cmake -DCMAKE_BUILD_TYPE=Debug -B build -cmake --build build -``` - -The plugin will be located at `build/libhy3.so`, and you can load it normally -(See [the hyprland wiki](https://wiki.hyprland.org/Plugins/Using-Plugins/#installing--using-plugins) for details.) - -Note that the hyprland headers and pkg-config file **MUST be installed correctly, for the target version of hyprland**. - ## Configuration > [!IMPORTANT] diff --git a/compile_commands_bear.sh b/compile_commands_bear.sh index 83b4946..2466693 100755 --- a/compile_commands_bear.sh +++ b/compile_commands_bear.sh @@ -1,4 +1,4 @@ rm -rf build -bear -- cmake --build build cmake -DCMAKE_BUILD_TYPE=Debug -DHY3_NO_VERSION_CHECK=TRUE -B build +bear -- cmake --build build -j16 sed -i 's/-std=gnu++23/-std=gnu++2b/g' compile_commands.json diff --git a/hyprload.toml b/hyprload.toml index 0d3855c..3ae0569 100644 --- a/hyprload.toml +++ b/hyprload.toml @@ -7,6 +7,6 @@ author = "outfoxxed" output = "build/libhy3.so" steps = [ "rm -rf build", - "cmake -DCMAKE_BUILD_TYPE=Debug -B build", + "cmake -DCMAKE_BUILD_TYPE=Release -B build", "cmake --build build" ] diff --git a/hyprpm.toml b/hyprpm.toml new file mode 100644 index 0000000..5ae6b84 --- /dev/null +++ b/hyprpm.toml @@ -0,0 +1,13 @@ +[repository] +name = "hy3" +authors = ["outfoxxed"] +commit_pins = [] + +[hy3] +description = "i3 like tiling for hyprland" +authors = ["outfoxxed"] +output = "build/libhy3.so" +build = [ + "cmake -DCMAKE_BUILD_TYPE=Release -B build", + "cmake --build build" +] diff --git a/src/main.cpp b/src/main.cpp index aebe592..249e14c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,7 +18,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { if (GIT_COMMIT_HASH != std::string(__hyprland_api_get_hash())) { HyprlandAPI::addNotification( PHANDLE, - "[hy3] Hy3 was compiled for a different version of hyprland; refusing to start.", + "[hy3] hy3 was compiled for a different version of hyprland; refusing to load.", CColor {1.0, 0.2, 0.2, 1.0}, 10000 ); From c0a24c9dc1d0a6c4dc71f4755b7ab4740594f411 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Mon, 1 Jan 2024 21:02:10 -0800 Subject: [PATCH 03/27] Update flake lock and hyprpm.toml for 0.34.0 --- README.md | 2 +- flake.lock | 18 +++++++++--------- hyprload.toml | 12 ------------ hyprpm.toml | 4 +++- 4 files changed, 13 insertions(+), 23 deletions(-) delete mode 100644 hyprload.toml diff --git a/README.md b/README.md index 54aed39..4d9566f 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ hyprpm update (See [the wiki](https://wiki.hyprland.org/Plugins/Using-Plugins/) for details.) > [!WARNING] -> When you are running a tagged hyprland version hyprpm will build against hy3's +> When you are running a tagged hyprland version hyprpm (0.34.0+) will build against hy3's > corrosponding release. However if you are running an untagged build (aka `-git`) hyprpm > will build against hy3's *latest* commit. This means **if you are running an out of date > untagged build of hyprland, hyprpm may pick an incompatible revision of hy3**. diff --git a/flake.lock b/flake.lock index d7a752d..216444c 100644 --- a/flake.lock +++ b/flake.lock @@ -9,11 +9,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1702236723, - "narHash": "sha256-zIEnimM1vhsFkz+Kubb8kJ6YgHuLe56pALOSJc6CMVY=", + "lastModified": 1704110595, + "narHash": "sha256-WSrjBI3k2dM/kGF20At0E6NlrJSB4+pE+WGJ6dFzWEs=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "167f2ed3b2bb18ceeabb831ac80b655ef8e16867", + "rev": "03ebbe18ed8517ee22591eac82cd54322f42cb7d", "type": "github" }, "original": { @@ -49,11 +49,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1700612854, - "narHash": "sha256-yrQ8osMD+vDLGFX7pcwsY/Qr5PUd6OmDMYJZzZi0+zc=", + "lastModified": 1703438236, + "narHash": "sha256-aqVBq1u09yFhL7bj1/xyUeJjzr92fXVvQSSEx6AdB1M=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "19cbff58383a4ae384dea4d1d0c823d72b49d614", + "rev": "5f64a12a728902226210bf01d25ec6cbb9d9265b", "type": "github" }, "original": { @@ -118,11 +118,11 @@ ] }, "locked": { - "lastModified": 1700508250, - "narHash": "sha256-X4o/mifI7Nhu0UKYlxx53wIC+gYDo3pVM9L2u3PE2bE=", + "lastModified": 1703514399, + "narHash": "sha256-VRr5Xc4S/VPr/gU3fiOD3vSIL2+GJ+LUrmFTWTwnTz4=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "eb120ff25265ecacd0fc13d7dab12131b60d0f47", + "rev": "0a318a7a217a6402b0b705837cd5b50b0e94b31b", "type": "github" }, "original": { diff --git a/hyprload.toml b/hyprload.toml deleted file mode 100644 index 3ae0569..0000000 --- a/hyprload.toml +++ /dev/null @@ -1,12 +0,0 @@ -[hy3] -description = "i3 like tiling for hyprland" -version = "0.1" -author = "outfoxxed" - -[hy3.build] -output = "build/libhy3.so" -steps = [ - "rm -rf build", - "cmake -DCMAKE_BUILD_TYPE=Release -B build", - "cmake --build build" -] diff --git a/hyprpm.toml b/hyprpm.toml index 5ae6b84..c8fd12b 100644 --- a/hyprpm.toml +++ b/hyprpm.toml @@ -1,7 +1,9 @@ [repository] name = "hy3" authors = ["outfoxxed"] -commit_pins = [] +commit_pins = [ + ["03ebbe18ed8517ee22591eac82cd54322f42cb7d", "2f28dc810c0e1f42763a1f14fb011c4fce6db8be"] +] [hy3] description = "i3 like tiling for hyprland" From 9a1111efbab842a26477b651ae02deaa39fe1ef4 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Mon, 1 Jan 2024 21:31:07 -0800 Subject: [PATCH 04/27] Add note in readme to make sure hyprpm is running --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 4d9566f..701c816 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,15 @@ wayland.windowManager.hyprland = { Hyprland now has a dedicated plugin manager, which should be used when your package manager isn't capable of locking hy3 builds to the correct hyprland version. +> [!IMPORTANT] +> Make sure hyprpm is activated by putting +> +> ```conf +> exec-once = hyprpm reload -n +> ``` +> +> in your hyprland.conf. (See [the wiki](https://wiki.hyprland.org/Plugins/Using-Plugins/) for details.) + To install hy3 via hyprpm run ```sh From 66ef53253776b08a78a9309cdb6e5421b9ad4106 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Fri, 12 Jan 2024 03:13:32 -0800 Subject: [PATCH 05/27] Update clang_tools in nix flake to clang 17 Fixes some of the issues with clangd but does not fix the missing --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 3be3c6c..a250f37 100644 --- a/flake.nix +++ b/flake.nix @@ -45,7 +45,7 @@ name = "hy3"; nativeBuildInputs = with pkgs; [ - clang-tools_16 + clang-tools_17 bear ]; From 06ecd58399f8e3dcb20a7dd256c97b2b6e77c107 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Fri, 12 Jan 2024 03:14:31 -0800 Subject: [PATCH 06/27] Move newly tiled windows into place in the window's workspace Usually the window workspace differs from the monitor workspace when moving a window to a background workspace. Previously onWindowCreatedTiling acted on the monitor active workspace which caused windows to always appear at the end of the outermost node on the target workspace. Now they appear relative to the last selected node. --- src/Hy3Layout.cpp | 25 +++++++++++++------------ src/TabGroup.cpp | 3 +-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index 6ad2d07..d29d801 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -73,11 +73,14 @@ void Hy3Layout::onWindowCreated(CWindow* window, eDirection direction) { void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) { hy3_log( - TRACE, - "onWindowCreatedTiling called with window {:x} (floating: {})", + LOG, + "onWindowCreatedTiling called with window {:x} (floating: {}, monitor: {}, workspace: {})", (uintptr_t) window, - window->m_bIsFloating + window->m_bIsFloating, + window->m_iMonitorID, + window->m_iWorkspaceID ); + if (window->m_bIsFloating) return; auto* existing = this->getNodeFromWindow(window); @@ -96,17 +99,15 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) { Hy3Node* opening_into; Hy3Node* opening_after = nullptr; - if (monitor->activeWorkspace != -1) { - auto* root = this->getWorkspaceRootGroup(monitor->activeWorkspace); + auto* root = this->getWorkspaceRootGroup(window->m_iWorkspaceID); - if (root != nullptr) { - opening_after = root->getFocusedNode(); + if (root != nullptr) { + opening_after = root->getFocusedNode(); - // opening_after->parent cannot be nullptr - if (opening_after == root) { - opening_after = - opening_after->intoGroup(Hy3GroupLayout::SplitH, GroupEphemeralityOption::Standard); - } + // opening_after->parent cannot be nullptr + if (opening_after == root) { + opening_after = + opening_after->intoGroup(Hy3GroupLayout::SplitH, GroupEphemeralityOption::Standard); } } diff --git a/src/TabGroup.cpp b/src/TabGroup.cpp index 7888984..af2d989 100644 --- a/src/TabGroup.cpp +++ b/src/TabGroup.cpp @@ -225,8 +225,7 @@ void Hy3TabBarEntry::prepareTexture(float scale, CBox& box) { PangoLayout* layout = pango_cairo_create_layout(cairo); pango_layout_set_text(layout, this->window_title.c_str(), -1); - if (*text_center) - pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); + if (*text_center) pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); PangoFontDescription* font_desc = pango_font_description_from_string(text_font->c_str()); pango_font_description_set_size(font_desc, *text_height * scale * PANGO_SCALE); From 783c7ae0cf1fc263446f7114f068df03466310e4 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Sun, 14 Jan 2024 02:31:06 -0800 Subject: [PATCH 07/27] Add hy3:movetoworkspace, which moves a node to a workspace --- README.md | 2 + src/Hy3Layout.cpp | 176 +++++++++++++++++++++++++++++++++++++------- src/Hy3Layout.hpp | 2 + src/Hy3Node.cpp | 1 + src/Hy3Node.hpp | 1 + src/dispatchers.cpp | 15 ++++ 6 files changed, 172 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 701c816..bd96816 100644 --- a/README.md +++ b/README.md @@ -317,6 +317,8 @@ plugin { - `hy3:movewindow, , [once], [visible]` - move a window left, up, down, or right - `once` - only move directly to the neighboring group, without moving into any of its subgroups - `visible` - only move between visible nodes, not hidden tabs + - `hy3:movetoworkspace, , [follow]` - move the active node to the given workspace + - `follow` - change focus to the given workspace when moving the selected node - `hy3:killactive` - close all windows in the focused node - `hy3:changefocus, ` - `top` - focus all nodes in the workspace diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index d29d801..bca5224 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -94,12 +94,47 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) { return; } - auto* monitor = g_pCompositor->getMonitorFromID(window->m_iMonitorID); + this->nodes.push_back({ + .parent = nullptr, + .data = window, + .workspace_id = window->m_iWorkspaceID, + .layout = this, + }); + + this->insertNode(this->nodes.back()); +} + +void Hy3Layout::insertNode(Hy3Node& node) { + if (node.parent != nullptr) { + hy3_log( + ERR, + "insertNode called for node {:x} which already has a parent ({:x})", + (uintptr_t) &node, + (uintptr_t) node.parent + ); + return; + } + + auto* workspace = g_pCompositor->getWorkspaceByID(node.workspace_id); + + if (workspace == nullptr) { + hy3_log( + ERR, + "insertNode called for node {:x} with invalid workspace id {}", + (uintptr_t) &node, + node.workspace_id + ); + return; + } + + node.reparenting = true; + + auto* monitor = g_pCompositor->getMonitorFromID(workspace->m_iMonitorID); Hy3Node* opening_into; Hy3Node* opening_after = nullptr; - auto* root = this->getWorkspaceRootGroup(window->m_iWorkspaceID); + auto* root = this->getWorkspaceRootGroup(node.workspace_id); if (root != nullptr) { opening_after = root->getFocusedNode(); @@ -112,27 +147,36 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) { } if (opening_after == nullptr) { - if (g_pCompositor->m_pLastWindow != nullptr && !g_pCompositor->m_pLastWindow->m_bIsFloating - && g_pCompositor->m_pLastWindow != window - && g_pCompositor->m_pLastWindow->m_iWorkspaceID == window->m_iWorkspaceID + if (g_pCompositor->m_pLastWindow != nullptr + && g_pCompositor->m_pLastWindow->m_iWorkspaceID == node.workspace_id + && !g_pCompositor->m_pLastWindow->m_bIsFloating + && (node.data.type == Hy3NodeType::Window + || g_pCompositor->m_pLastWindow != node.data.as_window) && g_pCompositor->m_pLastWindow->m_bIsMapped) { opening_after = this->getNodeFromWindow(g_pCompositor->m_pLastWindow); } else { - opening_after = this->getNodeFromWindow( - g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal()) - ); + auto* mouse_window = + g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal()); + + if (mouse_window != nullptr && mouse_window->m_iWorkspaceID == node.workspace_id) { + opening_after = this->getNodeFromWindow(mouse_window); + } } } - if (opening_after != nullptr && opening_after->workspace_id != window->m_iWorkspaceID) { + if (opening_after != nullptr + && ((node.data.type == Hy3NodeType::Group + && (opening_after == &node || node.data.as_group.hasChild(opening_after))) + || opening_after->reparenting)) + { opening_after = nullptr; } if (opening_after != nullptr) { opening_into = opening_after->parent; } else { - if ((opening_into = this->getWorkspaceRootGroup(window->m_iWorkspaceID)) == nullptr) { + if ((opening_into = this->getWorkspaceRootGroup(node.workspace_id)) == nullptr) { static const auto* tab_first_window = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tab_first_window")->intValue; @@ -140,7 +184,7 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) { .data = Hy3GroupLayout::SplitH, .position = monitor->vecPosition + monitor->vecReservedTopLeft, .size = monitor->vecSize - monitor->vecReservedTopLeft - monitor->vecReservedBottomRight, - .workspace_id = window->m_iWorkspaceID, + .workspace_id = node.workspace_id, .layout = this, }); @@ -152,7 +196,7 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) { .data = Hy3GroupLayout::Tabbed, .position = parent.position, .size = parent.size, - .workspace_id = window->m_iWorkspaceID, + .workspace_id = node.workspace_id, .layout = this, }); @@ -169,14 +213,14 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) { return; } - if (opening_into->workspace_id != window->m_iWorkspaceID) { + if (opening_into->workspace_id != node.workspace_id) { hy3_log( WARN, "opening_into node ({:x}) is on workspace {} which does not match the new window " "(workspace {})", (uintptr_t) opening_into, opening_into->workspace_id, - window->m_iWorkspaceID + node.workspace_id ); } @@ -211,14 +255,8 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) { } } - this->nodes.push_back({ - .parent = opening_into, - .data = window, - .workspace_id = window->m_iWorkspaceID, - .layout = this, - }); - - auto& node = this->nodes.back(); + node.parent = opening_into; + node.reparenting = false; if (opening_after == nullptr) { opening_into->data.as_group.children.push_back(&node); @@ -231,8 +269,7 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) { hy3_log( LOG, - "tiled window ({:x} as node {:x}) after node {:x} in node {:x}", - (uintptr_t) window, + "tiled node {:x} inserted after node {:x} in node {:x}", (uintptr_t) &node, (uintptr_t) opening_after, (uintptr_t) opening_into @@ -970,6 +1007,95 @@ void Hy3Layout::shiftFocus(int workspace, ShiftDirection direction, bool visible } } +void changeNodeWorkspaceRecursive(Hy3Node& node, CWorkspace* workspace) { + node.workspace_id = workspace->m_iID; + + if (node.data.type == Hy3NodeType::Window) { + auto* window = node.data.as_window; + window->moveToWorkspace(workspace->m_iID); + window->updateToplevel(); + window->updateDynamicRules(); + } else { + for (auto* child: node.data.as_group.children) { + changeNodeWorkspaceRecursive(*child, workspace); + } + } +} + +void Hy3Layout::moveNodeToWorkspace(int origin, std::string wsname, bool follow) { + std::string target_name; + auto target = getWorkspaceIDFromString(wsname, target_name); + + if (target == WORKSPACE_INVALID) { + hy3_log(ERR, "moveNodeToWorkspace called with invalid workspace {}", wsname); + return; + } + + if (origin == target) return; + + auto* node = this->getWorkspaceFocusedNode(origin); + auto* focused_window = g_pCompositor->m_pLastWindow; + auto* focused_window_node = this->getNodeFromWindow(focused_window); + + auto* workspace = g_pCompositor->getWorkspaceByID(target); + + auto wsid = node != nullptr ? node->workspace_id + : focused_window != nullptr ? focused_window->m_iWorkspaceID + : WORKSPACE_INVALID; + + if (wsid == WORKSPACE_INVALID) return; + + auto* origin_ws = g_pCompositor->getWorkspaceByID(wsid); + + if (workspace == nullptr) { + hy3_log(LOG, "creating target workspace {} for node move", target); + + workspace = g_pCompositor->createNewWorkspace(target, origin_ws->m_iMonitorID, target_name); + } + + // floating or fullscreen + if (focused_window != nullptr + && (focused_window_node == nullptr || focused_window->m_bIsFullscreen)) + { + hy3_log(LOG, "{:x}, {:x}", (uintptr_t) focused_window, (uintptr_t) workspace); + g_pCompositor->moveWindowToWorkspaceSafe(focused_window, workspace); + } else { + if (node == nullptr) return; + + hy3_log( + LOG, + "moving node {:x} from workspace {} to workspace {} (follow: {})", + (uintptr_t) node, + origin, + target, + follow + ); + + Hy3Node* expand_actor = nullptr; + auto* parent = node->removeFromParentRecursive(&expand_actor); + if (expand_actor != nullptr) expand_actor->recalcSizePosRecursive(); + + changeNodeWorkspaceRecursive(*node, workspace); + this->insertNode(*node); + } + + if (follow) { + auto* monitor = g_pCompositor->getMonitorFromID(workspace->m_iMonitorID); + + if (workspace->m_bIsSpecialWorkspace) { + monitor->setSpecialWorkspace(workspace); + } else if (origin_ws->m_bIsSpecialWorkspace) { + g_pCompositor->getMonitorFromID(origin_ws->m_iMonitorID)->setSpecialWorkspace(nullptr); + } + + monitor->changeWorkspace(workspace); + + static auto* const allow_workspace_cycles = + &g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles")->intValue; + if (*allow_workspace_cycles) workspace->rememberPrevWorkspace(origin_ws); + } +} + void Hy3Layout::changeFocus(int workspace, FocusShift shift) { auto* node = this->getWorkspaceFocusedNode(workspace); if (node == nullptr) return; @@ -1311,7 +1437,7 @@ bool Hy3Layout::shouldRenderSelected(CWindow* window) { Hy3Node* Hy3Layout::getWorkspaceRootGroup(const int& workspace) { for (auto& node: this->nodes) { if (node.workspace_id == workspace && node.parent == nullptr - && node.data.type == Hy3NodeType::Group) + && node.data.type == Hy3NodeType::Group && !node.reparenting) { return &node; } diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp index a165dce..9409be8 100644 --- a/src/Hy3Layout.hpp +++ b/src/Hy3Layout.hpp @@ -91,6 +91,7 @@ public: virtual void onEnable(); virtual void onDisable(); + void insertNode(Hy3Node& node); void makeGroupOnWorkspace(int workspace, Hy3GroupLayout, GroupEphemeralityOption); void makeOppositeGroupOnWorkspace(int workspace, GroupEphemeralityOption); void changeGroupOnWorkspace(int workspace, Hy3GroupLayout); @@ -108,6 +109,7 @@ public: void shiftNode(Hy3Node&, ShiftDirection, bool once, bool visible); void shiftWindow(int workspace, ShiftDirection, bool once, bool visible); void shiftFocus(int workspace, ShiftDirection, bool visible); + void moveNodeToWorkspace(int origin, std::string wsname, bool follow); void changeFocus(int workspace, FocusShift); void focusTab(int workspace, TabFocus target, TabFocusMousePriority, bool wrap_scroll, int index); void setNodeSwallow(int workspace, SetSwallowOption); diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp index 99c2b47..35fd752 100644 --- a/src/Hy3Node.cpp +++ b/src/Hy3Node.cpp @@ -759,6 +759,7 @@ Hy3Node* Hy3Node::removeFromParentRecursive(Hy3Node** expand_actor) { } } + this->parent = nullptr; return parent; } diff --git a/src/Hy3Node.hpp b/src/Hy3Node.hpp index 4b17d82..bd25556 100644 --- a/src/Hy3Node.hpp +++ b/src/Hy3Node.hpp @@ -79,6 +79,7 @@ public: struct Hy3Node { Hy3Node* parent = nullptr; + bool reparenting = false; Hy3NodeData data; Vector2D position; Vector2D size; diff --git a/src/dispatchers.cpp b/src/dispatchers.cpp index f4d663c..3d721bc 100644 --- a/src/dispatchers.cpp +++ b/src/dispatchers.cpp @@ -119,6 +119,20 @@ void dispatch_movefocus(std::string value) { } } +void dispatch_move_to_workspace(std::string value) { + int origin_workspace = workspace_for_action(); + if (origin_workspace == -1) return; + + auto args = CVarList(value); + + auto workspace = args[0]; + if (workspace == "") return; + + bool follow = args[1] == "follow"; + + g_Hy3Layout->moveNodeToWorkspace(origin_workspace, workspace, follow); +} + void dispatch_changefocus(std::string arg) { int workspace = workspace_for_action(); if (workspace == -1) return; @@ -237,6 +251,7 @@ void registerDispatchers() { HyprlandAPI::addDispatcher(PHANDLE, "hy3:setephemeral", dispatch_setephemeral); HyprlandAPI::addDispatcher(PHANDLE, "hy3:movefocus", dispatch_movefocus); HyprlandAPI::addDispatcher(PHANDLE, "hy3:movewindow", dispatch_movewindow); + HyprlandAPI::addDispatcher(PHANDLE, "hy3:movetoworkspace", dispatch_move_to_workspace); HyprlandAPI::addDispatcher(PHANDLE, "hy3:changefocus", dispatch_changefocus); HyprlandAPI::addDispatcher(PHANDLE, "hy3:focustab", dispatch_focustab); HyprlandAPI::addDispatcher(PHANDLE, "hy3:setswallow", dispatch_setswallow); From 7c643fa66e783a5ad47386b06be2b165f8bf6003 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Sun, 14 Jan 2024 02:43:37 -0800 Subject: [PATCH 08/27] Fix killactive and movetoworkspace not working in fullscreen --- src/dispatchers.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dispatchers.cpp b/src/dispatchers.cpp index 3d721bc..667b1cf 100644 --- a/src/dispatchers.cpp +++ b/src/dispatchers.cpp @@ -6,7 +6,7 @@ #include "dispatchers.hpp" #include "globals.hpp" -int workspace_for_action() { +int workspace_for_action(bool allow_fullscreen = false) { if (g_pLayoutManager->getCurrentLayout() != g_Hy3Layout.get()) return -1; int workspace_id = g_pCompositor->m_pLastMonitor->activeWorkspace; @@ -14,7 +14,7 @@ int workspace_for_action() { if (workspace_id == -1) return -1; auto* workspace = g_pCompositor->getWorkspaceByID(workspace_id); if (workspace == nullptr) return -1; - if (workspace->m_bHasFullscreenWindow) return -1; + if (!allow_fullscreen && workspace->m_bHasFullscreenWindow) return -1; return workspace_id; } @@ -120,7 +120,7 @@ void dispatch_movefocus(std::string value) { } void dispatch_move_to_workspace(std::string value) { - int origin_workspace = workspace_for_action(); + int origin_workspace = workspace_for_action(true); if (origin_workspace == -1) return; auto args = CVarList(value); @@ -202,7 +202,7 @@ void dispatch_setswallow(std::string arg) { } void dispatch_killactive(std::string value) { - int workspace = workspace_for_action(); + int workspace = workspace_for_action(true); if (workspace == -1) return; g_Hy3Layout->killFocusedNode(workspace); From d247317a38b0ab9cb82504ee62516082e63a862a Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Sun, 14 Jan 2024 02:50:56 -0800 Subject: [PATCH 09/27] Add changelog --- CHANGELOG.md | 11 +++++++++++ README.md | 2 ++ 2 files changed, 13 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c6b4c99 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog + +## Upcoming + +- Fixed `hy3:killactive` and `hy3:movetoworkspace` not working in fullscreen. +- `hy3:movetoworkspace` added to move a whole node to a workspace. +- Newly tiled windows (usually from moving a window to a new workspace) are now +placed relative to the last selected node. + +## hl0.34.0 and before +*check commit history* diff --git a/README.md b/README.md index bd96816..047dfe2 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ i3 / sway like layout for [hyprland](https://github.com/hyprwm/hyprland). [Installation](#installation), [Configuration](#configuration) +*Check the [changelog](./CHANGELOG.md) for a list of new features and improvements* + ### Features - [x] i3 like tiling - [x] Node based window manipulation (you can interact with multiple windows at once) From f150886e63151bb72320cb31b6848bb102cf7757 Mon Sep 17 00:00:00 2001 From: Pete Appleton Date: Sat, 20 Jan 2024 11:51:43 +0000 Subject: [PATCH 10/27] Avoid GCC build warnings - Add `default` to switch statements to ensure that a defined value is returned from non-void functions - Add `HY3_ENABLE_UNUSED_BLOCKS` option (default: `FALSE`) which controls a `#if` pre-processor directive surrounding the apparently unused `unfullscreen` label (and associated block) in `Hy3Layout.cpp` --- CMakeLists.txt | 1 + src/Hy3Layout.cpp | 9 +++++++-- src/Hy3Node.cpp | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e4e83ac..0074e30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ add_library(hy3 SHARED ) option(HY3_NO_VERSION_CHECK "Disable hyprland version check" FALSE) +option(HY3_ENABLE_UNUSED_BLOCKS "Enable the compilation of unused blocks" FALSE) if (HY3_NO_VERSION_CHECK) target_compile_definitions(hy3 PRIVATE -DHY3_NO_VERSION_CHECK=TRUE) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index bca5224..f4c793f 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -752,6 +752,7 @@ CWindow* Hy3Layout::getNextWindowCandidate(CWindow* window) { switch (node->data.type) { case Hy3NodeType::Window: return node->data.as_window; case Hy3NodeType::Group: return nullptr; + default: return nullptr; } } @@ -1072,7 +1073,7 @@ void Hy3Layout::moveNodeToWorkspace(int origin, std::string wsname, bool follow) ); Hy3Node* expand_actor = nullptr; - auto* parent = node->removeFromParentRecursive(&expand_actor); + node->removeFromParentRecursive(&expand_actor); if (expand_actor != nullptr) expand_actor->recalcSizePosRecursive(); changeNodeWorkspaceRecursive(*node, workspace); @@ -1402,12 +1403,14 @@ fullscreen: window->m_vRealPosition = monitor->vecPosition; window->m_vRealSize = monitor->vecSize; goto fsupdate; +#ifdef HY3_ENABLE_UNUSED_BLOCKS unfullscreen: if (node->data.type != Hy3NodeType::Window) return; window = node->data.as_window; window->m_bIsFullscreen = false; workspace->m_bHasFullscreenWindow = false; goto fsupdate; +#endif fsupdate: g_pCompositor->updateWindowAnimatedDecorationValues(window); g_pXWaylandManager->setWindowSize(window, window->m_vRealSize.goalv()); @@ -1427,11 +1430,13 @@ bool Hy3Layout::shouldRenderSelected(CWindow* window) { switch (focused->data.type) { case Hy3NodeType::Window: return focused->data.as_window == window; - case Hy3NodeType::Group: + case Hy3NodeType::Group: { auto* node = this->getNodeFromWindow(window); if (node == nullptr) return false; return focused->data.as_group.hasChild(node); } + default: return false; + } } Hy3Node* Hy3Layout::getWorkspaceRootGroup(const int& workspace) { diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp index 35fd752..84565ee 100644 --- a/src/Hy3Node.cpp +++ b/src/Hy3Node.cpp @@ -174,6 +174,7 @@ CWindow* Hy3Node::bringToTop() { } return nullptr; + default: return nullptr; } } @@ -237,6 +238,7 @@ Hy3Node* Hy3Node::getFocusedNode(bool ignore_group_focus, bool stop_at_expanded) stop_at_expanded ); } + default: return nullptr; } } @@ -584,6 +586,7 @@ bool Hy3Node::isUrgent() { } return false; + default: return false; } } From 5ca59bf723293d81add69c5f2169f23f385e5a22 Mon Sep 17 00:00:00 2001 From: Pete Appleton Date: Sat, 20 Jan 2024 14:09:09 +0000 Subject: [PATCH 11/27] Implement `resizeActiveWindow` fully --- .gitignore | 4 +- CHANGELOG.md | 3 + src/Hy3Layout.cpp | 266 +++++++++++++++++----------------------------- src/Hy3Layout.hpp | 7 +- src/Hy3Node.cpp | 52 +++++++++ src/Hy3Node.hpp | 2 + 6 files changed, 162 insertions(+), 172 deletions(-) diff --git a/.gitignore b/.gitignore index b159eae..36b6e89 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ build/ -compile_commands.json \ No newline at end of file +compile_commands.json +.vscode/ +*.log diff --git a/CHANGELOG.md b/CHANGELOG.md index c6b4c99..8fd0835 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +- Implement `resizeactivewindow` for floating windows +- Fully implement `resizeactivewindow` for tiled windows + ## Upcoming - Fixed `hy3:killactive` and `hy3:movetoworkspace` not working in fullscreen. diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index f4c793f..012f240 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -395,211 +395,141 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW if (!g_pCompositor->windowValidMapped(window)) return; auto* node = this->getNodeFromWindow(window); - if (node == nullptr) return; - if (node->parent != nullptr && node->parent->data.as_group.focused_child == node) - node = &node->getExpandActor(); + if(node != nullptr) { + if (node->parent != nullptr && node->parent->data.as_group.focused_child == node) + node = &node->getExpandActor(); - bool drag_x; - bool drag_y; + auto monitor = g_pCompositor->getMonitorFromID(window->m_iMonitorID); - if (corner == CORNER_NONE) { - drag_x = delta.x > 0; - drag_y = delta.y > 0; + const bool display_left = + STICKS(node->position.x, monitor->vecPosition.x + monitor->vecReservedTopLeft.x); + const bool display_right = STICKS( + node->position.x + node->size.x, + monitor->vecPosition.x + monitor->vecSize.x - monitor->vecReservedBottomRight.x + ); + const bool display_top = + STICKS(node->position.y, monitor->vecPosition.y + monitor->vecReservedTopLeft.y); + const bool display_bottom = STICKS( + node->position.y + node->size.y, + monitor->vecPosition.y + monitor->vecSize.y - monitor->vecReservedBottomRight.y + ); + + Vector2D resize_delta = delta; + if (display_left && display_right) resize_delta.x = 0; + if (display_top && display_bottom) resize_delta.y = 0; + + ShiftDirection target_edge_x; + ShiftDirection target_edge_y; + + // Determine the direction in which we're going to look for the sibling node + // that will be resized + if(corner == CORNER_NONE) { // It's probably a keyboard event + // If the horizontal delta is negative & there's space available to the left, + // or if the horizontal delta is positive but space ISN'T available to the right + // then resize against the left-hand sibling. + // Otherwise, resize against the right-hand sibling + target_edge_x = (delta.x < 0 && display_left) || (delta.x > 0 && !display_right) + ? ShiftDirection::Left : ShiftDirection::Right; + + // If the vertical delta is negative & there's space available above it, + // or if the vertical delta is positive but space ISN'T available below + // then resize against the upper sibling. + // Otherwise, resize against the lower sibling + target_edge_y = (delta.y < 0 && display_top) || (delta.y >0 && !display_bottom) + ? ShiftDirection::Up : ShiftDirection::Down; + } else { // It's probaly a mouse event + // If the event was triggered from the right-hand side then resize + // against the previous [left] sibling - otherwise, resize against + // the next [right] sibling + target_edge_x = corner == CORNER_TOPRIGHT || corner == CORNER_BOTTOMRIGHT + ? ShiftDirection::Left : ShiftDirection::Right; + + // If the event was triggered from the bottom edge then resize + // against the previous [upper] sibling - otherwise, resize against + // the next [lower] sibling + target_edge_y = corner == CORNER_BOTTOMLEFT || corner == CORNER_BOTTOMRIGHT + ? ShiftDirection::Up : ShiftDirection::Down; + } + + node = node->findSibling(node->data.as_group.layout, target_edge_x, target_edge_y); + auto* parent_node = node->parent; + + if (parent_node != nullptr) { + resizeNode(node, resize_delta, target_edge_x, target_edge_y); + + auto* outer_node = node->findSibling(parent_node->data.as_group.layout, target_edge_x, target_edge_y); + if (outer_node != nullptr && outer_node->parent != nullptr) { + resizeNode(outer_node, resize_delta, target_edge_x, target_edge_y); + } + } } else { - drag_x = corner == CORNER_TOPRIGHT || corner == CORNER_BOTTOMRIGHT; - drag_y = corner == CORNER_BOTTOMLEFT || corner == CORNER_BOTTOMRIGHT; + // No parent node - is this a floating window? If so, use the same logic as the `main` layout + if(window->m_bIsFloating) { + const auto required_size = Vector2D( + std::max((window->m_vRealSize.goalv() + delta).x, 20.0), + std::max((window->m_vRealSize.goalv() + delta).y, 20.0) + ); + window->m_vRealSize = required_size; + } } +} +void Hy3Layout::resizeNode( + Hy3Node* node, + Vector2D resize_delta, + ShiftDirection target_edge_x, + ShiftDirection target_edge_y +) { + auto& parent_node = node->parent; + auto& containing_group = parent_node->data.as_group; const auto animate = - &g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue; + &g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue; - auto monitor = g_pCompositor->getMonitorFromID(window->m_iMonitorID); - - const bool display_left = - STICKS(node->position.x, monitor->vecPosition.x + monitor->vecReservedTopLeft.x); - const bool display_right = STICKS( - node->position.x + node->size.x, - monitor->vecPosition.x + monitor->vecSize.x - monitor->vecReservedBottomRight.x - ); - const bool display_top = - STICKS(node->position.y, monitor->vecPosition.y + monitor->vecReservedTopLeft.y); - const bool display_bottom = STICKS( - node->position.y + node->size.y, - monitor->vecPosition.y + monitor->vecSize.y - monitor->vecReservedBottomRight.y - ); - - Vector2D allowed_movement = delta; - if (display_left && display_right) allowed_movement.x = 0; - if (display_top && display_bottom) allowed_movement.y = 0; - - auto* inner_node = node; - - // break into parent groups when encountering a corner we're dragging in or a - // tab group - while (inner_node->parent != nullptr) { - auto& group = inner_node->parent->data.as_group; - - switch (group.layout) { - case Hy3GroupLayout::Tabbed: - // treat tabbed layouts as if they dont exist during resizing - goto cont; - case Hy3GroupLayout::SplitH: - if ((drag_x && group.children.back() == inner_node) - || (!drag_x && group.children.front() == inner_node)) - { - goto cont; - } - break; - case Hy3GroupLayout::SplitV: - if ((drag_y && group.children.back() == inner_node) - || (!drag_y && group.children.front() == inner_node)) - { - goto cont; - } - break; - } - - break; - cont: - inner_node = inner_node->parent; - } - - auto* inner_parent = inner_node->parent; - if (inner_parent == nullptr) return; - - auto* outer_node = inner_node; - - // break into parent groups when encountering a corner we're dragging in, a - // tab group, or a layout matching the inner_parent. - while (outer_node->parent != nullptr) { - auto& group = outer_node->parent->data.as_group; - - // break out of all layouts that match the orientation of the inner_parent - if (group.layout == inner_parent->data.as_group.layout) goto cont2; - - switch (group.layout) { - case Hy3GroupLayout::Tabbed: - // treat tabbed layouts as if they dont exist during resizing - goto cont2; - case Hy3GroupLayout::SplitH: - if ((drag_x && group.children.back() == outer_node) - || (!drag_x && group.children.front() == outer_node)) - { - goto cont2; - } - break; - case Hy3GroupLayout::SplitV: - if ((drag_y && group.children.back() == outer_node) - || (!drag_y && group.children.front() == outer_node)) - { - goto cont2; - } - break; - } - - break; - cont2: - outer_node = outer_node->parent; - } - - auto& inner_group = inner_parent->data.as_group; - // adjust the inner node - switch (inner_group.layout) { + switch (containing_group.layout) { case Hy3GroupLayout::SplitH: { auto ratio_mod = - allowed_movement.x * (float) inner_group.children.size() / inner_parent->size.x; + resize_delta.x * (float) containing_group.children.size() / parent_node->size.x; - auto iter = std::find(inner_group.children.begin(), inner_group.children.end(), inner_node); + auto iter = std::find(containing_group.children.begin(), containing_group.children.end(), node); - if (drag_x) { - if (inner_node == inner_group.children.back()) break; + if (target_edge_x == ShiftDirection::Left) { + if (node == containing_group.children.back()) break; iter = std::next(iter); } else { - if (inner_node == inner_group.children.front()) break; + if (node == containing_group.children.front()) break; iter = std::prev(iter); ratio_mod = -ratio_mod; } auto* neighbor = *iter; - inner_node->size_ratio += ratio_mod; + node->size_ratio += ratio_mod; neighbor->size_ratio -= ratio_mod; } break; case Hy3GroupLayout::SplitV: { - auto ratio_mod = allowed_movement.y * (float) inner_parent->data.as_group.children.size() - / inner_parent->size.y; + auto ratio_mod = + resize_delta.y * (float) containing_group.children.size() / parent_node->size.y; - auto iter = std::find(inner_group.children.begin(), inner_group.children.end(), inner_node); + auto iter = std::find(containing_group.children.begin(), containing_group.children.end(), node); - if (drag_y) { - if (inner_node == inner_group.children.back()) break; + if (target_edge_y == ShiftDirection::Up) { + if (node == containing_group.children.back()) break; iter = std::next(iter); } else { - if (inner_node == inner_group.children.front()) break; + if (node == containing_group.children.front()) break; iter = std::prev(iter); ratio_mod = -ratio_mod; } auto* neighbor = *iter; - inner_node->size_ratio += ratio_mod; + node->size_ratio += ratio_mod; neighbor->size_ratio -= ratio_mod; } break; case Hy3GroupLayout::Tabbed: break; } - inner_parent->recalcSizePosRecursive(*animate == 0); - - if (outer_node != nullptr && outer_node->parent != nullptr) { - auto* outer_parent = outer_node->parent; - auto& outer_group = outer_parent->data.as_group; - // adjust the outer node - switch (outer_group.layout) { - case Hy3GroupLayout::SplitH: { - auto ratio_mod = - allowed_movement.x * (float) outer_group.children.size() / outer_parent->size.x; - - auto iter = std::find(outer_group.children.begin(), outer_group.children.end(), outer_node); - - if (drag_x) { - if (outer_node == inner_group.children.back()) break; - iter = std::next(iter); - } else { - if (outer_node == inner_group.children.front()) break; - iter = std::prev(iter); - ratio_mod = -ratio_mod; - } - - auto* neighbor = *iter; - - outer_node->size_ratio += ratio_mod; - neighbor->size_ratio -= ratio_mod; - } break; - case Hy3GroupLayout::SplitV: { - auto ratio_mod = allowed_movement.y * (float) outer_parent->data.as_group.children.size() - / outer_parent->size.y; - - auto iter = std::find(outer_group.children.begin(), outer_group.children.end(), outer_node); - - if (drag_y) { - if (outer_node == outer_group.children.back()) break; - iter = std::next(iter); - } else { - if (outer_node == outer_group.children.front()) break; - iter = std::prev(iter); - ratio_mod = -ratio_mod; - } - - auto* neighbor = *iter; - - outer_node->size_ratio += ratio_mod; - neighbor->size_ratio -= ratio_mod; - } break; - case Hy3GroupLayout::Tabbed: break; - } - - outer_parent->recalcSizePosRecursive(*animate == 0); - } + parent_node->recalcSizePosRecursive(*animate == 0); } void Hy3Layout::fullscreenRequestForWindow( diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp index 9409be8..29f4e2a 100644 --- a/src/Hy3Layout.hpp +++ b/src/Hy3Layout.hpp @@ -13,9 +13,6 @@ enum class GroupEphemeralityOption { #include -#include "Hy3Node.hpp" -#include "TabGroup.hpp" - enum class ShiftDirection { Left, Up, @@ -23,6 +20,9 @@ enum class ShiftDirection { Right, }; +#include "Hy3Node.hpp" +#include "TabGroup.hpp" + enum class FocusShift { Top, Bottom, @@ -144,6 +144,7 @@ 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 84565ee..4640d37 100644 --- a/src/Hy3Node.cpp +++ b/src/Hy3Node.cpp @@ -808,6 +808,58 @@ bool Hy3Node::swallowGroups(Hy3Node* into) { return true; } +Hy3Node* getOuterChild(Hy3GroupData &group, ShiftDirection direction) { + switch (direction) { + case ShiftDirection::Left: + case ShiftDirection::Up: + return group.children.back(); + break; + case ShiftDirection::Right: + case ShiftDirection::Down: + return group.children.front(); + break; + default: + return nullptr; + } +} + +Hy3Node* Hy3Node::findSibling(Hy3GroupLayout inner_layout, ShiftDirection direction_x, ShiftDirection direction_y) { + // break into parent groups when encountering a corner we're dragging in, a + // tab group, or a layout matching the inner_parent. + + auto current_node = this; + while (current_node->parent != nullptr) { + auto& parent_group = current_node->parent->data.as_group; + + // break out of all layouts that match the orientation of the inner_parent + if (parent_group.layout == inner_layout) { + goto cont2; + } + + switch (parent_group.layout) { + case Hy3GroupLayout::Tabbed: + // treat tabbed layouts as if they dont exist during resizing + goto cont2; + case Hy3GroupLayout::SplitH: + if(getOuterChild(parent_group, direction_x) == current_node) { + goto cont2; + } + break; + case Hy3GroupLayout::SplitV: + if(getOuterChild(parent_group, direction_y) == current_node) { + goto cont2; + } + break; + } + + break; + cont2: + current_node = current_node->parent; + } + + return current_node; +} + void Hy3Node::swapData(Hy3Node& a, Hy3Node& b) { Hy3NodeData aData = std::move(a.data); a.data = std::move(b.data); diff --git a/src/Hy3Node.hpp b/src/Hy3Node.hpp index bd25556..77ed7e9 100644 --- a/src/Hy3Node.hpp +++ b/src/Hy3Node.hpp @@ -1,6 +1,7 @@ #pragma once struct Hy3Node; +struct Hy3GroupData; enum class Hy3GroupLayout; #include @@ -98,6 +99,7 @@ struct Hy3Node { void markFocused(); void raiseToTop(); Hy3Node* getFocusedNode(bool ignore_group_focus = false, bool stop_at_expanded = false); + Hy3Node* findSibling(Hy3GroupLayout inner_layout, ShiftDirection direction_x, ShiftDirection direction_y); bool isIndirectlyFocused(); Hy3Node& getExpandActor(); From 6185efd8476e8140fcf129a74411d7480aefbf3d Mon Sep 17 00:00:00 2001 From: Pete Appleton Date: Mon, 22 Jan 2024 07:56:14 +0000 Subject: [PATCH 12/27] Comment-out unused code instead of masking with preprocessor --- CMakeLists.txt | 1 - src/Hy3Layout.cpp | 14 ++++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0074e30..e4e83ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,6 @@ add_library(hy3 SHARED ) option(HY3_NO_VERSION_CHECK "Disable hyprland version check" FALSE) -option(HY3_ENABLE_UNUSED_BLOCKS "Enable the compilation of unused blocks" FALSE) if (HY3_NO_VERSION_CHECK) target_compile_definitions(hy3 PRIVATE -DHY3_NO_VERSION_CHECK=TRUE) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index 012f240..369aa9f 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -1333,14 +1333,12 @@ fullscreen: window->m_vRealPosition = monitor->vecPosition; window->m_vRealSize = monitor->vecSize; goto fsupdate; -#ifdef HY3_ENABLE_UNUSED_BLOCKS -unfullscreen: - if (node->data.type != Hy3NodeType::Window) return; - window = node->data.as_window; - window->m_bIsFullscreen = false; - workspace->m_bHasFullscreenWindow = false; - goto fsupdate; -#endif +// unfullscreen: +// if (node->data.type != Hy3NodeType::Window) return; +// window = node->data.as_window; +// window->m_bIsFullscreen = false; +// workspace->m_bHasFullscreenWindow = false; +// goto fsupdate; fsupdate: g_pCompositor->updateWindowAnimatedDecorationValues(window); g_pXWaylandManager->setWindowSize(window, window->m_vRealSize.goalv()); From 5820adc5c1968ab1043cb1e65b56e13a34c0002d Mon Sep 17 00:00:00 2001 From: Pete Appleton Date: Mon, 22 Jan 2024 08:09:57 +0000 Subject: [PATCH 13/27] Move changelog entries to `upcoming` section --- CHANGELOG.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fd0835..f30e22d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,13 @@ # Changelog -- Implement `resizeactivewindow` for floating windows -- Fully implement `resizeactivewindow` for tiled windows - ## Upcoming - Fixed `hy3:killactive` and `hy3:movetoworkspace` not working in fullscreen. - `hy3:movetoworkspace` added to move a whole node to a workspace. - Newly tiled windows (usually from moving a window to a new workspace) are now placed relative to the last selected node. +- Implement `resizeactivewindow` for floating windows +- Fully implement `resizeactivewindow` for tiled windows ## hl0.34.0 and before *check commit history* From f3e8d2ff9af7cb9c834abcfee598c14d18e13929 Mon Sep 17 00:00:00 2001 From: Pete Appleton Date: Sat, 27 Jan 2024 11:49:46 +0000 Subject: [PATCH 14/27] Fix resize breakage with expanded nodes --- src/Hy3Layout.cpp | 108 ++++++------------------------------- src/Hy3Layout.hpp | 6 +++ src/Hy3Node.cpp | 134 ++++++++++++++++++++++++++++++++++++---------- src/Hy3Node.hpp | 4 +- 4 files changed, 131 insertions(+), 121 deletions(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index 369aa9f..91865ca 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -395,9 +395,9 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW if (!g_pCompositor->windowValidMapped(window)) return; auto* node = this->getNodeFromWindow(window); + if(node != nullptr) { - if (node->parent != nullptr && node->parent->data.as_group.focused_child == node) - node = &node->getExpandActor(); + node = &node->getExpandActor(); auto monitor = g_pCompositor->getMonitorFromID(window->m_iMonitorID); @@ -423,44 +423,26 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW // Determine the direction in which we're going to look for the sibling node // that will be resized - if(corner == CORNER_NONE) { // It's probably a keyboard event - // If the horizontal delta is negative & there's space available to the left, - // or if the horizontal delta is positive but space ISN'T available to the right - // then resize against the left-hand sibling. - // Otherwise, resize against the right-hand sibling - target_edge_x = (delta.x < 0 && display_left) || (delta.x > 0 && !display_right) + if(corner == CORNER_NONE) { // It's probably a keyboard event. + target_edge_x = display_right ? ShiftDirection::Left : ShiftDirection::Right; + target_edge_y = display_bottom ? ShiftDirection::Up : ShiftDirection::Down; + } else { // It's probably a mouse event + // Resize against the edges corresponding to the selected corner + target_edge_x = corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT ? ShiftDirection::Left : ShiftDirection::Right; - - // If the vertical delta is negative & there's space available above it, - // or if the vertical delta is positive but space ISN'T available below - // then resize against the upper sibling. - // Otherwise, resize against the lower sibling - target_edge_y = (delta.y < 0 && display_top) || (delta.y >0 && !display_bottom) - ? ShiftDirection::Up : ShiftDirection::Down; - } else { // It's probaly a mouse event - // If the event was triggered from the right-hand side then resize - // against the previous [left] sibling - otherwise, resize against - // the next [right] sibling - target_edge_x = corner == CORNER_TOPRIGHT || corner == CORNER_BOTTOMRIGHT - ? ShiftDirection::Left : ShiftDirection::Right; - - // If the event was triggered from the bottom edge then resize - // against the previous [upper] sibling - otherwise, resize against - // the next [lower] sibling - target_edge_y = corner == CORNER_BOTTOMLEFT || corner == CORNER_BOTTOMRIGHT + target_edge_y = corner == CORNER_TOPLEFT || corner == CORNER_TOPRIGHT ? ShiftDirection::Up : ShiftDirection::Down; } - node = node->findSibling(node->data.as_group.layout, target_edge_x, target_edge_y); - auto* parent_node = node->parent; + auto sibling_node_x = node->findSibling(target_edge_x); + auto sibling_node_y = node->findSibling(target_edge_y); - if (parent_node != nullptr) { - resizeNode(node, resize_delta, target_edge_x, target_edge_y); + if(sibling_node_x) { + sibling_node_x->resize(resize_delta.x, target_edge_x); + } - auto* outer_node = node->findSibling(parent_node->data.as_group.layout, target_edge_x, target_edge_y); - if (outer_node != nullptr && outer_node->parent != nullptr) { - resizeNode(outer_node, resize_delta, target_edge_x, target_edge_y); - } + if(sibling_node_y) { + sibling_node_y->resize(resize_delta.y, target_edge_y); } } else { // No parent node - is this a floating window? If so, use the same logic as the `main` layout @@ -474,64 +456,6 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW } } -void Hy3Layout::resizeNode( - Hy3Node* node, - Vector2D resize_delta, - ShiftDirection target_edge_x, - ShiftDirection target_edge_y -) { - auto& parent_node = node->parent; - auto& containing_group = parent_node->data.as_group; - const auto animate = - &g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue; - - switch (containing_group.layout) { - case Hy3GroupLayout::SplitH: { - auto ratio_mod = - resize_delta.x * (float) containing_group.children.size() / parent_node->size.x; - - auto iter = std::find(containing_group.children.begin(), containing_group.children.end(), node); - - if (target_edge_x == ShiftDirection::Left) { - if (node == containing_group.children.back()) break; - iter = std::next(iter); - } else { - if (node == containing_group.children.front()) break; - iter = std::prev(iter); - ratio_mod = -ratio_mod; - } - - auto* neighbor = *iter; - - node->size_ratio += ratio_mod; - neighbor->size_ratio -= ratio_mod; - } break; - case Hy3GroupLayout::SplitV: { - auto ratio_mod = - resize_delta.y * (float) containing_group.children.size() / parent_node->size.y; - - auto iter = std::find(containing_group.children.begin(), containing_group.children.end(), node); - - if (target_edge_y == ShiftDirection::Up) { - if (node == containing_group.children.back()) break; - iter = std::next(iter); - } else { - if (node == containing_group.children.front()) break; - iter = std::prev(iter); - ratio_mod = -ratio_mod; - } - - auto* neighbor = *iter; - - node->size_ratio += ratio_mod; - neighbor->size_ratio -= ratio_mod; - } break; - case Hy3GroupLayout::Tabbed: break; - } - - parent_node->recalcSizePosRecursive(*animate == 0); -} - void Hy3Layout::fullscreenRequestForWindow( CWindow* window, eFullscreenMode fullscreen_mode, diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp index 29f4e2a..f912849 100644 --- a/src/Hy3Layout.hpp +++ b/src/Hy3Layout.hpp @@ -20,6 +20,12 @@ enum class ShiftDirection { Right, }; +enum class Axis { + None, + Horizontal, + Vertical +}; + #include "Hy3Node.hpp" #include "TabGroup.hpp" diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp index 4640d37..f44ae78 100644 --- a/src/Hy3Node.cpp +++ b/src/Hy3Node.cpp @@ -7,6 +7,8 @@ #include "Hy3Node.hpp" #include "globals.hpp" +const float MIN_RATIO = 0.02f; + // Hy3GroupData // Hy3GroupData::Hy3GroupData(Hy3GroupLayout layout): layout(layout) { @@ -812,52 +814,128 @@ Hy3Node* getOuterChild(Hy3GroupData &group, ShiftDirection direction) { switch (direction) { case ShiftDirection::Left: case ShiftDirection::Up: - return group.children.back(); + return group.children.front(); break; case ShiftDirection::Right: case ShiftDirection::Down: - return group.children.front(); + return group.children.back(); break; default: return nullptr; } } -Hy3Node* Hy3Node::findSibling(Hy3GroupLayout inner_layout, ShiftDirection direction_x, ShiftDirection direction_y) { - // break into parent groups when encountering a corner we're dragging in, a - // tab group, or a layout matching the inner_parent. +Hy3Node* Hy3Node::getImmediateSibling(ShiftDirection direction) { + const auto& group = this->parent->data.as_group; + auto iter = std::find(group.children.begin(), group.children.end(), this); + + std::__cxx11::list::const_iterator list_sibling; + + switch (direction) { + case ShiftDirection::Left: + case ShiftDirection::Up: + list_sibling = std::prev(iter); + break; + case ShiftDirection::Right: + case ShiftDirection::Down: + list_sibling = std::next(iter); + break; + default: + list_sibling = iter; + } + + if(list_sibling == group.children.end()) { + hy3_log(WARN, "getImmediateSibling: sibling not found"); + list_sibling = iter; + } + + return *list_sibling; +} + +Axis getAxis(Hy3GroupLayout layout) { + switch (layout) + { + case Hy3GroupLayout::SplitH: + return Axis::Horizontal; + case Hy3GroupLayout::SplitV: + return Axis::Vertical; + default: + return Axis::None; + } +} + +Axis getAxis(ShiftDirection direction) { + switch (direction) + { + case ShiftDirection::Left: + case ShiftDirection::Right: + return Axis::Horizontal; + case ShiftDirection::Down: + case ShiftDirection::Up: + return Axis::Vertical; + default: + return Axis::None; + } +} + +Hy3Node* Hy3Node::findSibling(ShiftDirection direction) { auto current_node = this; - while (current_node->parent != nullptr) { + Hy3Node* sibling = nullptr; + + while (sibling == nullptr && current_node->parent != nullptr) { auto& parent_group = current_node->parent->data.as_group; - // break out of all layouts that match the orientation of the inner_parent - if (parent_group.layout == inner_layout) { - goto cont2; + if(parent_group.layout != Hy3GroupLayout::Tabbed && getAxis(parent_group.layout) == getAxis(direction)) { + // If the current node is the outermost child of its parent group then proceed + // then we need to look at the parent - otherwise, the sibling is simply the immediate + // sibling in the child collection + if(getOuterChild(parent_group, direction) != current_node) { + sibling = current_node->getImmediateSibling(direction); + } } - switch (parent_group.layout) { - case Hy3GroupLayout::Tabbed: - // treat tabbed layouts as if they dont exist during resizing - goto cont2; - case Hy3GroupLayout::SplitH: - if(getOuterChild(parent_group, direction_x) == current_node) { - goto cont2; - } - break; - case Hy3GroupLayout::SplitV: - if(getOuterChild(parent_group, direction_y) == current_node) { - goto cont2; - } - break; - } - - break; - cont2: current_node = current_node->parent; } - return current_node; + return sibling; +} + +void Hy3Node::resize( + double resize_delta, + ShiftDirection target_edge_x +) { + auto& parent_node = this->parent; + auto& containing_group = parent_node->data.as_group; + const auto animate = + &g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue; + + if(containing_group.layout != Hy3GroupLayout::Tabbed && getAxis(target_edge_x) == getAxis(containing_group.layout)) { + double parent_size = getAxis(target_edge_x) == Axis::Horizontal ? parent_node->size.x + : parent_node->size.y; + auto ratio_mod = resize_delta * (float) containing_group.children.size() / parent_size; + + auto iter = std::find(containing_group.children.begin(), containing_group.children.end(), this); + + if (target_edge_x == ShiftDirection::Left || target_edge_x == ShiftDirection::Up) { + if (this != containing_group.children.back()) { + iter = std::next(iter); + } + } else { + if (this != containing_group.children.front()) { + iter = std::prev(iter); + ratio_mod = -ratio_mod; + } + } + + auto* neighbor = *iter; + + if(this->size_ratio + ratio_mod > MIN_RATIO && neighbor->size_ratio - ratio_mod > MIN_RATIO) { + this->size_ratio += ratio_mod; + neighbor->size_ratio -= ratio_mod; + parent_node->recalcSizePosRecursive(*animate == 0); + } + } } void Hy3Node::swapData(Hy3Node& a, Hy3Node& b) { diff --git a/src/Hy3Node.hpp b/src/Hy3Node.hpp index 77ed7e9..148cc47 100644 --- a/src/Hy3Node.hpp +++ b/src/Hy3Node.hpp @@ -99,7 +99,9 @@ struct Hy3Node { void markFocused(); void raiseToTop(); Hy3Node* getFocusedNode(bool ignore_group_focus = false, bool stop_at_expanded = false); - Hy3Node* findSibling(Hy3GroupLayout inner_layout, ShiftDirection direction_x, ShiftDirection direction_y); + Hy3Node* findSibling(ShiftDirection); + Hy3Node* getImmediateSibling(ShiftDirection); + void resize(double, ShiftDirection); bool isIndirectlyFocused(); Hy3Node& getExpandActor(); From dad1589d2185d32243f8089a67ad2637d6233eae Mon Sep 17 00:00:00 2001 From: Pete Appleton Date: Mon, 29 Jan 2024 08:31:16 +0000 Subject: [PATCH 15/27] Improve iteration handling and validate results --- src/Hy3Layout.cpp | 52 +++++++++++++++++++++++++----------- src/Hy3Node.cpp | 67 +++++++++++++++++++++++++++++------------------ src/Hy3Node.hpp | 4 +-- 3 files changed, 81 insertions(+), 42 deletions(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index 91865ca..c62b306 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -390,6 +390,17 @@ void Hy3Layout::recalculateWindow(CWindow* window) { node->recalcSizePosRecursive(); } +ShiftDirection reverse(ShiftDirection direction) { + switch (direction) + { + case ShiftDirection::Left: return ShiftDirection::Right; + case ShiftDirection::Right: return ShiftDirection::Left; + case ShiftDirection::Up: return ShiftDirection::Down; + case ShiftDirection::Down: return ShiftDirection::Up; + default: return 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; @@ -421,11 +432,15 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW ShiftDirection target_edge_x; ShiftDirection target_edge_y; - // Determine the direction in which we're going to look for the sibling node + // Determine the direction in which we're going to look for the neighbor node // that will be resized if(corner == CORNER_NONE) { // It's probably a keyboard event. target_edge_x = display_right ? ShiftDirection::Left : ShiftDirection::Right; target_edge_y = display_bottom ? ShiftDirection::Up : ShiftDirection::Down; + + // If the anchor is not at the top/left then reverse the delta + if(target_edge_x == ShiftDirection::Left) resize_delta.x = -resize_delta.x; + if(target_edge_y == ShiftDirection::Up) resize_delta.y = -resize_delta.y; } else { // It's probably a mouse event // Resize against the edges corresponding to the selected corner target_edge_x = corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT @@ -434,25 +449,32 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW ? ShiftDirection::Up : ShiftDirection::Down; } - auto sibling_node_x = node->findSibling(target_edge_x); - auto sibling_node_y = node->findSibling(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); - if(sibling_node_x) { - sibling_node_x->resize(resize_delta.x, target_edge_x); + const auto animate = + &g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue; + + // Note that the resize direction is reversed, because from the neighbor's perspective + // the edge to be moved is the opposite way round. However, the delta is still the same. + if(horizontal_neighbor) { + horizontal_neighbor->resize(reverse(target_edge_x), resize_delta.x, *animate == 0); } - if(sibling_node_y) { - sibling_node_y->resize(resize_delta.y, target_edge_y); + if(vertical_neighbor) { + vertical_neighbor->resize(reverse(target_edge_y), resize_delta.y, *animate == 0); } - } else { + } else if(window->m_bIsFloating) { // No parent node - is this a floating window? If so, use the same logic as the `main` layout - if(window->m_bIsFloating) { - const auto required_size = Vector2D( - std::max((window->m_vRealSize.goalv() + delta).x, 20.0), - std::max((window->m_vRealSize.goalv() + delta).y, 20.0) - ); - window->m_vRealSize = required_size; - } + const auto required_size = Vector2D( + std::max((window->m_vRealSize.goalv() + delta).x, 20.0), + std::max((window->m_vRealSize.goalv() + delta).y, 20.0) + ); + window->m_vRealSize = required_size; } } diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp index f44ae78..6c2c415 100644 --- a/src/Hy3Node.cpp +++ b/src/Hy3Node.cpp @@ -7,7 +7,7 @@ #include "Hy3Node.hpp" #include "globals.hpp" -const float MIN_RATIO = 0.02f; +const float MIN_WINDOW_SIZE = 20; // Hy3GroupData // @@ -879,7 +879,7 @@ Axis getAxis(ShiftDirection direction) { } } -Hy3Node* Hy3Node::findSibling(ShiftDirection direction) { +Hy3Node* Hy3Node::findNeighbor(ShiftDirection direction) { auto current_node = this; Hy3Node* sibling = nullptr; @@ -901,40 +901,57 @@ Hy3Node* Hy3Node::findSibling(ShiftDirection direction) { return sibling; } +int directionToIteratorIncrement(ShiftDirection direction) { + switch (direction) + { + case ShiftDirection::Left: + case ShiftDirection::Up: + return -1; + case ShiftDirection::Right: + case ShiftDirection::Down: + return 1; + default: + hy3_log(WARN, "Unknown ShiftDirection enum value: {}", (int)direction); + return 1; + } +} + void Hy3Node::resize( - double resize_delta, - ShiftDirection target_edge_x + ShiftDirection direction, + double delta, + bool no_animation ) { auto& parent_node = this->parent; auto& containing_group = parent_node->data.as_group; - const auto animate = - &g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue; - if(containing_group.layout != Hy3GroupLayout::Tabbed && getAxis(target_edge_x) == getAxis(containing_group.layout)) { - double parent_size = getAxis(target_edge_x) == Axis::Horizontal ? parent_node->size.x + if(containing_group.layout != Hy3GroupLayout::Tabbed && getAxis(direction) == getAxis(containing_group.layout)) { + double parent_size = getAxis(direction) == Axis::Horizontal ? parent_node->size.x : parent_node->size.y; - auto ratio_mod = resize_delta * (float) containing_group.children.size() / parent_size; + auto ratio_mod = delta * (float) containing_group.children.size() / parent_size; - auto iter = std::find(containing_group.children.begin(), containing_group.children.end(), this); + const auto end_of_children = containing_group.children.end(); + auto iter = std::find(containing_group.children.begin(), end_of_children, this); - if (target_edge_x == ShiftDirection::Left || target_edge_x == ShiftDirection::Up) { - if (this != containing_group.children.back()) { - iter = std::next(iter); + if(iter != end_of_children) { + const auto outermost_node_in_group = getOuterChild(containing_group, direction); + if(this != outermost_node_in_group) { + auto inc = directionToIteratorIncrement(direction); + iter = std::next(iter, inc); + ratio_mod *= inc; } - } else { - if (this != containing_group.children.front()) { - iter = std::prev(iter); - ratio_mod = -ratio_mod; + + if(iter != end_of_children) { + auto* neighbor = *iter; + auto requested_size_ratio = this->size_ratio + ratio_mod; + auto requested_neighbor_size_ratio = neighbor->size_ratio -ratio_mod; + + if(requested_size_ratio * parent_size >= MIN_WINDOW_SIZE) { + this->size_ratio = requested_size_ratio; + neighbor->size_ratio = requested_neighbor_size_ratio; + parent_node->recalcSizePosRecursive(no_animation); + } } } - - auto* neighbor = *iter; - - if(this->size_ratio + ratio_mod > MIN_RATIO && neighbor->size_ratio - ratio_mod > MIN_RATIO) { - this->size_ratio += ratio_mod; - neighbor->size_ratio -= ratio_mod; - parent_node->recalcSizePosRecursive(*animate == 0); - } } } diff --git a/src/Hy3Node.hpp b/src/Hy3Node.hpp index 148cc47..f892efb 100644 --- a/src/Hy3Node.hpp +++ b/src/Hy3Node.hpp @@ -99,9 +99,9 @@ struct Hy3Node { void markFocused(); void raiseToTop(); Hy3Node* getFocusedNode(bool ignore_group_focus = false, bool stop_at_expanded = false); - Hy3Node* findSibling(ShiftDirection); + Hy3Node* findNeighbor(ShiftDirection); Hy3Node* getImmediateSibling(ShiftDirection); - void resize(double, ShiftDirection); + void resize(ShiftDirection, double, bool no_animation = false); bool isIndirectlyFocused(); Hy3Node& getExpandActor(); From cfa15c9ef6a01486c5983b38de5aa24cb2c32bd7 Mon Sep 17 00:00:00 2001 From: Pete Appleton Date: Mon, 29 Jan 2024 20:28:36 +0000 Subject: [PATCH 16/27] Use MIN_RATIO to cap node sizes A minimum Vector2D would be ideal, but hard to calculate - it would require either a tree walk for every single resize operation (very expensive), or storing after a `recalcSizePosRecursive` operation (significant work) --- src/Hy3Layout.cpp | 67 +++++++++++++++++++++++++---------------------- src/Hy3Node.cpp | 6 +++-- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index c62b306..96b4459 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -429,44 +429,47 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW if (display_left && display_right) resize_delta.x = 0; if (display_top && display_bottom) resize_delta.y = 0; - ShiftDirection target_edge_x; - ShiftDirection target_edge_y; + // Don't execute the logic unless there's something to do + if(resize_delta.x != 0 || resize_delta.y != 0) { + ShiftDirection target_edge_x; + ShiftDirection target_edge_y; - // Determine the direction in which we're going to look for the neighbor node - // that will be resized - if(corner == CORNER_NONE) { // It's probably a keyboard event. - target_edge_x = display_right ? ShiftDirection::Left : ShiftDirection::Right; - target_edge_y = display_bottom ? ShiftDirection::Up : ShiftDirection::Down; + // Determine the direction in which we're going to look for the neighbor node + // that will be resized + if(corner == CORNER_NONE) { // It's probably a keyboard event. + target_edge_x = display_right ? ShiftDirection::Left : ShiftDirection::Right; + target_edge_y = display_bottom ? ShiftDirection::Up : ShiftDirection::Down; - // If the anchor is not at the top/left then reverse the delta - if(target_edge_x == ShiftDirection::Left) resize_delta.x = -resize_delta.x; - if(target_edge_y == ShiftDirection::Up) resize_delta.y = -resize_delta.y; - } else { // It's probably a mouse event - // Resize against the edges corresponding to the selected corner - target_edge_x = corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT - ? ShiftDirection::Left : ShiftDirection::Right; - target_edge_y = corner == CORNER_TOPLEFT || corner == CORNER_TOPRIGHT - ? ShiftDirection::Up : ShiftDirection::Down; - } + // If the anchor is not at the top/left then reverse the delta + if(target_edge_x == ShiftDirection::Left) resize_delta.x = -resize_delta.x; + if(target_edge_y == ShiftDirection::Up) resize_delta.y = -resize_delta.y; + } else { // It's probably a mouse event + // Resize against the edges corresponding to the selected corner + target_edge_x = corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT + ? ShiftDirection::Left : ShiftDirection::Right; + target_edge_y = corner == CORNER_TOPLEFT || corner == CORNER_TOPRIGHT + ? ShiftDirection::Up : 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); - const auto animate = - &g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue; + const auto animate = + &g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue; - // Note that the resize direction is reversed, because from the neighbor's perspective - // the edge to be moved is the opposite way round. However, the delta is still the same. - if(horizontal_neighbor) { - horizontal_neighbor->resize(reverse(target_edge_x), resize_delta.x, *animate == 0); - } + // Note that the resize direction is reversed, because from the neighbor's perspective + // the edge to be moved is the opposite way round. However, the delta is still the same. + if(horizontal_neighbor) { + 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) { // No parent node - is this a floating window? If so, use the same logic as the `main` layout diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp index 6c2c415..d666d48 100644 --- a/src/Hy3Node.cpp +++ b/src/Hy3Node.cpp @@ -7,7 +7,7 @@ #include "Hy3Node.hpp" #include "globals.hpp" -const float MIN_WINDOW_SIZE = 20; +const float MIN_RATIO = 0.0f; // Hy3GroupData // @@ -945,9 +945,11 @@ void Hy3Node::resize( auto requested_size_ratio = this->size_ratio + ratio_mod; auto requested_neighbor_size_ratio = neighbor->size_ratio -ratio_mod; - if(requested_size_ratio * parent_size >= MIN_WINDOW_SIZE) { + if(requested_size_ratio >= MIN_RATIO + && requested_neighbor_size_ratio >= MIN_RATIO) { this->size_ratio = requested_size_ratio; neighbor->size_ratio = requested_neighbor_size_ratio; + parent_node->recalcSizePosRecursive(no_animation); } } From f58720ba832af0c3423a444f4f2eb6eae6b83f10 Mon Sep 17 00:00:00 2001 From: Pete Appleton Date: Wed, 31 Jan 2024 08:50:40 +0000 Subject: [PATCH 17/27] Fix: Only constrain node resize if they are at the root of the layout --- src/Hy3Layout.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index 96b4459..a9e00de 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -426,8 +426,13 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW ); Vector2D resize_delta = delta; - if (display_left && display_right) resize_delta.x = 0; - if (display_top && display_bottom) resize_delta.y = 0; + bool node_is_root = (node->data.type == Hy3NodeType::Group && node->parent == nullptr) + || (node->data.type == Hy3NodeType::Window && (node->parent == nullptr || node->parent->parent == nullptr)); + + if(node_is_root) { + if (display_left && display_right) resize_delta.x = 0; + if (display_top && display_bottom) resize_delta.y = 0; + } // Don't execute the logic unless there's something to do if(resize_delta.x != 0 || resize_delta.y != 0) { From acedb05a75a3a44c1a0f0f56842fe4e607324f4b Mon Sep 17 00:00:00 2001 From: q234rty Date: Tue, 6 Feb 2024 15:54:26 +0800 Subject: [PATCH 18/27] Fix building on Hyprland 0.35.0 Ref https://github.com/hyprwm/Hyprland/pull/4514 --- src/Hy3Layout.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index bca5224..09ba804 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -157,7 +157,7 @@ void Hy3Layout::insertNode(Hy3Node& node) { opening_after = this->getNodeFromWindow(g_pCompositor->m_pLastWindow); } else { auto* mouse_window = - g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal()); + g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS); if (mouse_window != nullptr && mouse_window->m_iWorkspaceID == node.workspace_id) { opening_after = this->getNodeFromWindow(mouse_window); @@ -1227,8 +1227,8 @@ void Hy3Layout::focusTab( Hy3Node* tab_focused_node; if (target == TabFocus::MouseLocation || mouse != TabFocusMousePriority::Ignore) { - if (g_pCompositor->windowFloatingFromCursor() == nullptr) { - auto mouse_pos = g_pInputManager->getMouseCoordsInternal(); + auto mouse_pos = g_pInputManager->getMouseCoordsInternal(); + if (g_pCompositor->vectorToWindowUnified(mouse_pos, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING | FLOATING_ONLY) == nullptr) { tab_node = findTabBarAt(*node, mouse_pos, &tab_focused_node); if (tab_node != nullptr) goto hastab; } From d3e20856a9896f28b506195b31407eddc6df2e20 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Tue, 6 Feb 2024 13:40:44 -0800 Subject: [PATCH 19/27] Update flake reference to hyprland 0.35.0 --- flake.lock | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/flake.lock b/flake.lock index 216444c..410c5fe 100644 --- a/flake.lock +++ b/flake.lock @@ -9,11 +9,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1704110595, - "narHash": "sha256-WSrjBI3k2dM/kGF20At0E6NlrJSB4+pE+WGJ6dFzWEs=", + "lastModified": 1707098342, + "narHash": "sha256-dU5m6Cd4+WQZal2ICDVf1kww/dNzo1YUWRxWeCctEig=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "03ebbe18ed8517ee22591eac82cd54322f42cb7d", + "rev": "84ab8d11e8951a6551d1e1bf87796a8589da6d47", "type": "github" }, "original": { @@ -47,13 +47,35 @@ "type": "github" } }, + "hyprlang": { + "inputs": { + "nixpkgs": [ + "hyprland", + "xdph", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1704287638, + "narHash": "sha256-TuRXJGwtK440AXQNl5eiqmQqY4LZ/9+z/R7xC0ie3iA=", + "owner": "hyprwm", + "repo": "hyprlang", + "rev": "6624f2bb66d4d27975766e81f77174adbe58ec97", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprlang", + "type": "github" + } + }, "nixpkgs": { "locked": { - "lastModified": 1703438236, - "narHash": "sha256-aqVBq1u09yFhL7bj1/xyUeJjzr92fXVvQSSEx6AdB1M=", + "lastModified": 1706191920, + "narHash": "sha256-eLihrZAPZX0R6RyM5fYAWeKVNuQPYjAkCUBr+JNvtdE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "5f64a12a728902226210bf01d25ec6cbb9d9265b", + "rev": "ae5c332cbb5827f6b1f02572496b141021de335f", "type": "github" }, "original": { @@ -87,18 +109,18 @@ "flake": false, "locked": { "host": "gitlab.freedesktop.org", - "lastModified": 1701368958, - "narHash": "sha256-7kvyoA91etzVEl9mkA/EJfB6z/PltxX7Xc4gcr7/xlo=", + "lastModified": 1706359063, + "narHash": "sha256-5HUTG0p+nCJv3cn73AmFHRZdfRV5AD5N43g8xAePSKM=", "owner": "wlroots", "repo": "wlroots", - "rev": "5d639394f3e83b01596dcd166a44a9a1a2583350", + "rev": "00b869c1a96f300a8f25da95d624524895e0ddf2", "type": "gitlab" }, "original": { "host": "gitlab.freedesktop.org", "owner": "wlroots", "repo": "wlroots", - "rev": "5d639394f3e83b01596dcd166a44a9a1a2583350", + "rev": "00b869c1a96f300a8f25da95d624524895e0ddf2", "type": "gitlab" } }, @@ -108,6 +130,7 @@ "hyprland", "hyprland-protocols" ], + "hyprlang": "hyprlang", "nixpkgs": [ "hyprland", "nixpkgs" @@ -118,11 +141,11 @@ ] }, "locked": { - "lastModified": 1703514399, - "narHash": "sha256-VRr5Xc4S/VPr/gU3fiOD3vSIL2+GJ+LUrmFTWTwnTz4=", + "lastModified": 1706145785, + "narHash": "sha256-j9MP4fv2U/vdRKAXXc2gyMTmYwVnHP6kHx1/y6jprrU=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "0a318a7a217a6402b0b705837cd5b50b0e94b31b", + "rev": "5a592647587cd20b9692a347df6939b6d371b3bb", "type": "github" }, "original": { From 107cb86304435368c68a4d8111cf01de628734b2 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Tue, 6 Feb 2024 13:56:26 -0800 Subject: [PATCH 20/27] Update to hyprland 0.35.0 --- CHANGELOG.md | 2 ++ hyprpm.toml | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6b4c99..2038191 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Upcoming +## hl0.35.0 and before + - Fixed `hy3:killactive` and `hy3:movetoworkspace` not working in fullscreen. - `hy3:movetoworkspace` added to move a whole node to a workspace. - Newly tiled windows (usually from moving a window to a new workspace) are now diff --git a/hyprpm.toml b/hyprpm.toml index c8fd12b..012b379 100644 --- a/hyprpm.toml +++ b/hyprpm.toml @@ -2,7 +2,8 @@ name = "hy3" authors = ["outfoxxed"] commit_pins = [ - ["03ebbe18ed8517ee22591eac82cd54322f42cb7d", "2f28dc810c0e1f42763a1f14fb011c4fce6db8be"] + ["03ebbe18ed8517ee22591eac82cd54322f42cb7d", "2f28dc810c0e1f42763a1f14fb011c4fce6db8be"], + ["84ab8d11e8951a6551d1e1bf87796a8589da6d47", "d3e20856a9896f28b506195b31407eddc6df2e20"] ] [hy3] From 7f1989689df71da8e2081dc24453ccd41341bf50 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Tue, 6 Feb 2024 14:36:11 -0800 Subject: [PATCH 21/27] Fix starting with a horizontal layout on vertical monitors --- src/Hy3Layout.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index 09ba804..1a8948e 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -156,8 +156,10 @@ void Hy3Layout::insertNode(Hy3Node& node) { { opening_after = this->getNodeFromWindow(g_pCompositor->m_pLastWindow); } else { - auto* mouse_window = - g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS); + auto* mouse_window = g_pCompositor->vectorToWindowUnified( + g_pInputManager->getMouseCoordsInternal(), + RESERVED_EXTENTS | INPUT_EXTENTS + ); if (mouse_window != nullptr && mouse_window->m_iWorkspaceID == node.workspace_id) { opening_after = this->getNodeFromWindow(mouse_window); @@ -180,8 +182,13 @@ void Hy3Layout::insertNode(Hy3Node& node) { static const auto* tab_first_window = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tab_first_window")->intValue; + auto width = + monitor->vecSize.x - monitor->vecReservedBottomRight.x - monitor->vecReservedTopLeft.x; + auto height = + monitor->vecSize.y - monitor->vecReservedBottomRight.y - monitor->vecReservedTopLeft.y; + this->nodes.push_back({ - .data = Hy3GroupLayout::SplitH, + .data = height > width ? Hy3GroupLayout::SplitV : Hy3GroupLayout::SplitH, .position = monitor->vecPosition + monitor->vecReservedTopLeft, .size = monitor->vecSize - monitor->vecReservedTopLeft - monitor->vecReservedBottomRight, .workspace_id = node.workspace_id, @@ -1228,7 +1235,12 @@ void Hy3Layout::focusTab( if (target == TabFocus::MouseLocation || mouse != TabFocusMousePriority::Ignore) { auto mouse_pos = g_pInputManager->getMouseCoordsInternal(); - if (g_pCompositor->vectorToWindowUnified(mouse_pos, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING | FLOATING_ONLY) == nullptr) { + if (g_pCompositor->vectorToWindowUnified( + mouse_pos, + RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING | FLOATING_ONLY + ) + == nullptr) + { tab_node = findTabBarAt(*node, mouse_pos, &tab_focused_node); if (tab_node != nullptr) goto hastab; } From d1d722826ce93351a2dda5c7c625d46d811cc946 Mon Sep 17 00:00:00 2001 From: Pete Appleton Date: Sat, 10 Feb 2024 08:28:43 +0000 Subject: [PATCH 22/27] Correct typo in README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 047dfe2..a059ee6 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Commits are tested before pushing and will build against the hyprland release ** There may be a mismatch with hyprland's main branch. If hy3 fails to build against hyprland's main branch please make an issue or ping me in the [hy3 matrix room](https://matrix.to/#/#hy3-support:outfoxxed.me). -Tagged hy3 versions are always checked against the corrosponding hyprland tag. +Tagged hy3 versions are always checked against the corresponding hyprland tag. If you encounter any bugs, please report them in the issue tracker. @@ -122,7 +122,7 @@ isn't capable of locking hy3 builds to the correct hyprland version. > exec-once = hyprpm reload -n > ``` > -> in your hyprland.conf. (See [the wiki](https://wiki.hyprland.org/Plugins/Using-Plugins/) for details.) +> in your hyprland.conf. (See [the wiki](https://wiki.hyprland.org/Plugins/Using-Plugins/) for details.) To install hy3 via hyprpm run @@ -294,7 +294,7 @@ plugin { # 0 = always automatically split horizontally # = pixel height to split at trigger_height = # default: 0 - + # a space or comma separated list of workspace ids where autotile should be enabled # it's possible to create an exception rule by prefixing the definition with "not:" # workspaces = 1,2 # autotiling will only be enabled on workspaces 1 and 2 From 449c9d67f84869e2cc974b12edc8db37acf75d7b Mon Sep 17 00:00:00 2001 From: Arjun31415 Date: Wed, 14 Feb 2024 08:29:11 +0530 Subject: [PATCH 23/27] Fix hy3 build `m_bNoFocus` field moved to struct `m_sAdditionalConfigData`. Ref https://github.com/hyprwm/Hyprland/pull/4672 --- flake.lock | 18 +++++++++--------- src/Hy3Layout.cpp | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/flake.lock b/flake.lock index 410c5fe..d4b336c 100644 --- a/flake.lock +++ b/flake.lock @@ -9,11 +9,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1707098342, - "narHash": "sha256-dU5m6Cd4+WQZal2ICDVf1kww/dNzo1YUWRxWeCctEig=", + "lastModified": 1707847639, + "narHash": "sha256-mBmt1lFImpIK8VwHkJIenzVS95wD67dsfH1oRk2RiEg=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "84ab8d11e8951a6551d1e1bf87796a8589da6d47", + "rev": "2a3429d4cfdc01794b9d6fc1b49be1da019b5606", "type": "github" }, "original": { @@ -71,11 +71,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1706191920, - "narHash": "sha256-eLihrZAPZX0R6RyM5fYAWeKVNuQPYjAkCUBr+JNvtdE=", + "lastModified": 1707546158, + "narHash": "sha256-nYYJTpzfPMDxI8mzhQsYjIUX+grorqjKEU9Np6Xwy/0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ae5c332cbb5827f6b1f02572496b141021de335f", + "rev": "d934204a0f8d9198e1e4515dd6fec76a139c87f0", "type": "github" }, "original": { @@ -141,11 +141,11 @@ ] }, "locked": { - "lastModified": 1706145785, - "narHash": "sha256-j9MP4fv2U/vdRKAXXc2gyMTmYwVnHP6kHx1/y6jprrU=", + "lastModified": 1706521509, + "narHash": "sha256-AInZ50acOJ3wzUwGzNr1TmxGTMx+8j6oSTzz4E7Vbp8=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "5a592647587cd20b9692a347df6939b6d371b3bb", + "rev": "c06fd88b3da492b8f9067be021b9184f7012b5a8", "type": "github" }, "original": { diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index f341ece..a99dd96 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -630,7 +630,7 @@ CWindow* Hy3Layout::getNextWindowCandidate(CWindow* window) { for (auto& w: g_pCompositor->m_vWindows | std::views::reverse) { if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2 && w->m_iWorkspaceID == window->m_iWorkspaceID && !w->m_bX11ShouldntFocus - && !w->m_bNoFocus && w.get() != window) + && !w->m_sAdditionalConfigData.noFocus && w.get() != window) { return w.get(); } From cdb2c28df1f404cb814d188160f31f33c95b5f6c Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Wed, 14 Feb 2024 22:33:07 -0800 Subject: [PATCH 24/27] Migrate config to hyprlang --- flake.lock | 30 ++++++++++-- src/Hy3Layout.cpp | 91 +++++++++++++++++------------------ src/Hy3Layout.hpp | 6 +-- src/Hy3Node.cpp | 118 ++++++++++++++++++---------------------------- src/TabGroup.cpp | 48 +++++++++---------- src/globals.hpp | 22 +++++++++ src/main.cpp | 57 +++++++++++----------- 7 files changed, 192 insertions(+), 180 deletions(-) diff --git a/flake.lock b/flake.lock index d4b336c..bb5cb70 100644 --- a/flake.lock +++ b/flake.lock @@ -3,17 +3,18 @@ "hyprland": { "inputs": { "hyprland-protocols": "hyprland-protocols", + "hyprlang": "hyprlang", "nixpkgs": "nixpkgs", "systems": "systems", "wlroots": "wlroots", "xdph": "xdph" }, "locked": { - "lastModified": 1707847639, - "narHash": "sha256-mBmt1lFImpIK8VwHkJIenzVS95wD67dsfH1oRk2RiEg=", + "lastModified": 1707952083, + "narHash": "sha256-DYt7APLnlG28Cj+KigYtlQrQ1W6DcHw5z7QXW+RDpa4=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "2a3429d4cfdc01794b9d6fc1b49be1da019b5606", + "rev": "3a6451b6026a5f38987e61ee07b442910b5432f5", "type": "github" }, "original": { @@ -48,6 +49,27 @@ } }, "hyprlang": { + "inputs": { + "nixpkgs": [ + "hyprland", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1707842572, + "narHash": "sha256-dYGkJycYJ0RjfkKE98XtppQukr6AHkR5bPJN0GsJeTI=", + "owner": "hyprwm", + "repo": "hyprlang", + "rev": "4a464738e2d12bf3a9735831f784969c7568a4af", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprlang", + "type": "github" + } + }, + "hyprlang_2": { "inputs": { "nixpkgs": [ "hyprland", @@ -130,7 +152,7 @@ "hyprland", "hyprland-protocols" ], - "hyprlang": "hyprlang", + "hyprlang": "hyprlang_2", "nixpkgs": [ "hyprland", "nixpkgs" diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index a99dd96..dde4c31 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -179,8 +179,8 @@ void Hy3Layout::insertNode(Hy3Node& node) { opening_into = opening_after->parent; } else { if ((opening_into = this->getWorkspaceRootGroup(node.workspace_id)) == nullptr) { - static const auto* tab_first_window = - &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tab_first_window")->intValue; + static const auto tab_first_window = + ConfigValue("plugin:hy3:tab_first_window"); auto width = monitor->vecSize.x - monitor->vecReservedBottomRight.x - monitor->vecReservedTopLeft.x; @@ -233,10 +233,10 @@ void Hy3Layout::insertNode(Hy3Node& node) { { // clang-format off - static const auto* at_enable = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:autotile:enable")->intValue; - static const auto* at_ephemeral = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:autotile:ephemeral_groups")->intValue; - static const auto* at_trigger_width = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:autotile:trigger_width")->intValue; - static const auto* at_trigger_height = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:autotile:trigger_height")->intValue; + static const auto at_enable = ConfigValue("plugin:hy3:autotile:enable"); + static const auto at_ephemeral = ConfigValue("plugin:hy3:autotile:ephemeral_groups"); + static const auto at_trigger_width = ConfigValue("plugin:hy3:autotile:trigger_width"); + static const auto at_trigger_height = ConfigValue("plugin:hy3:autotile:trigger_height"); // clang-format on this->updateAutotileWorkspaces(); @@ -287,8 +287,8 @@ void Hy3Layout::insertNode(Hy3Node& node) { } void Hy3Layout::onWindowRemovedTiling(CWindow* window) { - static const auto* node_collapse_policy = - &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:node_collapse_policy")->intValue; + static const auto node_collapse_policy = + ConfigValue("plugin:hy3:node_collapse_policy"); auto* node = this->getNodeFromWindow(window); @@ -398,8 +398,7 @@ void Hy3Layout::recalculateWindow(CWindow* window) { } ShiftDirection reverse(ShiftDirection direction) { - switch (direction) - { + switch (direction) { case ShiftDirection::Left: return ShiftDirection::Right; case ShiftDirection::Right: return ShiftDirection::Left; case ShiftDirection::Up: return ShiftDirection::Down; @@ -414,53 +413,56 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW auto* node = this->getNodeFromWindow(window); - if(node != nullptr) { + if (node != nullptr) { node = &node->getExpandActor(); auto monitor = g_pCompositor->getMonitorFromID(window->m_iMonitorID); const bool display_left = - STICKS(node->position.x, monitor->vecPosition.x + monitor->vecReservedTopLeft.x); + STICKS(node->position.x, monitor->vecPosition.x + monitor->vecReservedTopLeft.x); const bool display_right = STICKS( - node->position.x + node->size.x, - monitor->vecPosition.x + monitor->vecSize.x - monitor->vecReservedBottomRight.x + node->position.x + node->size.x, + monitor->vecPosition.x + monitor->vecSize.x - monitor->vecReservedBottomRight.x ); const bool display_top = - STICKS(node->position.y, monitor->vecPosition.y + monitor->vecReservedTopLeft.y); + STICKS(node->position.y, monitor->vecPosition.y + monitor->vecReservedTopLeft.y); const bool display_bottom = STICKS( - node->position.y + node->size.y, - monitor->vecPosition.y + monitor->vecSize.y - monitor->vecReservedBottomRight.y + node->position.y + node->size.y, + monitor->vecPosition.y + monitor->vecSize.y - monitor->vecReservedBottomRight.y ); Vector2D resize_delta = delta; bool node_is_root = (node->data.type == Hy3NodeType::Group && node->parent == nullptr) - || (node->data.type == Hy3NodeType::Window && (node->parent == nullptr || node->parent->parent == nullptr)); + || (node->data.type == Hy3NodeType::Window + && (node->parent == nullptr || node->parent->parent == nullptr)); - if(node_is_root) { + if (node_is_root) { if (display_left && display_right) resize_delta.x = 0; if (display_top && display_bottom) resize_delta.y = 0; } // Don't execute the logic unless there's something to do - if(resize_delta.x != 0 || resize_delta.y != 0) { + if (resize_delta.x != 0 || resize_delta.y != 0) { ShiftDirection target_edge_x; ShiftDirection target_edge_y; // Determine the direction in which we're going to look for the neighbor node // that will be resized - if(corner == CORNER_NONE) { // It's probably a keyboard event. + if (corner == CORNER_NONE) { // It's probably a keyboard event. target_edge_x = display_right ? ShiftDirection::Left : ShiftDirection::Right; target_edge_y = display_bottom ? ShiftDirection::Up : ShiftDirection::Down; // If the anchor is not at the top/left then reverse the delta - if(target_edge_x == ShiftDirection::Left) resize_delta.x = -resize_delta.x; - if(target_edge_y == ShiftDirection::Up) resize_delta.y = -resize_delta.y; - } else { // It's probably a mouse event + if (target_edge_x == ShiftDirection::Left) resize_delta.x = -resize_delta.x; + if (target_edge_y == ShiftDirection::Up) resize_delta.y = -resize_delta.y; + } else { // It's probably a mouse event // Resize against the edges corresponding to the selected corner target_edge_x = corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT - ? ShiftDirection::Left : ShiftDirection::Right; + ? ShiftDirection::Left + : ShiftDirection::Right; target_edge_y = corner == CORNER_TOPLEFT || corner == CORNER_TOPRIGHT - ? ShiftDirection::Up : ShiftDirection::Down; + ? ShiftDirection::Up + : ShiftDirection::Down; } // Find the neighboring node in each axis, which will be either above or at the @@ -470,24 +472,23 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW auto horizontal_neighbor = node->findNeighbor(target_edge_x); auto vertical_neighbor = node->findNeighbor(target_edge_y); - const auto animate = - &g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue; + static const auto animate = ConfigValue("misc:animate_manual_resizes"); // Note that the resize direction is reversed, because from the neighbor's perspective // the edge to be moved is the opposite way round. However, the delta is still the same. - if(horizontal_neighbor) { + if (horizontal_neighbor) { horizontal_neighbor->resize(reverse(target_edge_x), resize_delta.x, *animate == 0); } - if(vertical_neighbor) { + if (vertical_neighbor) { vertical_neighbor->resize(reverse(target_edge_y), resize_delta.y, *animate == 0); } } - } else if(window->m_bIsFloating) { + } 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), - std::max((window->m_vRealSize.goalv() + delta).y, 20.0) + std::max((window->m_vRealSize.goalv() + delta).x, 20.0), + std::max((window->m_vRealSize.goalv() + delta).y, 20.0) ); window->m_vRealSize = required_size; } @@ -542,8 +543,8 @@ void Hy3Layout::fullscreenRequestForWindow( // Copy of vaxry's massive hack // clang-format off - static const auto* gaps_in = &HyprlandAPI::getConfigValue(PHANDLE, "general:gaps_in")->intValue; - static const auto* gaps_out = &HyprlandAPI::getConfigValue(PHANDLE, "general:gaps_out")->intValue; + static const auto gaps_in = ConfigValue("general:gaps_in"); + static const auto gaps_out = ConfigValue("general:gaps_out"); // clang-format on int outer_gaps = -(*gaps_in - *gaps_out); @@ -982,8 +983,8 @@ void Hy3Layout::moveNodeToWorkspace(int origin, std::string wsname, bool follow) monitor->changeWorkspace(workspace); - static auto* const allow_workspace_cycles = - &g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles")->intValue; + static const auto allow_workspace_cycles = + ConfigValue("binds:allow_workspace_cycles"); if (*allow_workspace_cycles) workspace->rememberPrevWorkspace(origin_ws); } } @@ -1048,10 +1049,10 @@ bottom: Hy3Node* findTabBarAt(Hy3Node& node, Vector2D pos, Hy3Node** focused_node) { // clang-format off - static const auto* gaps_in = &HyprlandAPI::getConfigValue(PHANDLE, "general:gaps_in")->intValue; - static const auto* gaps_out = &HyprlandAPI::getConfigValue(PHANDLE, "general:gaps_out")->intValue; - static const auto* tab_bar_height = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:height")->intValue; - static const auto* tab_bar_padding = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:padding")->intValue; + static const auto gaps_in = ConfigValue("general:gaps_in"); + static const auto gaps_out = ConfigValue("general:gaps_out"); + static const auto tab_bar_height = ConfigValue("plugin:hy3:tabs:height"); + static const auto tab_bar_padding = ConfigValue("plugin:hy3:tabs:padding"); // clang-format on auto inset = *tab_bar_height + *tab_bar_padding; @@ -1467,8 +1468,8 @@ void Hy3Layout::applyNodeDataToWindow(Hy3Node* node, bool no_animation) { } // clang-format off - static const auto* gaps_in = &HyprlandAPI::getConfigValue(PHANDLE, "general:gaps_in")->intValue; - static const auto* single_window_no_gaps = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:no_gaps_when_only")->intValue; + static const auto gaps_in = ConfigValue("general:gaps_in"); + static const auto single_window_no_gaps = ConfigValue("plugin:hy3:no_gaps_when_only"); // clang-format on if (!g_pCompositor->windowExists(window) || !window->m_bIsMapped) { @@ -1788,8 +1789,8 @@ Hy3Node* Hy3Layout::shiftOrGetFocus( } void Hy3Layout::updateAutotileWorkspaces() { - static const auto* autotile_raw_workspaces = - &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:autotile:workspaces")->strValue; + static const auto autotile_raw_workspaces = + ConfigValue("plugin:hy3:autotile:workspaces"); if (*autotile_raw_workspaces == this->autotile.raw_workspaces) { return; diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp index f912849..766d0bb 100644 --- a/src/Hy3Layout.hpp +++ b/src/Hy3Layout.hpp @@ -20,11 +20,7 @@ enum class ShiftDirection { Right, }; -enum class Axis { - None, - Horizontal, - Vertical -}; +enum class Axis { None, Horizontal, Vertical }; #include "Hy3Node.hpp" #include "TabGroup.hpp" diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp index d666d48..59264f2 100644 --- a/src/Hy3Node.cpp +++ b/src/Hy3Node.cpp @@ -270,11 +270,11 @@ Hy3Node& Hy3Node::getExpandActor() { void Hy3Node::recalcSizePosRecursive(bool no_animation) { // clang-format off - static const auto* gaps_in = &HyprlandAPI::getConfigValue(PHANDLE, "general:gaps_in")->intValue; - static const auto* gaps_out = &HyprlandAPI::getConfigValue(PHANDLE, "general:gaps_out")->intValue; - static const auto* group_inset = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:group_inset")->intValue; - static const auto* tab_bar_height = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:height")->intValue; - static const auto* tab_bar_padding = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:padding")->intValue; + static const auto gaps_in = ConfigValue("general:gaps_in"); + static const auto gaps_out = ConfigValue("general:gaps_out"); + static const auto group_inset = ConfigValue("plugin:hy3:group_inset"); + static const auto tab_bar_height = ConfigValue("plugin:hy3:tabs:height"); + static const auto tab_bar_padding = ConfigValue("plugin:hy3:tabs:padding"); // clang-format on if (this->data.type == Hy3NodeType::Window && this->data.as_window->m_bIsFullscreen) { @@ -810,18 +810,13 @@ bool Hy3Node::swallowGroups(Hy3Node* into) { return true; } -Hy3Node* getOuterChild(Hy3GroupData &group, ShiftDirection direction) { +Hy3Node* getOuterChild(Hy3GroupData& group, ShiftDirection direction) { switch (direction) { - case ShiftDirection::Left: - case ShiftDirection::Up: - return group.children.front(); - break; - case ShiftDirection::Right: - case ShiftDirection::Down: - return group.children.back(); - break; - default: - return nullptr; + case ShiftDirection::Left: + case ShiftDirection::Up: return group.children.front(); break; + case ShiftDirection::Right: + case ShiftDirection::Down: return group.children.back(); break; + default: return nullptr; } } @@ -830,22 +825,17 @@ Hy3Node* Hy3Node::getImmediateSibling(ShiftDirection direction) { auto iter = std::find(group.children.begin(), group.children.end(), this); - std::__cxx11::list::const_iterator list_sibling; + std::__cxx11::list::const_iterator list_sibling; switch (direction) { - case ShiftDirection::Left: - case ShiftDirection::Up: - list_sibling = std::prev(iter); - break; - case ShiftDirection::Right: - case ShiftDirection::Down: - list_sibling = std::next(iter); - break; - default: - list_sibling = iter; + case ShiftDirection::Left: + case ShiftDirection::Up: list_sibling = std::prev(iter); break; + case ShiftDirection::Right: + case ShiftDirection::Down: list_sibling = std::next(iter); break; + default: list_sibling = iter; } - if(list_sibling == group.children.end()) { + if (list_sibling == group.children.end()) { hy3_log(WARN, "getImmediateSibling: sibling not found"); list_sibling = iter; } @@ -854,28 +844,20 @@ Hy3Node* Hy3Node::getImmediateSibling(ShiftDirection direction) { } Axis getAxis(Hy3GroupLayout layout) { - switch (layout) - { - case Hy3GroupLayout::SplitH: - return Axis::Horizontal; - case Hy3GroupLayout::SplitV: - return Axis::Vertical; - default: - return Axis::None; + switch (layout) { + case Hy3GroupLayout::SplitH: return Axis::Horizontal; + case Hy3GroupLayout::SplitV: return Axis::Vertical; + default: return Axis::None; } } Axis getAxis(ShiftDirection direction) { - switch (direction) - { + switch (direction) { case ShiftDirection::Left: - case ShiftDirection::Right: - return Axis::Horizontal; + case ShiftDirection::Right: return Axis::Horizontal; case ShiftDirection::Down: - case ShiftDirection::Up: - return Axis::Vertical; - default: - return Axis::None; + case ShiftDirection::Up: return Axis::Vertical; + default: return Axis::None; } } @@ -886,11 +868,13 @@ Hy3Node* Hy3Node::findNeighbor(ShiftDirection direction) { while (sibling == nullptr && current_node->parent != nullptr) { auto& parent_group = current_node->parent->data.as_group; - if(parent_group.layout != Hy3GroupLayout::Tabbed && getAxis(parent_group.layout) == getAxis(direction)) { + if (parent_group.layout != Hy3GroupLayout::Tabbed + && getAxis(parent_group.layout) == getAxis(direction)) + { // If the current node is the outermost child of its parent group then proceed // then we need to look at the parent - otherwise, the sibling is simply the immediate // sibling in the child collection - if(getOuterChild(parent_group, direction) != current_node) { + if (getOuterChild(parent_group, direction) != current_node) { sibling = current_node->getImmediateSibling(direction); } } @@ -902,51 +886,43 @@ Hy3Node* Hy3Node::findNeighbor(ShiftDirection direction) { } int directionToIteratorIncrement(ShiftDirection direction) { - switch (direction) - { - case ShiftDirection::Left: - case ShiftDirection::Up: - return -1; - case ShiftDirection::Right: - case ShiftDirection::Down: - return 1; - default: - hy3_log(WARN, "Unknown ShiftDirection enum value: {}", (int)direction); - return 1; + switch (direction) { + case ShiftDirection::Left: + case ShiftDirection::Up: return -1; + case ShiftDirection::Right: + case ShiftDirection::Down: return 1; + default: hy3_log(WARN, "Unknown ShiftDirection enum value: {}", (int) direction); return 1; } } -void Hy3Node::resize( - ShiftDirection direction, - double delta, - bool no_animation -) { +void Hy3Node::resize(ShiftDirection direction, double delta, bool no_animation) { auto& parent_node = this->parent; auto& containing_group = parent_node->data.as_group; - if(containing_group.layout != Hy3GroupLayout::Tabbed && getAxis(direction) == getAxis(containing_group.layout)) { - double parent_size = getAxis(direction) == Axis::Horizontal ? parent_node->size.x - : parent_node->size.y; + if (containing_group.layout != Hy3GroupLayout::Tabbed + && getAxis(direction) == getAxis(containing_group.layout)) + { + double parent_size = + getAxis(direction) == Axis::Horizontal ? parent_node->size.x : parent_node->size.y; auto ratio_mod = delta * (float) containing_group.children.size() / parent_size; const auto end_of_children = containing_group.children.end(); auto iter = std::find(containing_group.children.begin(), end_of_children, this); - if(iter != end_of_children) { + if (iter != end_of_children) { const auto outermost_node_in_group = getOuterChild(containing_group, direction); - if(this != outermost_node_in_group) { + if (this != outermost_node_in_group) { auto inc = directionToIteratorIncrement(direction); iter = std::next(iter, inc); ratio_mod *= inc; } - if(iter != end_of_children) { + if (iter != end_of_children) { auto* neighbor = *iter; auto requested_size_ratio = this->size_ratio + ratio_mod; - auto requested_neighbor_size_ratio = neighbor->size_ratio -ratio_mod; + auto requested_neighbor_size_ratio = neighbor->size_ratio - ratio_mod; - if(requested_size_ratio >= MIN_RATIO - && requested_neighbor_size_ratio >= MIN_RATIO) { + if (requested_size_ratio >= MIN_RATIO && requested_neighbor_size_ratio >= MIN_RATIO) { this->size_ratio = requested_size_ratio; neighbor->size_ratio = requested_neighbor_size_ratio; diff --git a/src/TabGroup.cpp b/src/TabGroup.cpp index af2d989..b48a784 100644 --- a/src/TabGroup.cpp +++ b/src/TabGroup.cpp @@ -126,18 +126,18 @@ bool Hy3TabBarEntry::shouldRemove() { void Hy3TabBarEntry::prepareTexture(float scale, CBox& box) { // clang-format off - static const auto* s_rounding = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:rounding")->intValue; - static const auto* render_text = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:render_text")->intValue; - static const auto* text_center = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:text_center")->intValue; - static const auto* text_font = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:text_font")->strValue; - static const auto* text_height = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:text_height")->intValue; - static const auto* text_padding = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:text_padding")->intValue; - static const auto* col_active = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:col.active")->intValue; - static const auto* col_urgent = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:col.urgent")->intValue; - static const auto* col_inactive = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:col.inactive")->intValue; - static const auto* col_text_active = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:col.text.active")->intValue; - static const auto* col_text_urgent = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:col.text.urgent")->intValue; - static const auto* col_text_inactive = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:col.text.inactive")->intValue; + static const auto s_rounding = ConfigValue("plugin:hy3:tabs:rounding"); + static const auto render_text = ConfigValue("plugin:hy3:tabs:render_text"); + static const auto text_center = ConfigValue("plugin:hy3:tabs:text_center"); + static const auto text_font = ConfigValue("plugin:hy3:tabs:text_font"); + static const auto text_height = ConfigValue("plugin:hy3:tabs:text_height"); + static const auto text_padding = ConfigValue("plugin:hy3:tabs:text_padding"); + static const auto col_active = ConfigValue("plugin:hy3:tabs:col.active"); + static const auto col_urgent = ConfigValue("plugin:hy3:tabs:col.urgent"); + static const auto col_inactive = ConfigValue("plugin:hy3:tabs:col.inactive"); + static const auto col_text_active = ConfigValue("plugin:hy3:tabs:col.text.active"); + static const auto col_text_urgent = ConfigValue("plugin:hy3:tabs:col.text.urgent"); + static const auto col_text_inactive = ConfigValue("plugin:hy3:tabs:col.text.inactive"); // clang-format on auto width = box.width; @@ -227,7 +227,7 @@ void Hy3TabBarEntry::prepareTexture(float scale, CBox& box) { if (*text_center) pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); - PangoFontDescription* font_desc = pango_font_description_from_string(text_font->c_str()); + PangoFontDescription* font_desc = pango_font_description_from_string(*text_font); pango_font_description_set_size(font_desc, *text_height * scale * PANGO_SCALE); pango_layout_set_font_description(layout, font_desc); pango_font_description_free(font_desc); @@ -452,10 +452,9 @@ Hy3TabGroup::Hy3TabGroup(Hy3Node& node) { } void Hy3TabGroup::updateWithGroup(Hy3Node& node, bool warp) { - static const auto* gaps_in = &HyprlandAPI::getConfigValue(PHANDLE, "general:gaps_in")->intValue; - static const auto* gaps_out = &HyprlandAPI::getConfigValue(PHANDLE, "general:gaps_out")->intValue; - static const auto* bar_height = - &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:height")->intValue; + static const auto gaps_in = ConfigValue("general:gaps_in"); + static const auto gaps_out = ConfigValue("general:gaps_out"); + static const auto bar_height = ConfigValue("plugin:hy3:tabs:height"); auto gaps = node.parent == nullptr ? *gaps_out : *gaps_in; auto tpos = node.position + Vector2D(gaps, gaps) + node.gap_topleft_offset; @@ -484,10 +483,8 @@ void Hy3TabGroup::updateWithGroup(Hy3Node& node, bool warp) { } void Hy3TabGroup::tick() { - static const auto* enter_from_top = - &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:from_top")->intValue; - static const auto* padding = - &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:padding")->intValue; + static const auto enter_from_top = ConfigValue("plugin:hy3:tabs:from_top"); + static const auto padding = ConfigValue("plugin:hy3:tabs:padding"); auto* workspace = g_pCompositor->getWorkspaceByID(this->workspace_id); this->bar.tick(); @@ -528,12 +525,9 @@ void Hy3TabGroup::tick() { } void Hy3TabGroup::renderTabBar() { - static const auto* window_rounding = - &HyprlandAPI::getConfigValue(PHANDLE, "decoration:rounding")->intValue; - static const auto* enter_from_top = - &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:from_top")->intValue; - static const auto* padding = - &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:padding")->intValue; + static const auto window_rounding = ConfigValue("decoration:rounding"); + static const auto enter_from_top = ConfigValue("plugin:hy3:tabs:from_top"); + static const auto padding = ConfigValue("plugin:hy3:tabs:padding"); auto* monitor = g_pHyprOpenGL->m_RenderData.pMonitor; auto* workspace = g_pCompositor->getWorkspaceByID(this->workspace_id); diff --git a/src/globals.hpp b/src/globals.hpp index f2032d9..fbaabe5 100644 --- a/src/globals.hpp +++ b/src/globals.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "Hy3Layout.hpp" #include "log.hpp" @@ -19,3 +20,24 @@ inline void errorNotif() { } ); } + +template +class ConfigValue { +public: + ConfigValue(const std::string& option) { + this->static_data_ptr = HyprlandAPI::getConfigValue(PHANDLE, option)->getDataStaticPtr(); + } + + const T& get() const { return *(T*) *this->static_data_ptr; } + + const T& operator*() const { return this->get(); } + +private: + void* const* static_data_ptr; +}; + +// Bullshit undocumented microptimization case for strings +template <> +inline const Hyprlang::STRING& ConfigValue::get() const { + return *(char* const*) this->static_data_ptr; +} diff --git a/src/main.cpp b/src/main.cpp index 249e14c..a7f69a9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,3 @@ -#include -#include - #include #include #include @@ -30,37 +27,41 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { selection_hook::init(); #define CONF(NAME, TYPE, VALUE) \ - HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:" NAME, SConfigValue {.TYPE##Value = VALUE}) + HyprlandAPI::addConfigValue( \ + PHANDLE, \ + "plugin:hy3:" NAME, \ + Hyprlang::CConfigValue((Hyprlang::TYPE) VALUE) \ + ) // general - CONF("no_gaps_when_only", int, 0); - CONF("node_collapse_policy", int, 2); - CONF("group_inset", int, 10); - CONF("tab_first_window", int, 0); + CONF("no_gaps_when_only", INT, 0); + CONF("node_collapse_policy", INT, 2); + CONF("group_inset", INT, 10); + CONF("tab_first_window", INT, 0); // tabs - CONF("tabs:height", int, 15); - CONF("tabs:padding", int, 5); - CONF("tabs:from_top", int, 0); - CONF("tabs:rounding", int, 3); - CONF("tabs:render_text", int, 1); - CONF("tabs:text_center", int, 0); - CONF("tabs:text_font", str, "Sans"); - CONF("tabs:text_height", int, 8); - CONF("tabs:text_padding", int, 3); - CONF("tabs:col.active", int, 0xff32b4ff); - CONF("tabs:col.urgent", int, 0xffff4f4f); - CONF("tabs:col.inactive", int, 0x80808080); - CONF("tabs:col.text.active", int, 0xff000000); - CONF("tabs:col.text.urgent", int, 0xff000000); - CONF("tabs:col.text.inactive", int, 0xff000000); + CONF("tabs:height", INT, 15); + CONF("tabs:padding", INT, 5); + CONF("tabs:from_top", INT, 0); + CONF("tabs:rounding", INT, 3); + CONF("tabs:render_text", INT, 1); + CONF("tabs:text_center", INT, 0); + CONF("tabs:text_font", STRING, "Sans"); + CONF("tabs:text_height", INT, 8); + CONF("tabs:text_padding", INT, 3); + CONF("tabs:col.active", INT, 0xff32b4ff); + CONF("tabs:col.urgent", INT, 0xffff4f4f); + CONF("tabs:col.inactive", INT, 0x80808080); + CONF("tabs:col.text.active", INT, 0xff000000); + CONF("tabs:col.text.urgent", INT, 0xff000000); + CONF("tabs:col.text.inactive", INT, 0xff000000); // autotiling - CONF("autotile:enable", int, 0); - CONF("autotile:ephemeral_groups", int, 1); - CONF("autotile:trigger_height", int, 0); - CONF("autotile:trigger_width", int, 0); - CONF("autotile:workspaces", str, "all"); + CONF("autotile:enable", INT, 0); + CONF("autotile:ephemeral_groups", INT, 1); + CONF("autotile:trigger_height", INT, 0); + CONF("autotile:trigger_width", INT, 0); + CONF("autotile:workspaces", STRING, "all"); #undef CONF From 1a4847456bf5365f7295b3ed57c6dbb5c0b1511b Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Sun, 18 Feb 2024 14:17:58 -0800 Subject: [PATCH 25/27] Update lockfile --- flake.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index bb5cb70..5fc180c 100644 --- a/flake.lock +++ b/flake.lock @@ -10,11 +10,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1707952083, - "narHash": "sha256-DYt7APLnlG28Cj+KigYtlQrQ1W6DcHw5z7QXW+RDpa4=", + "lastModified": 1708272248, + "narHash": "sha256-EMGPzNg9422NEoFJUfidRHPokX2+UWErX9qSghpfS/g=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "3a6451b6026a5f38987e61ee07b442910b5432f5", + "rev": "301b48b74087cc59753ffa144b215540e6f82831", "type": "github" }, "original": { @@ -56,11 +56,11 @@ ] }, "locked": { - "lastModified": 1707842572, - "narHash": "sha256-dYGkJycYJ0RjfkKE98XtppQukr6AHkR5bPJN0GsJeTI=", + "lastModified": 1708005943, + "narHash": "sha256-9TT3xk++LI5/SPYgjYX34xZ4ebR93c1uerIq+SE/ues=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "4a464738e2d12bf3a9735831f784969c7568a4af", + "rev": "aeb3e012adc7b3235335c540b214b82267c2b983", "type": "github" }, "original": { From f5fc457d6b510ad4eb07ba1e12ea8168085001ec Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Thu, 22 Feb 2024 18:09:50 -0800 Subject: [PATCH 26/27] Fix gaps config being read as an int (it is now a customtype) Fixes breakage introduced in hyprland/ddf022d61c63fb36b4abba392682772690c06b5c --- flake.lock | 14 +++++++------- src/Hy3Layout.cpp | 35 ++++++++++++++++++++++------------- src/Hy3Node.cpp | 31 +++++++++++++++---------------- src/TabGroup.cpp | 15 +++++++++------ src/globals.hpp | 40 +++++++++++++++++++++++++++++++--------- 5 files changed, 84 insertions(+), 51 deletions(-) diff --git a/flake.lock b/flake.lock index 5fc180c..0abb1d4 100644 --- a/flake.lock +++ b/flake.lock @@ -10,11 +10,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1708272248, - "narHash": "sha256-EMGPzNg9422NEoFJUfidRHPokX2+UWErX9qSghpfS/g=", + "lastModified": 1708650152, + "narHash": "sha256-OZUS5FED7KKAPpNaJYQr4BPGXQzGrDFgkKVg9U2aZh8=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "301b48b74087cc59753ffa144b215540e6f82831", + "rev": "8c3613632a6ccebf9fb797ec756ecfce99514eec", "type": "github" }, "original": { @@ -131,18 +131,18 @@ "flake": false, "locked": { "host": "gitlab.freedesktop.org", - "lastModified": 1706359063, - "narHash": "sha256-5HUTG0p+nCJv3cn73AmFHRZdfRV5AD5N43g8xAePSKM=", + "lastModified": 1708558866, + "narHash": "sha256-Mz6hCtommq7RQfcPnxLINigO4RYSNt23HeJHC6mVmWI=", "owner": "wlroots", "repo": "wlroots", - "rev": "00b869c1a96f300a8f25da95d624524895e0ddf2", + "rev": "0cb091f1a2d345f37d2ee445f4ffd04f7f4ec9e5", "type": "gitlab" }, "original": { "host": "gitlab.freedesktop.org", "owner": "wlroots", "repo": "wlroots", - "rev": "00b869c1a96f300a8f25da95d624524895e0ddf2", + "rev": "0cb091f1a2d345f37d2ee445f4ffd04f7f4ec9e5", "type": "gitlab" } }, diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index dde4c31..14b3c9b 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -543,13 +543,21 @@ void Hy3Layout::fullscreenRequestForWindow( // Copy of vaxry's massive hack // clang-format off - static const auto gaps_in = ConfigValue("general:gaps_in"); - static const auto gaps_out = ConfigValue("general:gaps_out"); + static const auto gaps_in = ConfigValue("general:gaps_in"); + static const auto gaps_out = ConfigValue("general:gaps_out"); // clang-format on - int outer_gaps = -(*gaps_in - *gaps_out); - auto gap_pos_offset = Vector2D(outer_gaps, outer_gaps); - auto gap_size_offset = Vector2D(outer_gaps * 2, outer_gaps * 2); + // clang-format off + auto gap_pos_offset = Vector2D( + -(gaps_in->left - gaps_out->left), + -(gaps_in->top - gaps_out->top) + ); + // clang-format on + + auto gap_size_offset = Vector2D( + -(gaps_in->left - gaps_out->left) + -(gaps_in->right - gaps_out->right), + -(gaps_in->top - gaps_out->top) + -(gaps_in->bottom - gaps_out->bottom) + ); Hy3Node fakeNode = { .data = window, @@ -1049,8 +1057,8 @@ bottom: Hy3Node* findTabBarAt(Hy3Node& node, Vector2D pos, Hy3Node** focused_node) { // clang-format off - static const auto gaps_in = ConfigValue("general:gaps_in"); - static const auto gaps_out = ConfigValue("general:gaps_out"); + static const auto gaps_in = ConfigValue("general:gaps_in"); + static const auto gaps_out = ConfigValue("general:gaps_out"); static const auto tab_bar_height = ConfigValue("plugin:hy3:tabs:height"); static const auto tab_bar_padding = ConfigValue("plugin:hy3:tabs:padding"); // clang-format on @@ -1058,9 +1066,9 @@ Hy3Node* findTabBarAt(Hy3Node& node, Vector2D pos, Hy3Node** focused_node) { auto inset = *tab_bar_height + *tab_bar_padding; if (node.parent == nullptr) { - inset += *gaps_out; + inset += gaps_out->left; } else { - inset += *gaps_in; + inset += gaps_in->left; } if (node.data.type == Hy3NodeType::Group) { @@ -1468,7 +1476,7 @@ void Hy3Layout::applyNodeDataToWindow(Hy3Node* node, bool no_animation) { } // clang-format off - static const auto gaps_in = ConfigValue("general:gaps_in"); + static const auto gaps_in = ConfigValue("general:gaps_in"); static const auto single_window_no_gaps = ConfigValue("plugin:hy3:no_gaps_when_only"); // clang-format on @@ -1517,9 +1525,10 @@ void Hy3Layout::applyNodeDataToWindow(Hy3Node* node, bool no_animation) { auto calcPos = window->m_vPosition; auto calcSize = window->m_vSize; - auto gaps_offset_topleft = Vector2D(*gaps_in, *gaps_in) + node->gap_topleft_offset; - auto gaps_offset_bottomright = Vector2D(*gaps_in * 2, *gaps_in * 2) - + node->gap_bottomright_offset + node->gap_topleft_offset; + auto gaps_offset_topleft = Vector2D(gaps_in->left, gaps_in->top) + node->gap_topleft_offset; + auto gaps_offset_bottomright = + Vector2D(gaps_in->left + gaps_in->right, gaps_in->top + gaps_in->bottom) + + node->gap_bottomright_offset + node->gap_topleft_offset; calcPos = calcPos + gaps_offset_topleft; calcSize = calcSize - gaps_offset_bottomright; diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp index 59264f2..5eed0fc 100644 --- a/src/Hy3Node.cpp +++ b/src/Hy3Node.cpp @@ -270,13 +270,25 @@ Hy3Node& Hy3Node::getExpandActor() { void Hy3Node::recalcSizePosRecursive(bool no_animation) { // clang-format off - static const auto gaps_in = ConfigValue("general:gaps_in"); - static const auto gaps_out = ConfigValue("general:gaps_out"); + static const auto gaps_in = ConfigValue("general:gaps_in"); + static const auto gaps_out = ConfigValue("general:gaps_out"); static const auto group_inset = ConfigValue("plugin:hy3:group_inset"); static const auto tab_bar_height = ConfigValue("plugin:hy3:tabs:height"); static const auto tab_bar_padding = ConfigValue("plugin:hy3:tabs:padding"); // clang-format on + // clang-format off + auto gap_topleft_offset = Vector2D( + -(gaps_in->left - gaps_out->left), + -(gaps_in->top - gaps_out->top) + ); + + auto gap_bottomright_offset = Vector2D( + -(gaps_in->right - gaps_out->right), + -(gaps_in->bottom - gaps_out->bottom) + ); + // clang-format on + if (this->data.type == Hy3NodeType::Window && this->data.as_window->m_bIsFullscreen) { auto* workspace = g_pCompositor->getWorkspaceByID(this->workspace_id); auto* monitor = g_pCompositor->getMonitorFromID(workspace->m_iMonitorID); @@ -287,11 +299,6 @@ void Hy3Node::recalcSizePosRecursive(bool no_animation) { return; } - int outer_gaps = -(*gaps_in - *gaps_out); - - auto gap_topleft_offset = Vector2D(outer_gaps, outer_gaps); - auto gap_bottomright_offset = Vector2D(outer_gaps, outer_gaps); - Hy3Node fake_node = { .data = this->data.as_window, .position = monitor->vecPosition + monitor->vecReservedTopLeft, @@ -305,15 +312,7 @@ void Hy3Node::recalcSizePosRecursive(bool no_animation) { return; } - int outer_gaps = 0; - Vector2D gap_topleft_offset; - Vector2D gap_bottomright_offset; - if (this->parent == nullptr) { - outer_gaps = -(*gaps_in - *gaps_out); - - gap_topleft_offset = Vector2D(outer_gaps, outer_gaps); - gap_bottomright_offset = Vector2D(outer_gaps, outer_gaps); - } else { + if (this->parent != nullptr) { gap_topleft_offset = this->gap_topleft_offset; gap_bottomright_offset = this->gap_bottomright_offset; } diff --git a/src/TabGroup.cpp b/src/TabGroup.cpp index b48a784..e7049fb 100644 --- a/src/TabGroup.cpp +++ b/src/TabGroup.cpp @@ -452,16 +452,19 @@ Hy3TabGroup::Hy3TabGroup(Hy3Node& node) { } void Hy3TabGroup::updateWithGroup(Hy3Node& node, bool warp) { - static const auto gaps_in = ConfigValue("general:gaps_in"); - static const auto gaps_out = ConfigValue("general:gaps_out"); + static const auto gaps_in = ConfigValue("general:gaps_in"); + static const auto gaps_out = ConfigValue("general:gaps_out"); static const auto bar_height = ConfigValue("plugin:hy3:tabs:height"); - auto gaps = node.parent == nullptr ? *gaps_out : *gaps_in; - auto tpos = node.position + Vector2D(gaps, gaps) + node.gap_topleft_offset; + auto& gaps = node.parent == nullptr ? gaps_out : gaps_in; + auto tpos = node.position + Vector2D(gaps->left, gaps->top) + node.gap_topleft_offset; + + // clang-format off auto tsize = Vector2D( - node.size.x - node.gap_bottomright_offset.x - node.gap_topleft_offset.x - gaps * 2, - *bar_height + node.size.x - node.gap_bottomright_offset.x - node.gap_topleft_offset.x - (gaps->left + gaps->right), + *bar_height ); + // clang-format on this->hidden = node.hidden; if (this->pos.goalv() != tpos) { diff --git a/src/globals.hpp b/src/globals.hpp index fbaabe5..48839ca 100644 --- a/src/globals.hpp +++ b/src/globals.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include #include @@ -21,23 +23,43 @@ inline void errorNotif() { ); } -template +class HyprlangUnspecifiedCustomType {}; + +// abandon hope all ye who enter here +template class ConfigValue { public: ConfigValue(const std::string& option) { this->static_data_ptr = HyprlandAPI::getConfigValue(PHANDLE, option)->getDataStaticPtr(); } - const T& get() const { return *(T*) *this->static_data_ptr; } + template + typename std::enable_if::value, const V&>::type + operator*() const { + return *(V*) ((Hyprlang::CUSTOMTYPE*) *this->static_data_ptr)->getData(); + } - const T& operator*() const { return this->get(); } + template + typename std::enable_if::value, const V*>::type + operator->() const { + return &**this; + } + + // Bullshit microptimization case for strings + template + typename std::enable_if::value, const char*>::type + operator*() const { + return *(const char**) this->static_data_ptr; + } + + template + typename std::enable_if< + !std::is_same::value && !std::is_same::value, + const T&>::type + operator*() const { + return *(T*) *this->static_data_ptr; + } private: void* const* static_data_ptr; }; - -// Bullshit undocumented microptimization case for strings -template <> -inline const Hyprlang::STRING& ConfigValue::get() const { - return *(char* const*) this->static_data_ptr; -} From 029a2001361d2a4cbbe7447968dee5d1b1880298 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Thu, 22 Feb 2024 18:11:12 -0800 Subject: [PATCH 27/27] Make sure debug info is kept for flake build --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index a250f37..570b3f6 100644 --- a/flake.nix +++ b/flake.nix @@ -10,7 +10,7 @@ packages = hyprlandSystems (system: pkgs: let hyprlandPackage = hyprland.packages.${system}.hyprland; in rec { - hy3 = hyprlandPackage.stdenv.mkDerivation { + hy3 = (pkgs.keepDebugInfo hyprlandPackage.stdenv).mkDerivation { pname = "hy3"; version = "0.1"; src = ./.;