From 16d5619f3b19505c7d565ecb572259c6aaf1fdec Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 18 Aug 2022 18:00:27 +0200 Subject: [PATCH 01/12] added a basic hyprland/language module --- include/factory.hpp | 1 + include/modules/hyprland/language.hpp | 28 ++++++++ meson.build | 1 + src/factory.cpp | 3 + src/modules/hyprland/language.cpp | 97 +++++++++++++++++++++++++++ 5 files changed, 130 insertions(+) create mode 100644 include/modules/hyprland/language.hpp create mode 100644 src/modules/hyprland/language.cpp diff --git a/include/factory.hpp b/include/factory.hpp index 47ef530b..3c90ef18 100644 --- a/include/factory.hpp +++ b/include/factory.hpp @@ -24,6 +24,7 @@ #ifdef HAVE_HYPRLAND #include "modules/hyprland/backend.hpp" #include "modules/hyprland/window.hpp" +#include "modules/hyprland/language.hpp" #endif #if defined(__linux__) && !defined(NO_FILESYSTEM) #include "modules/battery.hpp" diff --git a/include/modules/hyprland/language.hpp b/include/modules/hyprland/language.hpp new file mode 100644 index 00000000..b8afc9c6 --- /dev/null +++ b/include/modules/hyprland/language.hpp @@ -0,0 +1,28 @@ +#include + +#include "ALabel.hpp" +#include "bar.hpp" +#include "modules/hyprland/backend.hpp" +#include "util/json.hpp" + +namespace waybar::modules::hyprland { + +class Language : public waybar::ALabel { +public: + Language(const std::string&, const waybar::Bar&, const Json::Value&); + ~Language() = default; + + auto update() -> void; + +private: + void onEvent(const std::string&); + + void initLanguage(); + + std::mutex mutex_; + const Bar& bar_; + util::JsonParser parser_; + std::string layoutName_; +}; + +} \ No newline at end of file diff --git a/meson.build b/meson.build index 3c320068..5ab0dcc1 100644 --- a/meson.build +++ b/meson.build @@ -205,6 +205,7 @@ if true add_project_arguments('-DHAVE_HYPRLAND', language: 'cpp') src_files += 'src/modules/hyprland/backend.cpp' src_files += 'src/modules/hyprland/window.cpp' + src_files += 'src/modules/hyprland/language.cpp' endif if libnl.found() and libnlgen.found() diff --git a/src/factory.cpp b/src/factory.cpp index 6df69d5c..c50bcf5c 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -61,6 +61,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const { if (ref == "hyprland/window") { return new waybar::modules::hyprland::Window(id, bar_, config_[name]); } + if (ref == "hyprland/language") { + return new waybar::modules::hyprland::Language(id, bar_, config_[name]); + } #endif if (ref == "idle_inhibitor") { return new waybar::modules::IdleInhibitor(id, bar_, config_[name]); diff --git a/src/modules/hyprland/language.cpp b/src/modules/hyprland/language.cpp new file mode 100644 index 00000000..31ac855d --- /dev/null +++ b/src/modules/hyprland/language.cpp @@ -0,0 +1,97 @@ +#include "modules/hyprland/language.hpp" + +#include + +#include "modules/hyprland/backend.hpp" + +namespace waybar::modules::hyprland { + +Language::Language(const std::string& id, const Bar& bar, const Json::Value& config) + : ALabel(config, "language", id, "{}", 0, true), bar_(bar) { + modulesReady = true; + + if (!gIPC.get()) { + gIPC = std::make_unique(); + } + + // get the active layout when open + initLanguage(); + + label_.hide(); + ALabel::update(); + + // register for hyprland ipc + gIPC->registerForIPC("activelayout", [&](const std::string& ev) { this->onEvent(ev); }); +} + +auto Language::update() -> void { + // fix ampersands + std::lock_guard lg(mutex_); + + if (!format_.empty()) { + label_.show(); + label_.set_markup(fmt::format(format_, layoutName_)); + } else { + label_.hide(); + } + + ALabel::update(); +} + +void Language::onEvent(const std::string& ev) { + std::lock_guard lg(mutex_); + auto layoutName = ev.substr(ev.find_last_of(',') + 1); + auto keebName = ev.substr(0, ev.find_last_of(',')); + keebName = keebName.substr(keebName.find_first_of('>') + 2); + + if (config_.isMember("keyboard-name") && keebName != config_["keyboard-name"].asString()) + return; // ignore + + auto replaceAll = [](std::string str, const std::string& from, + const std::string& to) -> std::string { + size_t start_pos = 0; + while ((start_pos = str.find(from, start_pos)) != std::string::npos) { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); + } + return str; + }; + + layoutName = replaceAll(layoutName, "&", "&"); + + if (layoutName == layoutName_) return; + + layoutName_ = layoutName; + + spdlog::debug("hyprland language onevent with {}", layoutName); + + dp.emit(); +} + +void Language::initLanguage() { + const auto INPUTDEVICES = gIPC->getSocket1Reply("devices"); + + if (!config_.isMember("keyboard-name")) + return; + + const auto KEEBNAME = config_["keyboard-name"].asString(); + + try { + + auto searcher = INPUTDEVICES.substr(INPUTDEVICES.find(KEEBNAME) + KEEBNAME.length()); + searcher = searcher.substr(searcher.find("Keyboard at")); + searcher = searcher.substr(searcher.find("keymap:") + 7); + searcher = searcher.substr(0, searcher.find_first_of("\n\t")); + + layoutName_ = searcher; + + spdlog::debug("hyprland language initLanguage found {}", layoutName_); + + dp.emit(); + + } catch (std::exception& e) { + spdlog::error("hyprland language initLanguage failed with {}", e.what()); + } +} + +} // namespace waybar::modules::hyprland \ No newline at end of file From a23d58e9001af4408450d394d2c02b4344aa70f2 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 18 Aug 2022 18:04:39 +0200 Subject: [PATCH 02/12] fix linter --- src/modules/hyprland/language.cpp | 32 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/modules/hyprland/language.cpp b/src/modules/hyprland/language.cpp index 31ac855d..f5dd767b 100644 --- a/src/modules/hyprland/language.cpp +++ b/src/modules/hyprland/language.cpp @@ -45,7 +45,7 @@ void Language::onEvent(const std::string& ev) { keebName = keebName.substr(keebName.find_first_of('>') + 2); if (config_.isMember("keyboard-name") && keebName != config_["keyboard-name"].asString()) - return; // ignore + return; // ignore auto replaceAll = [](std::string str, const std::string& from, const std::string& to) -> std::string { @@ -69,29 +69,29 @@ void Language::onEvent(const std::string& ev) { } void Language::initLanguage() { - const auto INPUTDEVICES = gIPC->getSocket1Reply("devices"); + const auto INPUTDEVICES = gIPC->getSocket1Reply("devices"); - if (!config_.isMember("keyboard-name")) - return; + if (!config_.isMember("keyboard-name")) + return; - const auto KEEBNAME = config_["keyboard-name"].asString(); + const auto KEEBNAME = config_["keyboard-name"].asString(); - try { + try { - auto searcher = INPUTDEVICES.substr(INPUTDEVICES.find(KEEBNAME) + KEEBNAME.length()); - searcher = searcher.substr(searcher.find("Keyboard at")); - searcher = searcher.substr(searcher.find("keymap:") + 7); - searcher = searcher.substr(0, searcher.find_first_of("\n\t")); + auto searcher = INPUTDEVICES.substr(INPUTDEVICES.find(KEEBNAME) + KEEBNAME.length()); + searcher = searcher.substr(searcher.find("Keyboard at")); + searcher = searcher.substr(searcher.find("keymap:") + 7); + searcher = searcher.substr(0, searcher.find_first_of("\n\t")); - layoutName_ = searcher; + layoutName_ = searcher; - spdlog::debug("hyprland language initLanguage found {}", layoutName_); + spdlog::debug("hyprland language initLanguage found {}", layoutName_); - dp.emit(); + dp.emit(); - } catch (std::exception& e) { - spdlog::error("hyprland language initLanguage failed with {}", e.what()); - } + } catch (std::exception& e) { + spdlog::error("hyprland language initLanguage failed with {}", e.what()); + } } } // namespace waybar::modules::hyprland \ No newline at end of file From e8942feefc1b3231ceef74cd7db705f41d4a2dfd Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 18 Aug 2022 18:05:40 +0200 Subject: [PATCH 03/12] fix linter more --- src/modules/hyprland/language.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/modules/hyprland/language.cpp b/src/modules/hyprland/language.cpp index f5dd767b..7daf64d9 100644 --- a/src/modules/hyprland/language.cpp +++ b/src/modules/hyprland/language.cpp @@ -71,8 +71,7 @@ void Language::onEvent(const std::string& ev) { void Language::initLanguage() { const auto INPUTDEVICES = gIPC->getSocket1Reply("devices"); - if (!config_.isMember("keyboard-name")) - return; + if (!config_.isMember("keyboard-name")) return; const auto KEEBNAME = config_["keyboard-name"].asString(); From 8881b9a6ef7181c62cf55c585222efaeb5d06e7c Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 18 Aug 2022 18:06:34 +0200 Subject: [PATCH 04/12] fix linter the most --- src/modules/hyprland/language.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/modules/hyprland/language.cpp b/src/modules/hyprland/language.cpp index 7daf64d9..7006a95f 100644 --- a/src/modules/hyprland/language.cpp +++ b/src/modules/hyprland/language.cpp @@ -76,7 +76,6 @@ void Language::initLanguage() { const auto KEEBNAME = config_["keyboard-name"].asString(); try { - auto searcher = INPUTDEVICES.substr(INPUTDEVICES.find(KEEBNAME) + KEEBNAME.length()); searcher = searcher.substr(searcher.find("Keyboard at")); searcher = searcher.substr(searcher.find("keymap:") + 7); From b8a68b8085297d7a715e7be0ce1d1087cb8ebcd4 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Thu, 18 Aug 2022 19:32:26 +0300 Subject: [PATCH 05/12] man documentation for hl language module --- man/waybar-hyprland-language.5.scd | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 man/waybar-hyprland-language.5.scd diff --git a/man/waybar-hyprland-language.5.scd b/man/waybar-hyprland-language.5.scd new file mode 100644 index 00000000..cdd0a931 --- /dev/null +++ b/man/waybar-hyprland-language.5.scd @@ -0,0 +1,36 @@ +waybar-hyprland-language(5) + +# NAME + +waybar - hyprland language module + +# DESCRIPTION + +The *language* module displays the currently selected language. + +# CONFIGURATION + +Addressed by *hyprland/language* + +*format*: ++ + typeof: string ++ + default: {} ++ + The format, how information should be displayed. On {} the currently selected language is displayed. + +*keyboard-name*: ++ + typeof: string ++ + Specifies which keyboard to use from *hyprctl devices* output. Using the option that begins with "AT Translated set..." is recommended. + + +# EXAMPLES + +``` +"hyprland/language": { + "format": "Lang: {}" + "keyboard-name": "AT Translated Set 2 keyboard" +} +``` + +# STYLE + +- *#language* From 97f0d6fa4285249ed236eb78d87a8f8b43dd2d11 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Thu, 18 Aug 2022 19:35:40 +0300 Subject: [PATCH 06/12] remove redundant formatting --- man/waybar-hyprland-language.5.scd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/waybar-hyprland-language.5.scd b/man/waybar-hyprland-language.5.scd index cdd0a931..19a150ce 100644 --- a/man/waybar-hyprland-language.5.scd +++ b/man/waybar-hyprland-language.5.scd @@ -19,7 +19,7 @@ Addressed by *hyprland/language* *keyboard-name*: ++ typeof: string ++ - Specifies which keyboard to use from *hyprctl devices* output. Using the option that begins with "AT Translated set..." is recommended. + Specifies which keyboard to use from hyprctl devices output. Using the option that begins with "AT Translated set..." is recommended. # EXAMPLES From 43c3ca1d38112ce684567ba84488c9db3431605b Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 18 Aug 2022 18:59:34 +0200 Subject: [PATCH 07/12] added the thing i was talking about --- include/modules/hyprland/language.hpp | 1 + src/modules/hyprland/language.cpp | 39 ++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/include/modules/hyprland/language.hpp b/include/modules/hyprland/language.hpp index b8afc9c6..9e7193e2 100644 --- a/include/modules/hyprland/language.hpp +++ b/include/modules/hyprland/language.hpp @@ -18,6 +18,7 @@ private: void onEvent(const std::string&); void initLanguage(); + std::string getShortFrom(const std::string&); std::mutex mutex_; const Bar& bar_; diff --git a/src/modules/hyprland/language.cpp b/src/modules/hyprland/language.cpp index 7006a95f..067730d1 100644 --- a/src/modules/hyprland/language.cpp +++ b/src/modules/hyprland/language.cpp @@ -1,6 +1,8 @@ #include "modules/hyprland/language.hpp" #include +#include +#include #include "modules/hyprland/backend.hpp" @@ -30,7 +32,7 @@ auto Language::update() -> void { if (!format_.empty()) { label_.show(); - label_.set_markup(fmt::format(format_, layoutName_)); + label_.set_markup(layoutName_); } else { label_.hide(); } @@ -57,6 +59,15 @@ void Language::onEvent(const std::string& ev) { return str; }; + const auto BRIEFNAME = getShortFrom(layoutName); + + if (config_.isMember("format-" + BRIEFNAME)) { + const auto PROPNAME = "format-" + BRIEFNAME; + layoutName = fmt::format(format_, config_[PROPNAME].asString()); + } else { + layoutName = fmt::format(format_, layoutName); + } + layoutName = replaceAll(layoutName, "&", "&"); if (layoutName == layoutName_) return; @@ -92,4 +103,30 @@ void Language::initLanguage() { } } +std::string Language::getShortFrom(const std::string& fullName) { + 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); + + if (nameOfLayout != fullName) { + layout = rxkb_layout_next(layout); + continue; + } + + std::string briefName = rxkb_layout_get_brief(layout); + + rxkb_context_unref(CONTEXT); + + return briefName; + } + + rxkb_context_unref(CONTEXT); + + return ""; +} + } // namespace waybar::modules::hyprland \ No newline at end of file From ed6467e785c8a2cee39e1f45f63ac5c8921ce58d Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 18 Aug 2022 19:02:46 +0200 Subject: [PATCH 08/12] fix linter --- src/modules/hyprland/language.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/hyprland/language.cpp b/src/modules/hyprland/language.cpp index 067730d1..2ae4967c 100644 --- a/src/modules/hyprland/language.cpp +++ b/src/modules/hyprland/language.cpp @@ -1,8 +1,8 @@ #include "modules/hyprland/language.hpp" #include -#include #include +#include #include "modules/hyprland/backend.hpp" @@ -123,7 +123,7 @@ std::string Language::getShortFrom(const std::string& fullName) { return briefName; } - + rxkb_context_unref(CONTEXT); return ""; From b181cd04b6da08e1210de2926282b6be2ec3434e Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Thu, 18 Aug 2022 20:11:44 +0300 Subject: [PATCH 09/12] update man docs for format- option --- man/waybar-hyprland-language.5.scd | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/man/waybar-hyprland-language.5.scd b/man/waybar-hyprland-language.5.scd index 19a150ce..d3b31773 100644 --- a/man/waybar-hyprland-language.5.scd +++ b/man/waybar-hyprland-language.5.scd @@ -17,16 +17,23 @@ Addressed by *hyprland/language* default: {} ++ The format, how information should be displayed. On {} the currently selected language is displayed. +*format-* ++ + typeof: string++ + Provide an alternative name to display per language. + *keyboard-name*: ++ typeof: string ++ Specifies which keyboard to use from hyprctl devices output. Using the option that begins with "AT Translated set..." is recommended. + # EXAMPLES ``` "hyprland/language": { "format": "Lang: {}" + "format-us": "AMERICA, HELL YEAH!" + "format-tr": "As bayrakları" "keyboard-name": "AT Translated Set 2 keyboard" } ``` From 39c170bf10bcc6bb5b0a5723d4d5e69c45627a50 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 18 Aug 2022 19:13:24 +0200 Subject: [PATCH 10/12] remove one comment that I forgot to --- src/modules/hyprland/language.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/modules/hyprland/language.cpp b/src/modules/hyprland/language.cpp index 2ae4967c..5463508b 100644 --- a/src/modules/hyprland/language.cpp +++ b/src/modules/hyprland/language.cpp @@ -27,7 +27,6 @@ Language::Language(const std::string& id, const Bar& bar, const Json::Value& con } auto Language::update() -> void { - // fix ampersands std::lock_guard lg(mutex_); if (!format_.empty()) { From 40bc2e96db6a8708083a06134f45476d023d8d16 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Thu, 18 Aug 2022 20:21:14 +0300 Subject: [PATCH 11/12] wording --- man/waybar-hyprland-language.5.scd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/man/waybar-hyprland-language.5.scd b/man/waybar-hyprland-language.5.scd index d3b31773..cb169951 100644 --- a/man/waybar-hyprland-language.5.scd +++ b/man/waybar-hyprland-language.5.scd @@ -19,7 +19,7 @@ Addressed by *hyprland/language* *format-* ++ typeof: string++ - Provide an alternative name to display per language. + Provide an alternative name to display per language where is the language of your choosing. Can be passed multiple times with multiple languages as shown by the example below. *keyboard-name*: ++ typeof: string ++ @@ -32,8 +32,8 @@ Addressed by *hyprland/language* ``` "hyprland/language": { "format": "Lang: {}" - "format-us": "AMERICA, HELL YEAH!" - "format-tr": "As bayrakları" + "format-us": "AMERICA, HELL YEAH!" // For American English + "format-tr": "As bayrakları" // For Turkish "keyboard-name": "AT Translated Set 2 keyboard" } ``` From 4e930ba50a4c223aa4611369872ad11a1cd17f59 Mon Sep 17 00:00:00 2001 From: TheRealLorenz Date: Sat, 20 Aug 2022 22:21:57 +0200 Subject: [PATCH 12/12] Add 'max-volume' option to pulseaudio. Fixes #1607 --- man/waybar-pulseaudio.5.scd | 5 +++++ src/modules/pulseaudio.cpp | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/man/waybar-pulseaudio.5.scd b/man/waybar-pulseaudio.5.scd index 7de10281..07a0de80 100644 --- a/man/waybar-pulseaudio.5.scd +++ b/man/waybar-pulseaudio.5.scd @@ -96,6 +96,11 @@ Additionally you can control the volume by scrolling *up* or *down* while the cu default: true ++ Option to disable tooltip on hover. +*max-volume*: ++ + typeof: integer ++ + default: 100 ++ + The maximum volume that can be set, in percentage. + # FORMAT REPLACEMENTS *{desc}*: Pulseaudio port's description, for bluetooth it'll be the device name. diff --git a/src/modules/pulseaudio.cpp b/src/modules/pulseaudio.cpp index f6ff9591..24b858d3 100644 --- a/src/modules/pulseaudio.cpp +++ b/src/modules/pulseaudio.cpp @@ -90,12 +90,16 @@ bool waybar::modules::Pulseaudio::handleScroll(GdkEventScroll *e) { double volume_tick = static_cast(PA_VOLUME_NORM) / 100; pa_volume_t change = volume_tick; pa_cvolume pa_volume = pa_volume_; + int max_volume = 100; // isDouble returns true for integers as well, just in case if (config_["scroll-step"].isDouble()) { change = round(config_["scroll-step"].asDouble() * volume_tick); } + if (config_["max-volume"].isInt()) { + max_volume = std::min(0, config_["max-volume"].asInt()); + } if (dir == SCROLL_DIR::UP) { - if (volume_ + 1 <= 100) { + if (volume_ + 1 <= max_volume) { pa_cvolume_inc(&pa_volume, change); } } else if (dir == SCROLL_DIR::DOWN) {