From 587bd0cd628a3cc5c7a333acdba31a5503d1e2d4 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Fri, 8 Sep 2023 22:24:05 -0500 Subject: [PATCH 01/10] refactor: cleanup hyprland workspaces constructor --- include/modules/hyprland/workspaces.hpp | 2 ++ src/modules/hyprland/workspaces.cpp | 27 +++++++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index 270c1e36..93faf494 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -80,6 +80,8 @@ class Workspaces : public AModule, public EventHandler { void create_workspace(Json::Value& value); void remove_workspace(std::string name); void set_urgent_workspace(std::string windowaddress); + void parse_config(const Json::Value& config); + void register_ipc(); bool all_outputs_ = false; bool show_special_ = false; diff --git a/src/modules/hyprland/workspaces.cpp b/src/modules/hyprland/workspaces.cpp index 82442d53..504a6caa 100644 --- a/src/modules/hyprland/workspaces.cpp +++ b/src/modules/hyprland/workspaces.cpp @@ -14,6 +14,20 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value : AModule(config, "workspaces", id, false, false), bar_(bar), box_(bar.vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0) { + parse_config(config); + + box_.set_name("workspaces"); + if (!id.empty()) { + box_.get_style_context()->add_class(id); + } + event_box_.add(box_); + + register_ipc(); + + init(); +} + +auto Workspaces::parse_config(const Json::Value &config) -> void { Json::Value config_format = config["format"]; format_ = config_format.isString() ? config_format.asString() : "{name}"; @@ -43,18 +57,19 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value active_only_ = config_active_only.asBool(); } - box_.set_name("workspaces"); - if (!id.empty()) { - box_.get_style_context()->add_class(id); + auto config_sort_by = config_["sort-by"]; + if (config_sort_by.isString()) { + sort_by = config_sort_by.asString(); } - event_box_.add(box_); +} + +auto Workspaces::register_ipc() -> void { modulesReady = true; + if (!gIPC) { gIPC = std::make_unique(); } - init(); - gIPC->registerForIPC("workspace", this); gIPC->registerForIPC("createworkspace", this); gIPC->registerForIPC("destroyworkspace", this); From cbc12e544355e0df311c5e44216639970b7b72ab Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Fri, 8 Sep 2023 22:24:28 -0500 Subject: [PATCH 02/10] feat: hyprland workspaces add sort-by --- include/modules/hyprland/workspaces.hpp | 1 + man/waybar-hyprland-workspaces.5.scd | 8 +++ src/modules/hyprland/workspaces.cpp | 71 +++++++++++++++---------- 3 files changed, 53 insertions(+), 27 deletions(-) diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index 93faf494..3b8de4ae 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -86,6 +86,7 @@ class Workspaces : public AModule, public EventHandler { bool all_outputs_ = false; bool show_special_ = false; bool active_only_ = false; + std::string sort_by = "default"; void fill_persistent_workspaces(); void create_persistent_workspaces(); diff --git a/man/waybar-hyprland-workspaces.5.scd b/man/waybar-hyprland-workspaces.5.scd index 13764752..e0caf80f 100644 --- a/man/waybar-hyprland-workspaces.5.scd +++ b/man/waybar-hyprland-workspaces.5.scd @@ -36,6 +36,14 @@ Addressed by *hyprland/workspaces* default: false ++ If set to true, only the active workspace will be shown. +*sort-by*: ++ + typeof: string ++ + default: "default" ++ + If set to number, workspaces will sort by number. + If set to name, workspaces will sort by name. + If set to id, workspaces will sort by id. + If none of those, workspaces will sort with default behavior. + # FORMAT REPLACEMENTS *{id}*: id of workspace assigned by compositor diff --git a/src/modules/hyprland/workspaces.cpp b/src/modules/hyprland/workspaces.cpp index 504a6caa..517de1be 100644 --- a/src/modules/hyprland/workspaces.cpp +++ b/src/modules/hyprland/workspaces.cpp @@ -421,36 +421,53 @@ void Workspace::update(const std::string &format, const std::string &icon) { void Workspaces::sort_workspaces() { std::sort(workspaces_.begin(), workspaces_.end(), - [](std::unique_ptr &a, std::unique_ptr &b) { - // normal -> named persistent -> named -> special -> named special + [&](std::unique_ptr &a, std::unique_ptr &b) { + // Helper comparisons + auto is_id_less = a->id() < b->id(); + auto is_name_less = a->name() < b->name(); + auto is_number_less = std::stoi(a->name()) < std::stoi(b->name()); - // both normal (includes numbered persistent) => sort by ID - if (a->id() > 0 && b->id() > 0) { - return a->id() < b->id(); - } - - // one normal, one special => normal first - if ((a->is_special()) ^ (b->is_special())) { - return b->is_special(); - } - - // only one normal, one named - if ((a->id() > 0) ^ (b->id() > 0)) { - return a->id() > 0; - } - - // both special - if (a->is_special() && b->is_special()) { - // if one is -99 => put it last - if (a->id() == -99 || b->id() == -99) { - return b->id() == -99; + if (sort_by == "number") { + try { + return is_number_less; + } catch (const std::invalid_argument &) { } - // both are 0 (not yet named persistents) / both are named specials (-98 <= ID <=-1) - return a->name() < b->name(); - } + } else if (sort_by == "name") { + return is_name_less; + } else if (sort_by == "id") { + return is_id_less; + } else { + // normal -> named persistent -> named -> special -> named special - // sort non-special named workspaces by name (ID <= -1377) - return a->name() < b->name(); + // both normal (includes numbered persistent) => sort by ID + if (a->id() > 0 && b->id() > 0) { + return is_id_less; + } + + // one normal, one special => normal first + if ((a->is_special()) ^ (b->is_special())) { + return b->is_special(); + } + + // only one normal, one named + if ((a->id() > 0) ^ (b->id() > 0)) { + return a->id() > 0; + } + + // both special + if (a->is_special() && b->is_special()) { + // if one is -99 => put it last + if (a->id() == -99 || b->id() == -99) { + return b->id() == -99; + } + // both are 0 (not yet named persistents) / both are named specials (-98 <= ID + // <=-1) + return is_name_less; + } + + // sort non-special named workspaces by name (ID <= -1377) + return is_name_less; + } }); for (size_t i = 0; i < workspaces_.size(); ++i) { From 65ba449460bea5cd3a7008fe3777a76a0952d453 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Fri, 8 Sep 2023 23:17:21 -0500 Subject: [PATCH 03/10] chore: update man page index --- man/waybar.5.scd.in | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/man/waybar.5.scd.in b/man/waybar.5.scd.in index a8376697..92b365d9 100644 --- a/man/waybar.5.scd.in +++ b/man/waybar.5.scd.in @@ -273,28 +273,39 @@ Valid options for the (optional) "orientation" property are: "horizontal", "vert - *waybar-cpu(5)* - *waybar-custom(5)* - *waybar-disk(5)* +- *waybar-dwl-tags(5)* +- *waybar-gamemode(5)* +- *waybar-hyprland-language(5)* +- *waybar-hyprland-submap(5)* +- *waybar-hyprland-window(5)* +- *waybar-hyprland-workspaces(5)* - *waybar-idle-inhibitor(5)* - *waybar-image(5)* +- *waybar-inhibitor(5)* +- *waybar-jack(5)* - *waybar-keyboard-state(5)* - *waybar-memory(5)* - *waybar-mpd(5)* - *waybar-mpris(5)* - *waybar-network(5)* - *waybar-pulseaudio(5)* +- *waybar-river-layout(5)* - *waybar-river-mode(5)* - *waybar-river-tags(5)* - *waybar-river-window(5)* -- *waybar-river-layout(5)* +- *waybar-sndio(5)* - *waybar-states(5)* +- *waybar-sway-language(5)* - *waybar-sway-mode(5)* - *waybar-sway-scratchpad(5)* - *waybar-sway-window(5)* - *waybar-sway-workspaces(5)* +- *waybar-temperature(5)* +- *waybar-tray(5)* +- *waybar-upower(5)* - *waybar-wireplumber(5)* - *waybar-wlr-taskbar(5)* - *waybar-wlr-workspaces(5)* -- *waybar-temperature(5)* -- *waybar-tray(5)* # SEE ALSO From 8ea2626de8058348a36f752da4a2c1fafa05a538 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Sat, 9 Sep 2023 09:32:55 -0500 Subject: [PATCH 04/10] refactor: sort-by enum hyprland --- include/modules/hyprland/workspaces.hpp | 4 +- include/util/enum.hpp | 28 ++++++++ src/modules/hyprland/workspaces.cpp | 92 +++++++++++++++---------- 3 files changed, 85 insertions(+), 39 deletions(-) create mode 100644 include/util/enum.hpp diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index 3b8de4ae..9cd17f88 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -11,6 +11,7 @@ #include "AModule.hpp" #include "bar.hpp" #include "modules/hyprland/backend.hpp" +#include "util/enum.hpp" namespace waybar::modules::hyprland { @@ -86,7 +87,8 @@ class Workspaces : public AModule, public EventHandler { bool all_outputs_ = false; bool show_special_ = false; bool active_only_ = false; - std::string sort_by = "default"; + util::EnumParser enum_parser_; + util::EnumParser::SORT_METHOD sort_by_ = util::EnumParser::SORT_METHOD::DEFAULT; void fill_persistent_workspaces(); void create_persistent_workspaces(); diff --git a/include/util/enum.hpp b/include/util/enum.hpp new file mode 100644 index 00000000..a1cb6f6c --- /dev/null +++ b/include/util/enum.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include + +namespace waybar::util { + +struct EnumParser { + EnumParser() {} + + enum SORT_METHOD { ID, NAME, NUMBER, DEFAULT }; + + SORT_METHOD sortStringToEnum(const std::string& str) { + static const std::map enumMap = { + {"ID", ID}, {"NAME", NAME}, {"NUMBER", NUMBER}, {"DEFAULT", DEFAULT}}; + + auto it = enumMap.find(str); + if (it != enumMap.end()) { + return it->second; + } else { + throw std::invalid_argument("Invalid string representation for enum"); + } + } + + ~EnumParser() = default; +}; +} // namespace waybar::util diff --git a/src/modules/hyprland/workspaces.cpp b/src/modules/hyprland/workspaces.cpp index 517de1be..9eda2c39 100644 --- a/src/modules/hyprland/workspaces.cpp +++ b/src/modules/hyprland/workspaces.cpp @@ -59,7 +59,14 @@ auto Workspaces::parse_config(const Json::Value &config) -> void { auto config_sort_by = config_["sort-by"]; if (config_sort_by.isString()) { - sort_by = config_sort_by.asString(); + auto sort_by_str = config_sort_by.asString(); + try { + sort_by_ = enum_parser_.sortStringToEnum(sort_by_str); + } catch (const std::invalid_argument &e) { + // Handle the case where the string is not a valid enum representation. + sort_by_ = util::EnumParser::SORT_METHOD::DEFAULT; + g_warning("Invalid string representation for sort-by. Falling back to default sort method."); + } } } @@ -427,47 +434,56 @@ void Workspaces::sort_workspaces() { auto is_name_less = a->name() < b->name(); auto is_number_less = std::stoi(a->name()) < std::stoi(b->name()); - if (sort_by == "number") { - try { - return is_number_less; - } catch (const std::invalid_argument &) { - } - } else if (sort_by == "name") { - return is_name_less; - } else if (sort_by == "id") { - return is_id_less; - } else { - // normal -> named persistent -> named -> special -> named special - - // both normal (includes numbered persistent) => sort by ID - if (a->id() > 0 && b->id() > 0) { + switch (sort_by_) { + case util::EnumParser::SORT_METHOD::ID: return is_id_less; - } - - // one normal, one special => normal first - if ((a->is_special()) ^ (b->is_special())) { - return b->is_special(); - } - - // only one normal, one named - if ((a->id() > 0) ^ (b->id() > 0)) { - return a->id() > 0; - } - - // both special - if (a->is_special() && b->is_special()) { - // if one is -99 => put it last - if (a->id() == -99 || b->id() == -99) { - return b->id() == -99; - } - // both are 0 (not yet named persistents) / both are named specials (-98 <= ID - // <=-1) + case util::EnumParser::SORT_METHOD::NAME: return is_name_less; - } + case util::EnumParser::SORT_METHOD::NUMBER: + try { + return is_number_less; + } catch (const std::invalid_argument &) { + // Handle the exception if necessary. + break; + } + case util::EnumParser::SORT_METHOD::DEFAULT: + default: + // Handle the default case here. + // normal -> named persistent -> named -> special -> named special - // sort non-special named workspaces by name (ID <= -1377) - return is_name_less; + // both normal (includes numbered persistent) => sort by ID + if (a->id() > 0 && b->id() > 0) { + return is_id_less; + } + + // one normal, one special => normal first + if ((a->is_special()) ^ (b->is_special())) { + return b->is_special(); + } + + // only one normal, one named + if ((a->id() > 0) ^ (b->id() > 0)) { + return a->id() > 0; + } + + // both special + if (a->is_special() && b->is_special()) { + // if one is -99 => put it last + if (a->id() == -99 || b->id() == -99) { + return b->id() == -99; + } + // both are 0 (not yet named persistents) / both are named specials (-98 <= ID + // <=-1) + return is_name_less; + } + + // sort non-special named workspaces by name (ID <= -1377) + return is_name_less; + break; } + + // Return a default value if none of the cases match. + return is_name_less; // You can adjust this to your specific needs. }); for (size_t i = 0; i < workspaces_.size(); ++i) { From 8ce64ea784ca3345735cef7de9464583abd965dc Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Sat, 9 Sep 2023 09:38:03 -0500 Subject: [PATCH 05/10] refactor: make parsing sort-by more lenient --- include/util/enum.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/util/enum.hpp b/include/util/enum.hpp index a1cb6f6c..dcf0e45c 100644 --- a/include/util/enum.hpp +++ b/include/util/enum.hpp @@ -12,10 +12,16 @@ struct EnumParser { enum SORT_METHOD { ID, NAME, NUMBER, DEFAULT }; SORT_METHOD sortStringToEnum(const std::string& str) { + // Convert the input string to uppercase (make it lenient on config input) + std::string uppercaseStr; + for (char c : str) { + uppercaseStr += std::toupper(c); + } + static const std::map enumMap = { {"ID", ID}, {"NAME", NAME}, {"NUMBER", NUMBER}, {"DEFAULT", DEFAULT}}; - auto it = enumMap.find(str); + auto it = enumMap.find(uppercaseStr); if (it != enumMap.end()) { return it->second; } else { From 2b8c92e8fdbe98282a625741abf8d9b21f8b969f Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Sat, 9 Sep 2023 11:18:12 -0500 Subject: [PATCH 06/10] refactor: enum utility allow overriding --- include/modules/hyprland/workspaces.hpp | 10 ++++++++-- include/util/enum.hpp | 15 +++++++-------- src/modules/hyprland/workspaces.cpp | 12 ++++++------ 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index 9cd17f88..7c4d919e 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -87,8 +87,14 @@ class Workspaces : public AModule, public EventHandler { bool all_outputs_ = false; bool show_special_ = false; bool active_only_ = false; - util::EnumParser enum_parser_; - util::EnumParser::SORT_METHOD sort_by_ = util::EnumParser::SORT_METHOD::DEFAULT; + + enum SORT_METHOD { ID, NAME, NUMBER, DEFAULT }; + util::EnumParser enum_parser_; + SORT_METHOD sort_by_ = SORT_METHOD::DEFAULT; + std::map sort_map_ = {{"ID", SORT_METHOD::ID}, + {"NAME", SORT_METHOD::NAME}, + {"NUMBER", SORT_METHOD::NUMBER}, + {"DEFAULT", SORT_METHOD::DEFAULT}}; void fill_persistent_workspaces(); void create_persistent_workspaces(); diff --git a/include/util/enum.hpp b/include/util/enum.hpp index dcf0e45c..7ee80694 100644 --- a/include/util/enum.hpp +++ b/include/util/enum.hpp @@ -1,26 +1,25 @@ #pragma once +#include #include #include +#include #include namespace waybar::util { +template struct EnumParser { EnumParser() {} - enum SORT_METHOD { ID, NAME, NUMBER, DEFAULT }; - - SORT_METHOD sortStringToEnum(const std::string& str) { - // Convert the input string to uppercase (make it lenient on config input) + EnumType sortStringToEnum(const std::string& str, + const std::map& enumMap) { + // Convert the input string to uppercase std::string uppercaseStr; for (char c : str) { - uppercaseStr += std::toupper(c); + uppercaseStr += std::toupper(c); } - static const std::map enumMap = { - {"ID", ID}, {"NAME", NAME}, {"NUMBER", NUMBER}, {"DEFAULT", DEFAULT}}; - auto it = enumMap.find(uppercaseStr); if (it != enumMap.end()) { return it->second; diff --git a/src/modules/hyprland/workspaces.cpp b/src/modules/hyprland/workspaces.cpp index 9eda2c39..21a2a8f7 100644 --- a/src/modules/hyprland/workspaces.cpp +++ b/src/modules/hyprland/workspaces.cpp @@ -61,10 +61,10 @@ auto Workspaces::parse_config(const Json::Value &config) -> void { if (config_sort_by.isString()) { auto sort_by_str = config_sort_by.asString(); try { - sort_by_ = enum_parser_.sortStringToEnum(sort_by_str); + sort_by_ = enum_parser_.sortStringToEnum(sort_by_str, sort_map_); } catch (const std::invalid_argument &e) { // Handle the case where the string is not a valid enum representation. - sort_by_ = util::EnumParser::SORT_METHOD::DEFAULT; + sort_by_ = SORT_METHOD::DEFAULT; g_warning("Invalid string representation for sort-by. Falling back to default sort method."); } } @@ -435,18 +435,18 @@ void Workspaces::sort_workspaces() { auto is_number_less = std::stoi(a->name()) < std::stoi(b->name()); switch (sort_by_) { - case util::EnumParser::SORT_METHOD::ID: + case SORT_METHOD::ID: return is_id_less; - case util::EnumParser::SORT_METHOD::NAME: + case SORT_METHOD::NAME: return is_name_less; - case util::EnumParser::SORT_METHOD::NUMBER: + case SORT_METHOD::NUMBER: try { return is_number_less; } catch (const std::invalid_argument &) { // Handle the exception if necessary. break; } - case util::EnumParser::SORT_METHOD::DEFAULT: + case SORT_METHOD::DEFAULT: default: // Handle the default case here. // normal -> named persistent -> named -> special -> named special From 3ae2fe3272782af0459e40f2605d88927fc86678 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Sat, 9 Sep 2023 12:02:56 -0500 Subject: [PATCH 07/10] refactor: PR review cleanup --- include/modules/hyprland/workspaces.hpp | 2 +- include/util/enum.hpp | 21 ++++++++++----------- src/modules/hyprland/workspaces.cpp | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index 7c4d919e..14b9ba0e 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -88,7 +88,7 @@ class Workspaces : public AModule, public EventHandler { bool show_special_ = false; bool active_only_ = false; - enum SORT_METHOD { ID, NAME, NUMBER, DEFAULT }; + enum class SORT_METHOD { ID, NAME, NUMBER, DEFAULT }; util::EnumParser enum_parser_; SORT_METHOD sort_by_ = SORT_METHOD::DEFAULT; std::map sort_map_ = {{"ID", SORT_METHOD::ID}, diff --git a/include/util/enum.hpp b/include/util/enum.hpp index 7ee80694..a4239bd2 100644 --- a/include/util/enum.hpp +++ b/include/util/enum.hpp @@ -12,20 +12,19 @@ template struct EnumParser { EnumParser() {} - EnumType sortStringToEnum(const std::string& str, - const std::map& enumMap) { + EnumType parseStringToEnum(const std::string& str, + const std::map& enumMap) { // Convert the input string to uppercase - std::string uppercaseStr; - for (char c : str) { - uppercaseStr += std::toupper(c); - } + std::string uppercaseStr = str; + std::transform(uppercaseStr.begin(), uppercaseStr.end(), uppercaseStr.begin(), + [](unsigned char c) { return std::toupper(c); }); + // Return enum match of string auto it = enumMap.find(uppercaseStr); - if (it != enumMap.end()) { - return it->second; - } else { - throw std::invalid_argument("Invalid string representation for enum"); - } + if (it != enumMap.end()) return it->second; + + // Throw error if it doesnt return + throw std::invalid_argument("Invalid string representation for enum"); } ~EnumParser() = default; diff --git a/src/modules/hyprland/workspaces.cpp b/src/modules/hyprland/workspaces.cpp index 21a2a8f7..91da69de 100644 --- a/src/modules/hyprland/workspaces.cpp +++ b/src/modules/hyprland/workspaces.cpp @@ -61,7 +61,7 @@ auto Workspaces::parse_config(const Json::Value &config) -> void { if (config_sort_by.isString()) { auto sort_by_str = config_sort_by.asString(); try { - sort_by_ = enum_parser_.sortStringToEnum(sort_by_str, sort_map_); + sort_by_ = enum_parser_.parseStringToEnum(sort_by_str, sort_map_); } catch (const std::invalid_argument &e) { // Handle the case where the string is not a valid enum representation. sort_by_ = SORT_METHOD::DEFAULT; From 2fee12d930eda56310276e0ef80f10a70a093868 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Sat, 9 Sep 2023 12:14:52 -0500 Subject: [PATCH 08/10] fix: enumparser capitalize everything to avoid issues --- include/util/enum.hpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/include/util/enum.hpp b/include/util/enum.hpp index a4239bd2..6f402614 100644 --- a/include/util/enum.hpp +++ b/include/util/enum.hpp @@ -12,12 +12,26 @@ template struct EnumParser { EnumParser() {} + // Helper function to capitalize a string + std::string capitalizeString(const std::string& str) { + std::string result = str; + std::transform(result.begin(), result.end(), result.begin(), + [](unsigned char c) { return std::toupper(c); }); + return result; + } + EnumType parseStringToEnum(const std::string& str, const std::map& enumMap) { // Convert the input string to uppercase - std::string uppercaseStr = str; - std::transform(uppercaseStr.begin(), uppercaseStr.end(), uppercaseStr.begin(), - [](unsigned char c) { return std::toupper(c); }); + std::string uppercaseStr = capitalizeString(str); + + // Capitalize the map keys before searching + std::map capitalizedEnumMap; + std::transform(enumMap.begin(), enumMap.end(), + std::inserter(capitalizedEnumMap, capitalizedEnumMap.end()), + [this](const auto& pair) { + return std::make_pair(capitalizeString(pair.first), pair.second); + }); // Return enum match of string auto it = enumMap.find(uppercaseStr); From b8630968b262726b01c00a34a65907ca86eed784 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Sat, 9 Sep 2023 13:23:17 -0500 Subject: [PATCH 09/10] refactor: move capitalize string helper --- include/util/enum.hpp | 20 ++++++-------------- include/util/string.hpp | 8 ++++++++ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/util/enum.hpp b/include/util/enum.hpp index 6f402614..951cace3 100644 --- a/include/util/enum.hpp +++ b/include/util/enum.hpp @@ -6,32 +6,24 @@ #include #include +#include "util/string.hpp" + namespace waybar::util { template struct EnumParser { EnumParser() {} - // Helper function to capitalize a string - std::string capitalizeString(const std::string& str) { - std::string result = str; - std::transform(result.begin(), result.end(), result.begin(), - [](unsigned char c) { return std::toupper(c); }); - return result; - } - EnumType parseStringToEnum(const std::string& str, const std::map& enumMap) { // Convert the input string to uppercase - std::string uppercaseStr = capitalizeString(str); + std::string uppercaseStr = capitalize(str); // Capitalize the map keys before searching std::map capitalizedEnumMap; - std::transform(enumMap.begin(), enumMap.end(), - std::inserter(capitalizedEnumMap, capitalizedEnumMap.end()), - [this](const auto& pair) { - return std::make_pair(capitalizeString(pair.first), pair.second); - }); + std::transform( + enumMap.begin(), enumMap.end(), std::inserter(capitalizedEnumMap, capitalizedEnumMap.end()), + [this](const auto& pair) { return std::make_pair(capitalize(pair.first), pair.second); }); // Return enum match of string auto it = enumMap.find(uppercaseStr); diff --git a/include/util/string.hpp b/include/util/string.hpp index 24a9b2b9..d06557c1 100644 --- a/include/util/string.hpp +++ b/include/util/string.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include const std::string WHITESPACE = " \n\r\t\f\v"; @@ -15,3 +16,10 @@ inline std::string rtrim(const std::string& s) { } inline std::string trim(const std::string& s) { return rtrim(ltrim(s)); } + +inline std::string capitalize(const std::string& str) { + std::string result = str; + std::transform(result.begin(), result.end(), result.begin(), + [](unsigned char c) { return std::toupper(c); }); + return result; +} From 79cf33b9f1643d8dca5809ae8ca208d234a8e071 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Sat, 9 Sep 2023 17:48:36 -0500 Subject: [PATCH 10/10] refactor: enumparser create implementation file --- include/util/enum.hpp | 29 +++++----------------------- meson.build | 1 + src/util/enum.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 24 deletions(-) create mode 100644 src/util/enum.cpp diff --git a/include/util/enum.hpp b/include/util/enum.hpp index 951cace3..681385fd 100644 --- a/include/util/enum.hpp +++ b/include/util/enum.hpp @@ -1,38 +1,19 @@ #pragma once -#include -#include #include #include #include -#include "util/string.hpp" - namespace waybar::util { template struct EnumParser { - EnumParser() {} + public: + EnumParser(); + ~EnumParser(); EnumType parseStringToEnum(const std::string& str, - const std::map& enumMap) { - // Convert the input string to uppercase - std::string uppercaseStr = capitalize(str); - - // Capitalize the map keys before searching - std::map capitalizedEnumMap; - std::transform( - enumMap.begin(), enumMap.end(), std::inserter(capitalizedEnumMap, capitalizedEnumMap.end()), - [this](const auto& pair) { return std::make_pair(capitalize(pair.first), pair.second); }); - - // Return enum match of string - auto it = enumMap.find(uppercaseStr); - if (it != enumMap.end()) return it->second; - - // Throw error if it doesnt return - throw std::invalid_argument("Invalid string representation for enum"); - } - - ~EnumParser() = default; + const std::map& enumMap); }; + } // namespace waybar::util diff --git a/meson.build b/meson.build index e71807ec..b27bc05b 100644 --- a/meson.build +++ b/meson.build @@ -171,6 +171,7 @@ src_files = files( 'src/client.cpp', 'src/config.cpp', 'src/group.cpp', + 'src/util/enum.cpp', 'src/util/prepare_for_sleep.cpp', 'src/util/ustring_clen.cpp', 'src/util/sanitize_str.cpp', diff --git a/src/util/enum.cpp b/src/util/enum.cpp new file mode 100644 index 00000000..a29304c5 --- /dev/null +++ b/src/util/enum.cpp @@ -0,0 +1,45 @@ +#include "util/enum.hpp" + +#include // for std::transform +#include // for std::toupper +#include +#include +#include +#include + +#include "modules/hyprland/workspaces.hpp" +#include "util/string.hpp" + +namespace waybar::util { + +template +EnumParser::EnumParser() = default; + +template +EnumParser::~EnumParser() = default; + +template +EnumType EnumParser::parseStringToEnum(const std::string& str, + const std::map& enumMap) { + // Convert the input string to uppercase + std::string uppercaseStr = capitalize(str); + + // Capitalize the map keys before searching + std::map capitalizedEnumMap; + std::transform( + enumMap.begin(), enumMap.end(), std::inserter(capitalizedEnumMap, capitalizedEnumMap.end()), + [this](const auto& pair) { return std::make_pair(capitalize(pair.first), pair.second); }); + + // Return enum match of string + auto it = capitalizedEnumMap.find(uppercaseStr); + if (it != capitalizedEnumMap.end()) return it->second; + + // Throw error if it doesn't return + throw std::invalid_argument("Invalid string representation for enum"); +} + +// Explicit instantiations for specific EnumType types you intend to use +// Add explicit instantiations for all relevant EnumType types +template struct EnumParser; + +} // namespace waybar::util