diff --git a/include/modules/sni/icon_manager.hpp b/include/modules/sni/icon_manager.hpp new file mode 100644 index 00000000..614d42d9 --- /dev/null +++ b/include/modules/sni/icon_manager.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +#include +#include + +class IconManager { + public: + static IconManager& instance() { + static IconManager instance; + return instance; + } + + void setIconsConfig(const Json::Value& icons_config) { + if (icons_config.isObject()) { + for (const auto& key : icons_config.getMemberNames()) { + std::string app_name = key; + const Json::Value& icon_value = icons_config[key]; + + if (icon_value.isString()) { + std::string icon_path = icon_value.asString(); + icons_map_[app_name] = icon_path; + } + } + } else { + spdlog::warn("Invalid icon config format."); + } + } + + std::string getIconForApp(const std::string& app_name) const { + auto it = icons_map_.find(app_name); + if (it != icons_map_.end()) { + return it->second; + } + return ""; + } + + private: + IconManager() = default; + std::unordered_map icons_map_; +}; diff --git a/include/modules/sni/item.hpp b/include/modules/sni/item.hpp index ebc08d45..c5e86d37 100644 --- a/include/modules/sni/item.hpp +++ b/include/modules/sni/item.hpp @@ -62,6 +62,7 @@ class Item : public sigc::trackable { void proxyReady(Glib::RefPtr& result); void setProperty(const Glib::ustring& name, Glib::VariantBase& value); void setStatus(const Glib::ustring& value); + void setCustomIcon(const std::string& id); void getUpdatedProperties(); void processUpdatedProperties(Glib::RefPtr& result); void onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name, diff --git a/man/waybar-tray.5.scd b/man/waybar-tray.5.scd index 381d593d..dec5347f 100644 --- a/man/waybar-tray.5.scd +++ b/man/waybar-tray.5.scd @@ -47,7 +47,11 @@ Addressed by *tray* ``` "tray": { "icon-size": 21, - "spacing": 10 + "spacing": 10, + "icons": { + "blueman": "bluetooth", + "TelegramDesktop": "$HOME/.local/share/icons/hicolor/16x16/apps/telegram.png" + } } ``` diff --git a/resources/config.jsonc b/resources/config.jsonc index 6ac1aa50..67d5ff5b 100644 --- a/resources/config.jsonc +++ b/resources/config.jsonc @@ -104,7 +104,11 @@ }, "tray": { // "icon-size": 21, - "spacing": 10 + "spacing": 10, + // "icons": { + // "blueman": "bluetooth", + // "TelegramDesktop": "$HOME/.local/share/icons/hicolor/16x16/apps/telegram.png" + // } }, "clock": { // "timezone": "America/New_York", diff --git a/src/modules/sni/item.cpp b/src/modules/sni/item.cpp index b3e84885..978e8b07 100644 --- a/src/modules/sni/item.cpp +++ b/src/modules/sni/item.cpp @@ -1,4 +1,5 @@ #include "modules/sni/item.hpp" +#include "modules/sni/icon_manager.hpp" #include #include @@ -7,6 +8,7 @@ #include #include +#include #include "gdk/gdk.h" #include "util/format.hpp" @@ -138,6 +140,7 @@ void Item::setProperty(const Glib::ustring& name, Glib::VariantBase& value) { category = get_variant(value); } else if (name == "Id") { id = get_variant(value); + setCustomIcon(id); } else if (name == "Title") { title = get_variant(value); if (tooltip.text.empty()) { @@ -199,6 +202,19 @@ void Item::setStatus(const Glib::ustring& value) { style->add_class(lower); } +void Item::setCustomIcon(const std::string& id) { + std::string custom_icon = IconManager::instance().getIconForApp(id); + if (!custom_icon.empty()) { + if (std::filesystem::exists(custom_icon)) { + Glib::RefPtr custom_pixbuf = Gdk::Pixbuf::create_from_file(custom_icon); + icon_name = ""; // icon_name has priority over pixmap + icon_pixmap = custom_pixbuf; + } else { // if file doesn't exist it's most likely an icon_name + icon_name = custom_icon; + } + } +} + void Item::getUpdatedProperties() { auto params = Glib::VariantContainerBase::create_tuple( {Glib::Variant::create(SNI_INTERFACE_NAME)}); diff --git a/src/modules/sni/tray.cpp b/src/modules/sni/tray.cpp index a2c56808..abd23ebd 100644 --- a/src/modules/sni/tray.cpp +++ b/src/modules/sni/tray.cpp @@ -1,4 +1,5 @@ #include "modules/sni/tray.hpp" +#include "modules/sni/icon_manager.hpp" #include @@ -20,6 +21,9 @@ Tray::Tray(const std::string& id, const Bar& bar, const Json::Value& config) box_.set_spacing(config_["spacing"].asUInt()); } nb_hosts_ += 1; + if (config_["icons"].isObject()) { + IconManager::instance().setIconsConfig(config_["icons"]); + } dp.emit(); }