diff --git a/include/modules/hyprland/language.hpp b/include/modules/hyprland/language.hpp index 64290f8..30789d0 100644 --- a/include/modules/hyprland/language.hpp +++ b/include/modules/hyprland/language.hpp @@ -18,12 +18,21 @@ class Language : public waybar::ALabel, public EventHandler { void onEvent(const std::string&) override; void initLanguage(); - std::string getShortFrom(const std::string&); + + struct Layout { + std::string full_name; + std::string short_name; + std::string variant; + std::string short_description; + }; + + auto getLayout(const std::string&) -> Layout; std::mutex mutex_; const Bar& bar_; util::JsonParser parser_; - std::string layoutName_; + + Layout layout_; }; } // namespace waybar::modules::hyprland diff --git a/man/waybar-hyprland-language.5.scd b/man/waybar-hyprland-language.5.scd index 4a4e175..3e92def 100644 --- a/man/waybar-hyprland-language.5.scd +++ b/man/waybar-hyprland-language.5.scd @@ -15,7 +15,7 @@ Addressed by *hyprland/language* *format*: ++ typeof: string ++ default: {} ++ - The format, how information should be displayed. On {} the currently selected language is displayed. + The format, how information should be displayed. *format-* ++ typeof: string++ @@ -26,12 +26,22 @@ Addressed by *hyprland/language* Specifies which keyboard to use from hyprctl devices output. Using the option that begins with "at-translated-set..." is recommended. +# FORMAT REPLACEMENTS + +*{short}*: Short name of layout (e.g. "us"). Equals to {}. + +*{shortDescription}*: Short description of layout (e.g. "en"). + +*{long}*: Long name of layout (e.g. "English (Dvorak)"). + +*{variant}*: Variant of layout (e.g. "dvorak"). + # EXAMPLES ``` "hyprland/language": { - "format": "Lang: {}" + "format": "Lang: {long}" "format-en": "AMERICA, HELL YEAH!" "format-tr": "As bayrakları" "keyboard-name": "at-translated-set-2-keyboard" diff --git a/src/modules/hyprland/language.cpp b/src/modules/hyprland/language.cpp index 622c28d..cfc24f8 100644 --- a/src/modules/hyprland/language.cpp +++ b/src/modules/hyprland/language.cpp @@ -6,7 +6,7 @@ #include -#include "modules/hyprland/backend.hpp" +#include "util/string.hpp" namespace waybar::modules::hyprland { @@ -37,9 +37,20 @@ Language::~Language() { auto Language::update() -> void { std::lock_guard lg(mutex_); + std::string layoutName = std::string{}; + if (config_.isMember("format-" + layout_.short_description)) { + const auto propName = "format-" + layout_.short_description; + layoutName = fmt::format(fmt::runtime(format_), config_[propName].asString()); + } else { + layoutName = trim(fmt::format(fmt::runtime(format_), fmt::arg("long", layout_.full_name), + fmt::arg("short", layout_.short_name), + fmt::arg("shortDescription", layout_.short_description), + fmt::arg("variant", layout_.variant))); + } + if (!format_.empty()) { label_.show(); - label_.set_markup(layoutName_); + label_.set_markup(layoutName); } else { label_.hide(); } @@ -57,18 +68,7 @@ void Language::onEvent(const std::string& ev) { layoutName = waybar::util::sanitize_string(layoutName); - const auto briefName = getShortFrom(layoutName); - - if (config_.isMember("format-" + briefName)) { - const auto propName = "format-" + briefName; - layoutName = fmt::format(fmt::runtime(format_), config_[propName].asString()); - } else { - layoutName = fmt::format(fmt::runtime(format_), layoutName); - } - - if (layoutName == layoutName_) return; - - layoutName_ = layoutName; + layout_ = getLayout(layoutName); spdlog::debug("hyprland language onevent with {}", layoutName); @@ -89,19 +89,9 @@ void Language::initLanguage() { searcher = waybar::util::sanitize_string(searcher); - auto layoutName = std::string{}; - const auto briefName = getShortFrom(searcher); + layout_ = getLayout(searcher); - if (config_.isMember("format-" + briefName)) { - const auto propName = "format-" + briefName; - layoutName = fmt::format(fmt::runtime(format_), config_[propName].asString()); - } else { - layoutName = fmt::format(fmt::runtime(format_), searcher); - } - - layoutName_ = layoutName; - - spdlog::debug("hyprland language initLanguage found {}", layoutName_); + spdlog::debug("hyprland language initLanguage found {}", layout_.full_name); dp.emit(); @@ -110,11 +100,10 @@ void Language::initLanguage() { } } -std::string Language::getShortFrom(const std::string& fullName) { +auto Language::getLayout(const std::string& fullName) -> Layout { const auto CONTEXT = rxkb_context_new(RXKB_CONTEXT_LOAD_EXOTIC_RULES); rxkb_context_parse_default_ruleset(CONTEXT); - std::string foundName = ""; rxkb_layout* layout = rxkb_layout_first(CONTEXT); while (layout) { std::string nameOfLayout = rxkb_layout_get_description(layout); @@ -124,16 +113,26 @@ std::string Language::getShortFrom(const std::string& fullName) { continue; } - std::string briefName = rxkb_layout_get_brief(layout); + auto name = std::string(rxkb_layout_get_name(layout)); + auto variant_ = rxkb_layout_get_variant(layout); + std::string variant = variant_ == nullptr ? "" : std::string(variant_); + + auto short_description_ = rxkb_layout_get_brief(layout); + std::string short_description = + short_description_ == nullptr ? "" : std::string(short_description_); + + Layout info = Layout{nameOfLayout, name, variant, short_description}; rxkb_context_unref(CONTEXT); - return briefName; + return info; } rxkb_context_unref(CONTEXT); - return ""; + spdlog::debug("hyprland language didn't find matching layout"); + + return Layout {"", "", "", ""}; } } // namespace waybar::modules::hyprland