From 18026582e2881ded62ea15bc85c3f306a5b3306e Mon Sep 17 00:00:00 2001 From: Ilia Bozhinov Date: Mon, 1 Apr 2024 15:09:24 +0300 Subject: [PATCH] activators: add extension type bindings (#66) Those are not parsed by wf-config, instead, Wayfire plugins determine their format. --- include/wayfire/config/types.hpp | 5 ++++ src/types.cpp | 43 +++++++++++++++++++++++++++++++- test/types_test.cpp | 7 +++++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/include/wayfire/config/types.hpp b/include/wayfire/config/types.hpp index 1f24b9f..991c92b 100644 --- a/include/wayfire/config/types.hpp +++ b/include/wayfire/config/types.hpp @@ -444,6 +444,11 @@ struct activatorbinding_t */ const std::vector& get_hotspots() const; + /** + * @return A list of all unknown bindings which activate this binding. + */ + const std::vector& get_extensions() const; + /** * Check equality of two activator bindings. * diff --git a/src/types.cpp b/src/types.cpp index 1ca665d..4906b78 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -753,6 +753,7 @@ struct wf::activatorbinding_t::impl std::vector buttons; std::vector gestures; std::vector hotspots; + std::vector extensions; }; wf::activatorbinding_t::activatorbinding_t() @@ -792,6 +793,21 @@ bool try_add_binding( return false; } +static std::string filter_trailing_leading(std::string token) +{ + while (!token.empty() && token.back() == ' ') + { + token.pop_back(); + } + + while (!token.empty() && token.front() == ' ') + { + token.erase(token.begin()); + } + + return token; +} + template<> std::optional wf::option_type::from_string( const std::string& string) @@ -806,6 +822,13 @@ std::optional wf::option_type::from_string( auto tokens = split_at(string, "|", true); for (auto& token : tokens) { + const bool only_whitespace = std::all_of(token.begin(), token.end(), + [] (char c) { return std::isspace(c); }); + if (only_whitespace) + { + return {}; + } + bool is_valid_binding = try_add_binding(binding.priv->keys, token) || try_add_binding(binding.priv->buttons, token) || @@ -814,7 +837,7 @@ std::optional wf::option_type::from_string( if (!is_valid_binding) { - return {}; + binding.priv->extensions.push_back(filter_trailing_leading(token)); } } @@ -877,12 +900,30 @@ bool wf::activatorbinding_t::has_match(const touchgesture_t& gesture) const bool wf::activatorbinding_t::operator ==(const activatorbinding_t& other) const { + if (other.get_extensions().size() != this->get_extensions().size()) + { + return false; + } + + for (size_t i = 0; i < other.get_extensions().size(); i++) + { + if (other.get_extensions()[i] != this->get_extensions()[i]) + { + return false; + } + } + return priv->keys == other.priv->keys && priv->buttons == other.priv->buttons && priv->gestures == other.priv->gestures && priv->hotspots == other.priv->hotspots; } +const std::vector& wf::activatorbinding_t::get_extensions() const +{ + return priv->extensions; +} + const std::vector& wf::activatorbinding_t::get_hotspots() const { diff --git a/test/types_test.cpp b/test/types_test.cpp index a2ae978..92a322c 100644 --- a/test/types_test.cpp +++ b/test/types_test.cpp @@ -401,8 +401,13 @@ TEST_CASE("wf::activatorbinding_t") 0, 1); CHECK(!from_string(" KEY_K || KEY_U")); - CHECK(!from_string(" KEY_K | thrash")); CHECK(!from_string(" KEY_K |")); + + auto with_ext = from_string(" KEY_T | thrash"); + CHECK(with_ext.has_value() == true); + CHECK(with_ext->get_extensions().size() == 1); + CHECK(with_ext->get_extensions().front() == "thrash"); + CHECK(with_ext->has_match(kb1)); } TEST_CASE("wf::output_config::mode_t")