Added GeoClue2 privacy item
Rebased onto current master and fixed the privacy module build: - privacy_item.hpp no longer includes privacy.hpp (it does not use the Privacy class); this broke the circular include that left PrivacyItem undeclared when privacy.hpp was reached first from privacy_item.cpp. - privacy_item.cpp now includes gtkmm/label.h explicitly, since Gtk::Label was previously only pulled in transitively via privacy.hpp.
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
#include "util/geoclue_backend.hpp"
|
||||
|
||||
#include <giomm/dbuswatchname.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace waybar::util::GeoClueBackend {
|
||||
|
||||
GeoClueBackend::GeoClueBackend(PrivateConstructorTag tag)
|
||||
: watcherID_(0), signal_conn(), connected(false), location_in_use(false) {
|
||||
// Start watching DBUS
|
||||
watcherID_ =
|
||||
Gio::DBus::watch_name(Gio::DBus::BusType::BUS_TYPE_SYSTEM, "org.freedesktop.GeoClue2",
|
||||
sigc::mem_fun(*this, &GeoClueBackend::onAppear),
|
||||
sigc::mem_fun(*this, &GeoClueBackend::onVanished),
|
||||
Gio::DBus::BusNameWatcherFlags::BUS_NAME_WATCHER_FLAGS_AUTO_START);
|
||||
}
|
||||
|
||||
GeoClueBackend::~GeoClueBackend() {
|
||||
if (watcherID_ > 0) {
|
||||
Gio::DBus::unwatch_name(watcherID_);
|
||||
watcherID_ = 0;
|
||||
}
|
||||
signal_conn.disconnect();
|
||||
}
|
||||
|
||||
std::shared_ptr<GeoClueBackend> GeoClueBackend::getInstance() {
|
||||
PrivateConstructorTag tag;
|
||||
return std::make_shared<GeoClueBackend>(tag);
|
||||
}
|
||||
|
||||
void GeoClueBackend::propertyChanged(
|
||||
const Gio::DBus::Proxy::MapChangedProperties& changedProperties,
|
||||
const std::vector<Glib::ustring>& invalidatedProperties) {
|
||||
if (!connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto in_use_variant = changedProperties.find("InUse");
|
||||
in_use_variant != changedProperties.end()) {
|
||||
bool in_use =
|
||||
Glib::VariantBase::cast_dynamic<Glib::Variant<bool>>(in_use_variant->second).get();
|
||||
location_in_use.store(in_use);
|
||||
in_use_changed_signal_event.emit();
|
||||
}
|
||||
}
|
||||
|
||||
void GeoClueBackend::onAppear(const Glib::RefPtr<Gio::DBus::Connection>& conn,
|
||||
const Glib::ustring& name, const Glib::ustring& name_owner) {
|
||||
location_in_use.store(false);
|
||||
signal_conn.disconnect();
|
||||
connected = true;
|
||||
|
||||
proxy = Gio::DBus::Proxy::create_sync(conn, "org.freedesktop.GeoClue2",
|
||||
"/org/freedesktop/GeoClue2/Manager",
|
||||
"org.freedesktop.GeoClue2.Manager");
|
||||
|
||||
// Subscribe DBus events
|
||||
signal_conn = proxy->signal_properties_changed().connect(
|
||||
sigc::mem_fun(*this, &GeoClueBackend::propertyChanged));
|
||||
|
||||
// Get the initial value
|
||||
auto callArgs = Glib::Variant<std::tuple<Glib::ustring, Glib::ustring>>::create(
|
||||
std::make_tuple("org.freedesktop.GeoClue2.Manager", "InUse"));
|
||||
Glib::VariantContainerBase base =
|
||||
proxy->call_sync("org.freedesktop.DBus.Properties.Get", callArgs);
|
||||
if (base.is_of_type(Glib::VariantType("(v)"))) {
|
||||
Glib::Variant<std::tuple<bool>> variant_value;
|
||||
base.get_child(variant_value, 0);
|
||||
auto [value] = variant_value.get();
|
||||
if (location_in_use != value) {
|
||||
location_in_use.store(value);
|
||||
}
|
||||
}
|
||||
|
||||
in_use_changed_signal_event.emit();
|
||||
}
|
||||
|
||||
void GeoClueBackend::onVanished(const Glib::RefPtr<Gio::DBus::Connection>& conn,
|
||||
const Glib::ustring& name) {
|
||||
signal_conn.disconnect();
|
||||
connected = false;
|
||||
|
||||
location_in_use.store(false);
|
||||
in_use_changed_signal_event.emit();
|
||||
}
|
||||
|
||||
} // namespace waybar::util::GeoClueBackend
|
||||
@@ -5,7 +5,7 @@
|
||||
namespace waybar::util::PipewireBackend {
|
||||
|
||||
static void getNodeInfo(void* data_, const struct pw_node_info* info) {
|
||||
auto* pNodeInfo = static_cast<PrivacyNodeInfo*>(data_);
|
||||
auto* pNodeInfo = static_cast<PWPrivacyNodeInfo*>(data_);
|
||||
pNodeInfo->handleNodeEventInfo(info);
|
||||
|
||||
static_cast<PipewireBackend*>(pNodeInfo->data)->privacy_nodes_changed_signal_event.emit();
|
||||
@@ -17,7 +17,7 @@ static const struct pw_node_events NODE_EVENTS = {
|
||||
};
|
||||
|
||||
static void proxyDestroy(void* data) {
|
||||
static_cast<PrivacyNodeInfo*>(data)->handleProxyEventDestroy();
|
||||
static_cast<PWPrivacyNodeInfo*>(data)->handleProxyEventDestroy();
|
||||
}
|
||||
|
||||
static const struct pw_proxy_events PROXY_EVENTS = {
|
||||
@@ -127,12 +127,13 @@ void PipewireBackend::handleRegistryEventGlobal(uint32_t id, uint32_t permission
|
||||
return;
|
||||
}
|
||||
|
||||
auto* proxy = (pw_proxy*)pw_registry_bind(registry_, id, type, version, sizeof(PrivacyNodeInfo));
|
||||
auto* proxy =
|
||||
(pw_proxy*)pw_registry_bind(registry_, id, type, version, sizeof(PWPrivacyNodeInfo));
|
||||
|
||||
if (proxy == nullptr) return;
|
||||
|
||||
auto* pNodeInfo = (PrivacyNodeInfo*)pw_proxy_get_user_data(proxy);
|
||||
new (pNodeInfo) PrivacyNodeInfo{};
|
||||
auto* pNodeInfo = (PWPrivacyNodeInfo*)pw_proxy_get_user_data(proxy);
|
||||
new (pNodeInfo) PWPrivacyNodeInfo{};
|
||||
pNodeInfo->id = id;
|
||||
pNodeInfo->data = this;
|
||||
pNodeInfo->type = mediaType;
|
||||
@@ -152,7 +153,7 @@ void PipewireBackend::handleRegistryEventGlobalRemove(uint32_t id) {
|
||||
mutex_.lock();
|
||||
auto iter = privacy_nodes.find(id);
|
||||
if (iter != privacy_nodes.end()) {
|
||||
privacy_nodes[id]->~PrivacyNodeInfo();
|
||||
privacy_nodes[id]->~PWPrivacyNodeInfo();
|
||||
privacy_nodes.erase(id);
|
||||
}
|
||||
mutex_.unlock();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace waybar::util::PipewireBackend {
|
||||
|
||||
std::string PrivacyNodeInfo::getName() {
|
||||
std::string PWPrivacyNodeInfo::getName() {
|
||||
const std::vector<std::string*> names{&application_name, &node_name};
|
||||
std::string name = "Unknown Application";
|
||||
for (const auto& item : names) {
|
||||
@@ -15,7 +15,7 @@ std::string PrivacyNodeInfo::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string PrivacyNodeInfo::getIconName() {
|
||||
std::string PWPrivacyNodeInfo::getIconName() {
|
||||
const std::vector<std::string*> names{&application_icon_name, &pipewire_access_portal_app_id,
|
||||
&application_name, &node_name};
|
||||
std::string name = "application-x-executable-symbolic";
|
||||
@@ -27,12 +27,12 @@ std::string PrivacyNodeInfo::getIconName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
void PrivacyNodeInfo::handleProxyEventDestroy() {
|
||||
void PWPrivacyNodeInfo::handleProxyEventDestroy() {
|
||||
spa_hook_remove(&proxy_listener);
|
||||
spa_hook_remove(&object_listener);
|
||||
}
|
||||
|
||||
void PrivacyNodeInfo::handleNodeEventInfo(const struct pw_node_info* info) {
|
||||
void PWPrivacyNodeInfo::handleNodeEventInfo(const struct pw_node_info* info) {
|
||||
state = info->state;
|
||||
|
||||
const struct spa_dict_item* item;
|
||||
|
||||
Reference in New Issue
Block a user