diff --git a/include/modules/privacy/privacy.hpp b/include/modules/privacy/privacy.hpp index b14cf452..c6b09b2c 100644 --- a/include/modules/privacy/privacy.hpp +++ b/include/modules/privacy/privacy.hpp @@ -26,10 +26,6 @@ class Privacy : public AModule { std::list nodes_audio_in; // Application is using the microphone std::list nodes_audio_out; // Application is outputting audio - PrivacyItem privacy_item_screenshare; - PrivacyItem privacy_item_audio_input; - PrivacyItem privacy_item_audio_output; - std::mutex mutex_; sigc::connection visibility_conn; diff --git a/include/modules/privacy/privacy_item.hpp b/include/modules/privacy/privacy_item.hpp index ac94d168..40ed40c5 100644 --- a/include/modules/privacy/privacy_item.hpp +++ b/include/modules/privacy/privacy_item.hpp @@ -20,16 +20,14 @@ namespace waybar::modules::privacy { class PrivacyItem : public Gtk::Revealer { public: PrivacyItem(const Json::Value &config_, enum PrivacyNodeType privacy_type_, - std::list *nodes, const std::string &pos); + std::list *nodes, const std::string &pos, const uint icon_size, + const uint transition_duration); - bool is_enabled(); + enum PrivacyNodeType privacy_type; void set_in_use(bool in_use); - void set_icon_size(uint size); - private: - enum PrivacyNodeType privacy_type; std::list *nodes; sigc::connection signal_conn; @@ -41,7 +39,6 @@ class PrivacyItem : public Gtk::Revealer { std::string lastStatus; // Config - bool enabled = true; std::string iconName = "image-missing-symbolic"; bool tooltip = true; uint tooltipIconSize = 24; diff --git a/src/modules/privacy/privacy.cpp b/src/modules/privacy/privacy.cpp index 72b7928b..e96f14fa 100644 --- a/src/modules/privacy/privacy.cpp +++ b/src/modules/privacy/privacy.cpp @@ -1,6 +1,7 @@ #include "modules/privacy/privacy.hpp" #include +#include #include #include @@ -10,6 +11,7 @@ #include "AModule.hpp" #include "gtkmm/image.h" +#include "modules/privacy/privacy_item.hpp" namespace waybar::modules::privacy { @@ -23,18 +25,9 @@ Privacy::Privacy(const std::string& id, const Json::Value& config, const std::st nodes_screenshare(), nodes_audio_in(), nodes_audio_out(), - privacy_item_screenshare(config["screenshare"], PRIVACY_NODE_TYPE_VIDEO_INPUT, - &nodes_screenshare, pos), - privacy_item_audio_input(config["audio-in"], PRIVACY_NODE_TYPE_AUDIO_INPUT, &nodes_audio_in, - pos), - privacy_item_audio_output(config["audio-out"], PRIVACY_NODE_TYPE_AUDIO_OUTPUT, - &nodes_audio_out, pos), visibility_conn(), box_(Gtk::ORIENTATION_HORIZONTAL, 0) { box_.set_name(name_); - box_.add(privacy_item_screenshare); - box_.add(privacy_item_audio_output); - box_.add(privacy_item_audio_input); event_box_.add(box_); @@ -48,22 +41,45 @@ Privacy::Privacy(const std::string& id, const Json::Value& config, const std::st if (config_["icon-size"].isUInt()) { iconSize = config_["icon-size"].asUInt(); } - privacy_item_screenshare.set_icon_size(iconSize); - privacy_item_audio_output.set_icon_size(iconSize); - privacy_item_audio_input.set_icon_size(iconSize); // Transition Duration if (config_["transition-duration"].isUInt()) { transition_duration = config_["transition-duration"].asUInt(); } - privacy_item_screenshare.set_transition_duration(transition_duration); - privacy_item_audio_output.set_transition_duration(transition_duration); - privacy_item_audio_input.set_transition_duration(transition_duration); - if (!privacy_item_screenshare.is_enabled() && !privacy_item_audio_input.is_enabled() && - !privacy_item_audio_output.is_enabled()) { - throw std::runtime_error("No privacy modules enabled"); + // Initialize each privacy module + Json::Value modules = config_["modules"]; + // Add Screenshare and Mic usage as default modules if none are specified + if (!modules.isArray() || modules.size() == 0) { + modules = Json::Value(Json::arrayValue); + for (auto& type : {"screenshare", "audio-in"}) { + Json::Value obj = Json::Value(Json::objectValue); + obj["type"] = type; + modules.append(obj); + } } + for (uint i = 0; i < modules.size(); i++) { + const Json::Value& module_config = modules[i]; + if (!module_config.isObject() || !module_config["type"].isString()) continue; + const std::string type = module_config["type"].asString(); + if (type == "screenshare") { + auto item = + Gtk::make_managed(module_config, PRIVACY_NODE_TYPE_VIDEO_INPUT, + &nodes_screenshare, pos, iconSize, transition_duration); + box_.add(*item); + } else if (type == "audio-in") { + auto item = + Gtk::make_managed(module_config, PRIVACY_NODE_TYPE_AUDIO_INPUT, + &nodes_audio_in, pos, iconSize, transition_duration); + box_.add(*item); + } else if (type == "audio-out") { + auto item = + Gtk::make_managed(module_config, PRIVACY_NODE_TYPE_AUDIO_OUTPUT, + &nodes_audio_out, pos, iconSize, transition_duration); + box_.add(*item); + } + } + backend = util::PipewireBackend::PipewireBackend::getInstance(); backend->privacy_nodes_changed_signal_event.connect( sigc::mem_fun(*this, &Privacy::onPrivacyNodesChanged)); @@ -109,9 +125,23 @@ auto Privacy::update() -> void { bool audio_in = !nodes_audio_in.empty(); bool audio_out = !nodes_audio_out.empty(); - privacy_item_screenshare.set_in_use(screenshare); - privacy_item_audio_input.set_in_use(audio_in); - privacy_item_audio_output.set_in_use(audio_out); + for (Gtk::Widget* widget : box_.get_children()) { + PrivacyItem* module = dynamic_cast(widget); + if (!module) continue; + switch (module->privacy_type) { + case util::PipewireBackend::PRIVACY_NODE_TYPE_VIDEO_INPUT: + module->set_in_use(screenshare); + break; + case util::PipewireBackend::PRIVACY_NODE_TYPE_AUDIO_INPUT: + module->set_in_use(audio_in); + break; + case util::PipewireBackend::PRIVACY_NODE_TYPE_AUDIO_OUTPUT: + module->set_in_use(audio_out); + break; + case util::PipewireBackend::PRIVACY_NODE_TYPE_NONE: + break; + } + } mutex_.unlock(); // Hide the whole widget if none are in use diff --git a/src/modules/privacy/privacy_item.cpp b/src/modules/privacy/privacy_item.cpp index 9f1c0819..1d4c8a0e 100644 --- a/src/modules/privacy/privacy_item.cpp +++ b/src/modules/privacy/privacy_item.cpp @@ -23,7 +23,8 @@ namespace waybar::modules::privacy { PrivacyItem::PrivacyItem(const Json::Value &config_, enum PrivacyNodeType privacy_type_, - std::list *nodes_, const std::string &pos) + std::list *nodes_, const std::string &pos, + const uint icon_size, const uint transition_duration) : Gtk::Revealer(), privacy_type(privacy_type_), nodes(nodes_), @@ -46,7 +47,6 @@ PrivacyItem::PrivacyItem(const Json::Value &config_, enum PrivacyNodeType privac break; default: case util::PipewireBackend::PRIVACY_NODE_TYPE_NONE: - enabled = false; return; } @@ -58,16 +58,13 @@ PrivacyItem::PrivacyItem(const Json::Value &config_, enum PrivacyNodeType privac } else if (pos == "modules-right") { set_transition_type(Gtk::REVEALER_TRANSITION_TYPE_SLIDE_LEFT); } + set_transition_duration(transition_duration); box_.set_name("privacy-item"); box_.add(icon_); + icon_.set_pixel_size(icon_size); add(box_); - // Icon Name - if (config_["enabled"].isBool()) { - enabled = config_["enabled"].asBool(); - } - // Icon Name if (config_["icon-name"].isString()) { iconName = config_["icon-name"].asString(); @@ -124,8 +121,6 @@ void PrivacyItem::update_tooltip() { tooltip_window.show_all(); } -bool PrivacyItem::is_enabled() { return enabled; } - void PrivacyItem::set_in_use(bool in_use) { if (in_use) { update_tooltip(); @@ -177,6 +172,4 @@ void PrivacyItem::set_in_use(bool in_use) { lastStatus = status; } -void PrivacyItem::set_icon_size(uint size) { icon_.set_pixel_size(size); } - } // namespace waybar::modules::privacy