diff --git a/include/modules/upower/upower.hpp b/include/modules/upower/upower.hpp index bce89e5..3160499 100644 --- a/include/modules/upower/upower.hpp +++ b/include/modules/upower/upower.hpp @@ -25,6 +25,10 @@ class UPower : public AModule { static void deviceAdded_cb(UpClient *client, UpDevice *device, gpointer data); static void deviceRemoved_cb(UpClient *client, const gchar *object_path, gpointer data); static void deviceNotify_cb(gpointer data); + static void prepareForSleep_cb(GDBusConnection *system_bus, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, + const gchar *signal_name, GVariant *parameters, + gpointer user_data); void removeDevice(const std::string devicePath); void addDevice(UpDevice *device); void setDisplayDevice(); @@ -41,6 +45,8 @@ class UPower : public AModule { UpClient *client = NULL; UpDevice *displayDevice = NULL; std::map devices; + guint login1_id; + GDBusConnection *login1_connection; }; } // namespace waybar::modules diff --git a/meson.build b/meson.build index d34ce95..5e76181 100644 --- a/meson.build +++ b/meson.build @@ -86,7 +86,7 @@ wayland_cursor = dependency('wayland-cursor') wayland_protos = dependency('wayland-protocols') gtkmm = dependency('gtkmm-3.0', version : ['>=3.22.0']) dbusmenu_gtk = dependency('dbusmenu-gtk3-0.4', required: get_option('dbusmenu-gtk')) -giounix = dependency('gio-unix-2.0', required: (get_option('dbusmenu-gtk').enabled() or get_option('logind').enabled())) +giounix = dependency('gio-unix-2.0', required: (get_option('dbusmenu-gtk').enabled() or get_option('logind').enabled() or get_option('upower_glib').enabled())) jsoncpp = dependency('jsoncpp') sigcpp = dependency('sigc++-2.0') libepoll = dependency('epoll-shim', required: false) @@ -204,7 +204,7 @@ if libnl.found() and libnlgen.found() src_files += 'src/modules/network.cpp' endif -if upower_glib.found() +if (upower_glib.found() and giounix.found() and not get_option('logind').disabled()) add_project_arguments('-DHAVE_UPOWER', language: 'cpp') src_files += 'src/modules/upower/upower.cpp' endif diff --git a/src/modules/upower/upower.cpp b/src/modules/upower/upower.cpp index 0e6796c..a26dc9e 100644 --- a/src/modules/upower/upower.cpp +++ b/src/modules/upower/upower.cpp @@ -1,5 +1,7 @@ #include "modules/upower/upower.hpp" +#include + #include #include #include @@ -35,7 +37,22 @@ UPower::UPower(const std::string& id, const Json::Value& config) throw std::runtime_error("Unable to create UPower client!"); } - // TODO: Connect to login1 prepare_for_sleep signal + // Connect to Login1 PrepareForSleep signal + login1_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (!login1_connection) { + throw std::runtime_error("Unable to connect to the SYSTEM Bus!..."); + } else { + login1_id = g_dbus_connection_signal_subscribe(login1_connection, + "org.freedesktop.login1", + "org.freedesktop.login1.Manager", + "PrepareForSleep", + "/org/freedesktop/login1", + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + prepareForSleep_cb, + this, + NULL); + } g_signal_connect(client, "device-added", G_CALLBACK(deviceAdded_cb), this); g_signal_connect(client, "device-removed", G_CALLBACK(deviceRemoved_cb), this); @@ -46,7 +63,13 @@ UPower::UPower(const std::string& id, const Json::Value& config) dp.emit(); } -UPower::~UPower() {} +UPower::~UPower() { + if (client != NULL) g_object_unref(client); + if (login1_id > 0) { + g_dbus_connection_signal_unsubscribe(login1_connection, login1_id); + login1_id = 0; + } +} void UPower::deviceAdded_cb(UpClient* client, UpDevice* device, gpointer data) { UPower* up = static_cast(data); @@ -67,6 +90,19 @@ void UPower::deviceNotify_cb(gpointer data) { // Update the widget up->dp.emit(); } +void UPower::prepareForSleep_cb(GDBusConnection* system_bus, const gchar* sender_name, + const gchar* object_path, const gchar* interface_name, + const gchar* signal_name, GVariant* parameters, gpointer data) { + if (g_variant_is_of_type(parameters, G_VARIANT_TYPE("(b)"))) { + gboolean sleeping; + g_variant_get(parameters, "(b)", &sleeping); + + if (!sleeping) { + UPower* up = static_cast(data); + up->resetDevices(); + } + } +} void UPower::removeDevice(const std::string devicePath) { devices.erase(devicePath); }