mirror of
https://github.com/rad4day/Waybar.git
synced 2025-07-13 22:52:30 +02:00
Merge pull request #2612 from ErikReider/privacy-module
Add Privacy Module
This commit is contained in:
@ -68,6 +68,9 @@
|
||||
#ifdef HAVE_UPOWER
|
||||
#include "modules/upower/upower.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_PIPEWIRE
|
||||
#include "modules/privacy/privacy.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_LIBPULSE
|
||||
#include "modules/pulseaudio.hpp"
|
||||
#endif
|
||||
@ -101,7 +104,7 @@ namespace waybar {
|
||||
class Factory {
|
||||
public:
|
||||
Factory(const Bar& bar, const Json::Value& config);
|
||||
AModule* makeModule(const std::string& name) const;
|
||||
AModule* makeModule(const std::string& name, const std::string& pos) const;
|
||||
|
||||
private:
|
||||
const Bar& bar_;
|
||||
|
41
include/modules/privacy/privacy.hpp
Normal file
41
include/modules/privacy/privacy.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "ALabel.hpp"
|
||||
#include "gtkmm/box.h"
|
||||
#include "modules/privacy/privacy_item.hpp"
|
||||
#include "util/pipewire/pipewire_backend.hpp"
|
||||
#include "util/pipewire/privacy_node_info.hpp"
|
||||
|
||||
using waybar::util::PipewireBackend::PrivacyNodeInfo;
|
||||
|
||||
namespace waybar::modules::privacy {
|
||||
|
||||
class Privacy : public AModule {
|
||||
public:
|
||||
Privacy(const std::string &, const Json::Value &, const std::string &pos);
|
||||
auto update() -> void override;
|
||||
|
||||
void onPrivacyNodesChanged();
|
||||
|
||||
private:
|
||||
std::list<PrivacyNodeInfo *> nodes_screenshare; // Screen is being shared
|
||||
std::list<PrivacyNodeInfo *> nodes_audio_in; // Application is using the microphone
|
||||
std::list<PrivacyNodeInfo *> nodes_audio_out; // Application is outputting audio
|
||||
|
||||
std::mutex mutex_;
|
||||
sigc::connection visibility_conn;
|
||||
|
||||
// Config
|
||||
Gtk::Box box_;
|
||||
uint iconSpacing = 4;
|
||||
uint iconSize = 20;
|
||||
uint transition_duration = 250;
|
||||
|
||||
std::shared_ptr<util::PipewireBackend::PipewireBackend> backend = nullptr;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::privacy
|
51
include/modules/privacy/privacy_item.hpp
Normal file
51
include/modules/privacy/privacy_item.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <json/value.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "gtkmm/box.h"
|
||||
#include "gtkmm/image.h"
|
||||
#include "gtkmm/revealer.h"
|
||||
#include "util/pipewire/privacy_node_info.hpp"
|
||||
|
||||
using waybar::util::PipewireBackend::PrivacyNodeInfo;
|
||||
using waybar::util::PipewireBackend::PrivacyNodeType;
|
||||
|
||||
namespace waybar::modules::privacy {
|
||||
|
||||
class PrivacyItem : public Gtk::Revealer {
|
||||
public:
|
||||
PrivacyItem(const Json::Value &config_, enum PrivacyNodeType privacy_type_,
|
||||
std::list<PrivacyNodeInfo *> *nodes, const std::string &pos, const uint icon_size,
|
||||
const uint transition_duration);
|
||||
|
||||
enum PrivacyNodeType privacy_type;
|
||||
|
||||
void set_in_use(bool in_use);
|
||||
|
||||
private:
|
||||
std::list<PrivacyNodeInfo *> *nodes;
|
||||
|
||||
sigc::connection signal_conn;
|
||||
|
||||
Gtk::Box tooltip_window;
|
||||
|
||||
bool init = false;
|
||||
bool in_use = false;
|
||||
|
||||
// Config
|
||||
std::string iconName = "image-missing-symbolic";
|
||||
bool tooltip = true;
|
||||
uint tooltipIconSize = 24;
|
||||
|
||||
Gtk::Box box_;
|
||||
Gtk::Image icon_;
|
||||
|
||||
void update_tooltip();
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::privacy
|
40
include/util/pipewire/pipewire_backend.hpp
Normal file
40
include/util/pipewire/pipewire_backend.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
#include "util/backend_common.hpp"
|
||||
#include "util/pipewire/privacy_node_info.hpp"
|
||||
|
||||
namespace waybar::util::PipewireBackend {
|
||||
|
||||
class PipewireBackend {
|
||||
private:
|
||||
pw_thread_loop* mainloop_;
|
||||
pw_context* context_;
|
||||
pw_core* core_;
|
||||
|
||||
spa_hook registry_listener;
|
||||
|
||||
/* Hack to keep constructor inaccessible but still public.
|
||||
* This is required to be able to use std::make_shared.
|
||||
* It is important to keep this class only accessible via a reference-counted
|
||||
* pointer because the destructor will manually free memory, and this could be
|
||||
* a problem with C++20's copy and move semantics.
|
||||
*/
|
||||
struct private_constructor_tag {};
|
||||
|
||||
public:
|
||||
std::mutex mutex_;
|
||||
|
||||
pw_registry* registry;
|
||||
|
||||
sigc::signal<void> privacy_nodes_changed_signal_event;
|
||||
|
||||
std::unordered_map<uint32_t, PrivacyNodeInfo*> privacy_nodes;
|
||||
|
||||
static std::shared_ptr<PipewireBackend> getInstance();
|
||||
|
||||
PipewireBackend(private_constructor_tag tag);
|
||||
~PipewireBackend();
|
||||
};
|
||||
} // namespace waybar::util::PipewireBackend
|
62
include/util/pipewire/privacy_node_info.hpp
Normal file
62
include/util/pipewire/privacy_node_info.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "util/gtk_icon.hpp"
|
||||
|
||||
namespace waybar::util::PipewireBackend {
|
||||
|
||||
enum PrivacyNodeType {
|
||||
PRIVACY_NODE_TYPE_NONE,
|
||||
PRIVACY_NODE_TYPE_VIDEO_INPUT,
|
||||
PRIVACY_NODE_TYPE_AUDIO_INPUT,
|
||||
PRIVACY_NODE_TYPE_AUDIO_OUTPUT
|
||||
};
|
||||
|
||||
class PrivacyNodeInfo {
|
||||
public:
|
||||
PrivacyNodeType type = PRIVACY_NODE_TYPE_NONE;
|
||||
uint32_t id;
|
||||
uint32_t client_id;
|
||||
enum pw_node_state state = PW_NODE_STATE_IDLE;
|
||||
std::string media_class;
|
||||
std::string media_name;
|
||||
std::string node_name;
|
||||
std::string application_name;
|
||||
|
||||
std::string pipewire_access_portal_app_id;
|
||||
std::string application_icon_name;
|
||||
|
||||
struct spa_hook object_listener;
|
||||
struct spa_hook proxy_listener;
|
||||
|
||||
void *data;
|
||||
|
||||
std::string get_name() {
|
||||
const std::vector<std::string *> names{&application_name, &node_name};
|
||||
std::string name = "Unknown Application";
|
||||
for (auto &name_ : names) {
|
||||
if (name_ != nullptr && name_->length() > 0) {
|
||||
name = *name_;
|
||||
name[0] = toupper(name[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string get_icon_name() {
|
||||
const std::vector<std::string *> names{&application_icon_name, &pipewire_access_portal_app_id,
|
||||
&application_name, &node_name};
|
||||
const std::string name = "application-x-executable-symbolic";
|
||||
for (auto &name_ : names) {
|
||||
if (name_ != nullptr && name_->length() > 0 && DefaultGtkIconThemeWrapper::has_icon(*name_)) {
|
||||
return *name_;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
};
|
||||
} // namespace waybar::util::PipewireBackend
|
Reference in New Issue
Block a user