From e920cb95e889ca36abdb35f34abc85778e09301c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 12 Sep 2023 23:39:40 +0100 Subject: [PATCH 1/9] allow restricting workspaces for autotiling --- src/Hy3Layout.cpp | 30 +++++++++++++++++++++++++++++- src/main.cpp | 1 + 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index e747037..b527cdc 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -1,3 +1,5 @@ +#include +#include #include #include @@ -14,6 +16,30 @@ std::unique_ptr urgentHookPtr std::unique_ptr tickHookPtr = std::make_unique(Hy3Layout::tickHook); +std::set getAutotileWorkspaces() { + std::set workspaces; + auto at_workspaces = HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:autotile:workspaces")->strValue; + + if (at_workspaces == "all") { + return workspaces; + } + + // split on space and comma + const std::regex regex { R"([\s,]+)" }; + const auto begin = std::regex_token_iterator(at_workspaces.begin(), at_workspaces.end(), regex, -1); + const auto end = std::regex_token_iterator(); + + for (auto s = begin; s != end; ++s) { + try { + workspaces.insert(std::stoi(*s)); + } catch (...) { + hy3_log(ERR, "autotile:workspaces: invalid workspace id: {}", (std::string) *s); + } + } + + return workspaces; +} + bool performContainment(Hy3Node& node, bool contained, CWindow* window) { if (node.data.type == Hy3NodeType::Group) { auto& group = node.data.as_group; @@ -163,11 +189,13 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window) { 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_workspaces = getAutotileWorkspaces(); // clang-format on auto& target_group = opening_into->data.as_group; if (*at_enable && opening_after != nullptr && target_group.children.size() > 1 - && target_group.layout != Hy3GroupLayout::Tabbed) + && target_group.layout != Hy3GroupLayout::Tabbed && + (at_workspaces.empty() || at_workspaces.contains(opening_into->workspace_id))) { auto is_horizontal = target_group.layout == Hy3GroupLayout::SplitH; auto trigger = is_horizontal ? *at_trigger_width : *at_trigger_height; diff --git a/src/main.cpp b/src/main.cpp index 5185f2e..138ec7f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,6 +43,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { CONF("autotile:ephemeral_groups", int, 1); CONF("autotile:trigger_height", int, 0); CONF("autotile:trigger_width", int, 0); + CONF("autotile:workspaces", str, "all"); #undef CONF From 5b91b0e151fa7ec1a3095bf1ada023df3360f8e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 13 Sep 2023 11:28:58 +0100 Subject: [PATCH 2/9] autotile: allow dynamically updating workspaces config --- src/Hy3Layout.cpp | 73 ++++++++++++++++++++++++++++------------------- src/Hy3Layout.hpp | 7 +++++ 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index b527cdc..bcf84d0 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -1,7 +1,7 @@ -#include -#include #include #include +#include +#include #include "globals.hpp" #include "Hy3Layout.hpp" @@ -16,30 +16,6 @@ std::unique_ptr urgentHookPtr std::unique_ptr tickHookPtr = std::make_unique(Hy3Layout::tickHook); -std::set getAutotileWorkspaces() { - std::set workspaces; - auto at_workspaces = HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:autotile:workspaces")->strValue; - - if (at_workspaces == "all") { - return workspaces; - } - - // split on space and comma - const std::regex regex { R"([\s,]+)" }; - const auto begin = std::regex_token_iterator(at_workspaces.begin(), at_workspaces.end(), regex, -1); - const auto end = std::regex_token_iterator(); - - for (auto s = begin; s != end; ++s) { - try { - workspaces.insert(std::stoi(*s)); - } catch (...) { - hy3_log(ERR, "autotile:workspaces: invalid workspace id: {}", (std::string) *s); - } - } - - return workspaces; -} - bool performContainment(Hy3Node& node, bool contained, CWindow* window) { if (node.data.type == Hy3NodeType::Group) { auto& group = node.data.as_group; @@ -189,13 +165,14 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window) { 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_workspaces = getAutotileWorkspaces(); // clang-format on + this->updateAtWorkspaces(); + auto& target_group = opening_into->data.as_group; if (*at_enable && opening_after != nullptr && target_group.children.size() > 1 - && target_group.layout != Hy3GroupLayout::Tabbed && - (at_workspaces.empty() || at_workspaces.contains(opening_into->workspace_id))) + && target_group.layout != Hy3GroupLayout::Tabbed + && this->shouldAtWorkspace(opening_into->workspace_id)) { auto is_horizontal = target_group.layout == Hy3GroupLayout::SplitH; auto trigger = is_horizontal ? *at_trigger_width : *at_trigger_height; @@ -1738,3 +1715,41 @@ Hy3Node* Hy3Layout::shiftOrGetFocus( return nullptr; } + +void Hy3Layout::updateAtWorkspaces() { + static const auto* at_raw_workspaces + = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:autotile:workspaces")->strValue; + + if (*at_raw_workspaces == this->at_raw_workspaces) { + return; + } + + this->at_raw_workspaces = *at_raw_workspaces; + this->at_workspaces.clear(); + + if (this->at_raw_workspaces == "all") { + return; + } + + // split on space and comma + const std::regex regex {R"([\s,]+)"}; + const auto begin = std::regex_token_iterator( + this->at_raw_workspaces.begin(), + this->at_raw_workspaces.end(), + regex, + -1 + ); + const auto end = std::regex_token_iterator(); + + for (auto s = begin; s != end; ++s) { + try { + this->at_workspaces.insert(std::stoi(*s)); + } catch (...) { + hy3_log(ERR, "autotile:workspaces: invalid workspace id: {}", (std::string) *s); + } + } +} + +bool Hy3Layout::shouldAtWorkspace(int workspace_id) { + return this->at_workspaces.empty() || this->at_workspaces.contains(workspace_id); +} diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp index f532f73..f701663 100644 --- a/src/Hy3Layout.hpp +++ b/src/Hy3Layout.hpp @@ -9,6 +9,7 @@ enum class GroupEphemeralityOption { }; #include +#include #include @@ -138,5 +139,11 @@ private: // nullptr. if once is true, only one group will be broken out of / into Hy3Node* shiftOrGetFocus(Hy3Node&, ShiftDirection, bool shift, bool once, bool visible); + void updateAtWorkspaces(); + bool shouldAtWorkspace(int); + + std::string at_raw_workspaces; + std::set at_workspaces; + friend struct Hy3Node; }; From 95d7fdb67c7c65f4d874748af2a1c323d58d5804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 13 Sep 2023 11:41:39 +0100 Subject: [PATCH 3/9] autotile: allow defining workspaces where autotiling isn't enabled --- src/Hy3Layout.cpp | 9 ++++++++- src/main.cpp | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index bcf84d0..eb63370 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -1751,5 +1751,12 @@ void Hy3Layout::updateAtWorkspaces() { } bool Hy3Layout::shouldAtWorkspace(int workspace_id) { - return this->at_workspaces.empty() || this->at_workspaces.contains(workspace_id); + static const auto* at_workspaces_except + = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:autotile:workspaces.except")->intValue; + + if (*at_workspaces_except) { + return !this->at_workspaces.empty() && !this->at_workspaces.contains(workspace_id); + } else { + return this->at_workspaces.empty() || this->at_workspaces.contains(workspace_id); + } } diff --git a/src/main.cpp b/src/main.cpp index 138ec7f..55afe9e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,6 +44,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { CONF("autotile:trigger_height", int, 0); CONF("autotile:trigger_width", int, 0); CONF("autotile:workspaces", str, "all"); + CONF("autotile:workspaces.except", int, 0); #undef CONF From b9e72a008aa5ee93577b98ed2b1db9f256a991ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 13 Sep 2023 11:47:08 +0100 Subject: [PATCH 4/9] update README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index e04bf79..51f7cfe 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,12 @@ 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 + workspaces = # default: all + + # if enabled only workspaces that are not in the list are autotiled + workspaces.except = # default: false } } } From 3737f8234baa2c735a3ad5ccb2f4e3cf6d57486e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Thu, 14 Sep 2023 11:28:44 +0100 Subject: [PATCH 5/9] autotile: different handling of except workspaces rule --- src/Hy3Layout.cpp | 21 ++++++++++++--------- src/Hy3Layout.hpp | 1 + src/main.cpp | 1 - 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index eb63370..7d4d26b 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -1731,15 +1731,21 @@ void Hy3Layout::updateAtWorkspaces() { return; } + this->at_workspaces_blacklist = this->at_raw_workspaces.rfind("not:", 0) == 0; + + const auto at_raw_workspaces_filtered = (this->at_workspaces_blacklist) + ? this->at_raw_workspaces.substr(4) + : this->at_raw_workspaces; + // split on space and comma const std::regex regex {R"([\s,]+)"}; - const auto begin = std::regex_token_iterator( - this->at_raw_workspaces.begin(), - this->at_raw_workspaces.end(), + const auto begin = std::sregex_token_iterator( + at_raw_workspaces_filtered.begin(), + at_raw_workspaces_filtered.end(), regex, -1 ); - const auto end = std::regex_token_iterator(); + const auto end = std::sregex_token_iterator(); for (auto s = begin; s != end; ++s) { try { @@ -1751,11 +1757,8 @@ void Hy3Layout::updateAtWorkspaces() { } bool Hy3Layout::shouldAtWorkspace(int workspace_id) { - static const auto* at_workspaces_except - = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:autotile:workspaces.except")->intValue; - - if (*at_workspaces_except) { - return !this->at_workspaces.empty() && !this->at_workspaces.contains(workspace_id); + if (this->at_workspaces_blacklist) { + return !this->at_workspaces.contains(workspace_id); } else { return this->at_workspaces.empty() || this->at_workspaces.contains(workspace_id); } diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp index f701663..a171c7e 100644 --- a/src/Hy3Layout.hpp +++ b/src/Hy3Layout.hpp @@ -143,6 +143,7 @@ private: bool shouldAtWorkspace(int); std::string at_raw_workspaces; + bool at_workspaces_blacklist; std::set at_workspaces; friend struct Hy3Node; diff --git a/src/main.cpp b/src/main.cpp index 55afe9e..138ec7f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,7 +44,6 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { CONF("autotile:trigger_height", int, 0); CONF("autotile:trigger_width", int, 0); CONF("autotile:workspaces", str, "all"); - CONF("autotile:workspaces.except", int, 0); #undef CONF From 1ce3e5943769b12c90ff63673877caea77d8da33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Thu, 14 Sep 2023 11:29:10 +0100 Subject: [PATCH 6/9] update README --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 51f7cfe..49f99bc 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,9 @@ plugin { 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 + # workspaces = not:1,2 # autotiling will be enabled on all workspaces except 1 and 2 workspaces = # default: all # if enabled only workspaces that are not in the list are autotiled From 94581fdacbfb6ec7936b4a99235bc86584f9f2da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Thu, 14 Sep 2023 11:30:20 +0100 Subject: [PATCH 7/9] remove workspaces.except from README --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 49f99bc..3e0b4ec 100644 --- a/README.md +++ b/README.md @@ -212,9 +212,6 @@ plugin { # workspaces = 1,2 # autotiling will only be enabled on workspaces 1 and 2 # workspaces = not:1,2 # autotiling will be enabled on all workspaces except 1 and 2 workspaces = # default: all - - # if enabled only workspaces that are not in the list are autotiled - workspaces.except = # default: false } } } From 191f3f676cabd039a6bb68a8c93591c28dfd785c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Fri, 22 Sep 2023 10:51:45 +0100 Subject: [PATCH 8/9] autotile: rename autotiling functions --- src/Hy3Layout.cpp | 8 ++++---- src/Hy3Layout.hpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index 7d4d26b..b70416b 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -167,12 +167,12 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window) { static const auto* at_trigger_height = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:autotile:trigger_height")->intValue; // clang-format on - this->updateAtWorkspaces(); + this->updateAutotileWorkspaces(); auto& target_group = opening_into->data.as_group; if (*at_enable && opening_after != nullptr && target_group.children.size() > 1 && target_group.layout != Hy3GroupLayout::Tabbed - && this->shouldAtWorkspace(opening_into->workspace_id)) + && this->shouldAutotileWorkspace(opening_into->workspace_id)) { auto is_horizontal = target_group.layout == Hy3GroupLayout::SplitH; auto trigger = is_horizontal ? *at_trigger_width : *at_trigger_height; @@ -1716,7 +1716,7 @@ Hy3Node* Hy3Layout::shiftOrGetFocus( return nullptr; } -void Hy3Layout::updateAtWorkspaces() { +void Hy3Layout::updateAutotileWorkspaces() { static const auto* at_raw_workspaces = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:autotile:workspaces")->strValue; @@ -1756,7 +1756,7 @@ void Hy3Layout::updateAtWorkspaces() { } } -bool Hy3Layout::shouldAtWorkspace(int workspace_id) { +bool Hy3Layout::shouldAutotileWorkspace(int workspace_id) { if (this->at_workspaces_blacklist) { return !this->at_workspaces.contains(workspace_id); } else { diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp index a171c7e..eacb275 100644 --- a/src/Hy3Layout.hpp +++ b/src/Hy3Layout.hpp @@ -139,8 +139,8 @@ private: // nullptr. if once is true, only one group will be broken out of / into Hy3Node* shiftOrGetFocus(Hy3Node&, ShiftDirection, bool shift, bool once, bool visible); - void updateAtWorkspaces(); - bool shouldAtWorkspace(int); + void updateAutotileWorkspaces(); + bool shouldAutotileWorkspace(int); std::string at_raw_workspaces; bool at_workspaces_blacklist; From a55ca43e21f595b833366b595931244154ce0452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Fri, 22 Sep 2023 11:00:31 +0100 Subject: [PATCH 9/9] autotile: pack fields into struct --- src/Hy3Layout.cpp | 30 +++++++++++++++--------------- src/Hy3Layout.hpp | 8 +++++--- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index b70416b..535ed08 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -1717,31 +1717,31 @@ Hy3Node* Hy3Layout::shiftOrGetFocus( } void Hy3Layout::updateAutotileWorkspaces() { - static const auto* at_raw_workspaces + static const auto* autotile_raw_workspaces = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:autotile:workspaces")->strValue; - if (*at_raw_workspaces == this->at_raw_workspaces) { + if (*autotile_raw_workspaces == this->autotile.raw_workspaces) { return; } - this->at_raw_workspaces = *at_raw_workspaces; - this->at_workspaces.clear(); + this->autotile.raw_workspaces = *autotile_raw_workspaces; + this->autotile.workspaces.clear(); - if (this->at_raw_workspaces == "all") { + if (this->autotile.raw_workspaces == "all") { return; } - this->at_workspaces_blacklist = this->at_raw_workspaces.rfind("not:", 0) == 0; + this->autotile.workspace_blacklist = this->autotile.raw_workspaces.rfind("not:", 0) == 0; - const auto at_raw_workspaces_filtered = (this->at_workspaces_blacklist) - ? this->at_raw_workspaces.substr(4) - : this->at_raw_workspaces; + const auto autotile_raw_workspaces_filtered = (this->autotile.workspace_blacklist) + ? this->autotile.raw_workspaces.substr(4) + : this->autotile.raw_workspaces; // split on space and comma const std::regex regex {R"([\s,]+)"}; const auto begin = std::sregex_token_iterator( - at_raw_workspaces_filtered.begin(), - at_raw_workspaces_filtered.end(), + autotile_raw_workspaces_filtered.begin(), + autotile_raw_workspaces_filtered.end(), regex, -1 ); @@ -1749,7 +1749,7 @@ void Hy3Layout::updateAutotileWorkspaces() { for (auto s = begin; s != end; ++s) { try { - this->at_workspaces.insert(std::stoi(*s)); + this->autotile.workspaces.insert(std::stoi(*s)); } catch (...) { hy3_log(ERR, "autotile:workspaces: invalid workspace id: {}", (std::string) *s); } @@ -1757,9 +1757,9 @@ void Hy3Layout::updateAutotileWorkspaces() { } bool Hy3Layout::shouldAutotileWorkspace(int workspace_id) { - if (this->at_workspaces_blacklist) { - return !this->at_workspaces.contains(workspace_id); + if (this->autotile.workspace_blacklist) { + return !this->autotile.workspaces.contains(workspace_id); } else { - return this->at_workspaces.empty() || this->at_workspaces.contains(workspace_id); + return this->autotile.workspaces.empty() || this->autotile.workspaces.contains(workspace_id); } } diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp index eacb275..e8dd753 100644 --- a/src/Hy3Layout.hpp +++ b/src/Hy3Layout.hpp @@ -142,9 +142,11 @@ private: void updateAutotileWorkspaces(); bool shouldAutotileWorkspace(int); - std::string at_raw_workspaces; - bool at_workspaces_blacklist; - std::set at_workspaces; + struct { + std::string raw_workspaces; + bool workspace_blacklist; + std::set workspaces; + } autotile; friend struct Hy3Node; };