Merge pull request #3941 from ChaosInfinited/features/systray-custom-icons

Features/systray custom icons
This commit is contained in:
Alexis Rouillard
2025-03-28 09:46:22 +01:00
committed by GitHub
6 changed files with 74 additions and 2 deletions

View File

@ -0,0 +1,43 @@
#pragma once
#include <json/json.h>
#include <spdlog/spdlog.h>
#include <string>
#include <unordered_map>
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<std::string, std::string> icons_map_;
};

View File

@ -62,6 +62,7 @@ class Item : public sigc::trackable {
void proxyReady(Glib::RefPtr<Gio::AsyncResult>& result); void proxyReady(Glib::RefPtr<Gio::AsyncResult>& result);
void setProperty(const Glib::ustring& name, Glib::VariantBase& value); void setProperty(const Glib::ustring& name, Glib::VariantBase& value);
void setStatus(const Glib::ustring& value); void setStatus(const Glib::ustring& value);
void setCustomIcon(const std::string& id);
void getUpdatedProperties(); void getUpdatedProperties();
void processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& result); void processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& result);
void onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name, void onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name,

View File

@ -47,7 +47,11 @@ Addressed by *tray*
``` ```
"tray": { "tray": {
"icon-size": 21, "icon-size": 21,
"spacing": 10 "spacing": 10,
"icons": {
"blueman": "bluetooth",
"TelegramDesktop": "$HOME/.local/share/icons/hicolor/16x16/apps/telegram.png"
}
} }
``` ```

View File

@ -104,7 +104,11 @@
}, },
"tray": { "tray": {
// "icon-size": 21, // "icon-size": 21,
"spacing": 10 "spacing": 10,
// "icons": {
// "blueman": "bluetooth",
// "TelegramDesktop": "$HOME/.local/share/icons/hicolor/16x16/apps/telegram.png"
// }
}, },
"clock": { "clock": {
// "timezone": "America/New_York", // "timezone": "America/New_York",

View File

@ -1,4 +1,5 @@
#include "modules/sni/item.hpp" #include "modules/sni/item.hpp"
#include "modules/sni/icon_manager.hpp"
#include <gdkmm/general.h> #include <gdkmm/general.h>
#include <glibmm/main.h> #include <glibmm/main.h>
@ -7,6 +8,7 @@
#include <fstream> #include <fstream>
#include <map> #include <map>
#include <filesystem>
#include "gdk/gdk.h" #include "gdk/gdk.h"
#include "util/format.hpp" #include "util/format.hpp"
@ -138,6 +140,7 @@ void Item::setProperty(const Glib::ustring& name, Glib::VariantBase& value) {
category = get_variant<std::string>(value); category = get_variant<std::string>(value);
} else if (name == "Id") { } else if (name == "Id") {
id = get_variant<std::string>(value); id = get_variant<std::string>(value);
setCustomIcon(id);
} else if (name == "Title") { } else if (name == "Title") {
title = get_variant<std::string>(value); title = get_variant<std::string>(value);
if (tooltip.text.empty()) { if (tooltip.text.empty()) {
@ -199,6 +202,19 @@ void Item::setStatus(const Glib::ustring& value) {
style->add_class(lower); 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<Gdk::Pixbuf> 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() { void Item::getUpdatedProperties() {
auto params = Glib::VariantContainerBase::create_tuple( auto params = Glib::VariantContainerBase::create_tuple(
{Glib::Variant<Glib::ustring>::create(SNI_INTERFACE_NAME)}); {Glib::Variant<Glib::ustring>::create(SNI_INTERFACE_NAME)});

View File

@ -1,4 +1,5 @@
#include "modules/sni/tray.hpp" #include "modules/sni/tray.hpp"
#include "modules/sni/icon_manager.hpp"
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
@ -20,6 +21,9 @@ Tray::Tray(const std::string& id, const Bar& bar, const Json::Value& config)
box_.set_spacing(config_["spacing"].asUInt()); box_.set_spacing(config_["spacing"].asUInt());
} }
nb_hosts_ += 1; nb_hosts_ += 1;
if (config_["icons"].isObject()) {
IconManager::instance().setIconsConfig(config_["icons"]);
}
dp.emit(); dp.emit();
} }