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
|
||||
Reference in New Issue
Block a user