aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/clock.cpp138
1 files changed, 97 insertions, 41 deletions
diff --git a/src/clock.cpp b/src/clock.cpp
index f41a0cc..748174b 100644
--- a/src/clock.cpp
+++ b/src/clock.cpp
@@ -22,6 +22,11 @@
#include <glib.h>
#include <gio/gio.h>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
namespace unity {
namespace indicator {
namespace datetime {
@@ -30,58 +35,109 @@ namespace datetime {
****
***/
-Clock::Clock():
- m_cancellable(g_cancellable_new())
+class Clock::Impl
{
- g_bus_get(G_BUS_TYPE_SYSTEM, m_cancellable, on_system_bus_ready, this);
-}
+public:
-Clock::~Clock()
-{
- g_cancellable_cancel(m_cancellable);
- g_clear_object(&m_cancellable);
+ Impl(Clock& owner):
+ m_owner(owner)
+ {
+ auto tag = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
+ "org.freedesktop.login1",
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ on_login1_appeared,
+ on_login1_vanished,
+ this, nullptr);
+ m_watched_names.insert(tag);
+ }
- if (m_sleep_subscription_id)
- g_dbus_connection_signal_unsubscribe(m_system_bus, m_sleep_subscription_id);
- g_clear_object(&m_system_bus);
-}
+ ~Impl()
+ {
+ for(const auto& tag : m_watched_names)
+ g_bus_unwatch_name(tag);
+ }
-void
-Clock::on_system_bus_ready(GObject*, GAsyncResult * res, gpointer gself)
-{
- GDBusConnection * system_bus;
+private:
+
+ void remember_subscription(const std::string& name,
+ GDBusConnection* bus,
+ guint tag)
+ {
+ auto subscription = std::shared_ptr<GDBusConnection>(
+ G_DBUS_CONNECTION(g_object_ref(bus)),
+ [tag](GDBusConnection* bus){
+ g_dbus_connection_signal_unsubscribe(bus, tag);
+ g_object_unref(G_OBJECT(bus));
+ }
+ );
- if ((system_bus = g_bus_get_finish(res, nullptr)))
+ m_subscriptions[name].push_back(subscription);
+ }
+
+ /**
+ *** DBus Chatter: org.freedesktop.login1
+ ***
+ *** Fire Clock::minute_changed() signal on login1's PrepareForSleep signal
+ **/
+
+ static void on_login1_appeared(GDBusConnection * bus,
+ const gchar * name,
+ const gchar * name_owner,
+ gpointer gself)
{
- auto self = static_cast<Clock*>(gself);
-
- self->m_system_bus = system_bus;
-
- self->m_sleep_subscription_id = g_dbus_connection_signal_subscribe(
- system_bus,
- nullptr,
- "org.freedesktop.login1.Manager", // interface
- "PrepareForSleep", // signal name
- "/org/freedesktop/login1", // object path
- nullptr, // arg0
- G_DBUS_SIGNAL_FLAGS_NONE,
- on_prepare_for_sleep,
- self,
- nullptr);
+ auto tag = g_dbus_connection_signal_subscribe(bus,
+ name_owner,
+ "org.freedesktop.login1.Manager", // interface
+ "PrepareForSleep", // signal name
+ "/org/freedesktop/login1", // object path
+ nullptr, // arg0
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ on_prepare_for_sleep,
+ gself,
+ nullptr);
+
+ static_cast<Impl*>(gself)->remember_subscription(name, bus, tag);
}
+
+ static void on_login1_vanished(GDBusConnection * /*system_bus*/,
+ const gchar * name,
+ gpointer gself)
+ {
+ static_cast<Impl*>(gself)->m_subscriptions[name].clear();
+ }
+
+ static void on_prepare_for_sleep(GDBusConnection* /*connection*/,
+ const gchar* /*sender_name*/,
+ const gchar* /*object_path*/,
+ const gchar* /*interface_name*/,
+ const gchar* /*signal_name*/,
+ GVariant* /*parameters*/,
+ gpointer gself)
+ {
+ static_cast<Impl*>(gself)->m_owner.minute_changed();
+ }
+
+ /***
+ ****
+ ***/
+
+ Clock& m_owner;
+ std::set<guint> m_watched_names;
+ std::map<std::string,std::vector<std::shared_ptr<GDBusConnection>>> m_subscriptions;
+};
+
+/***
+****
+***/
+
+Clock::Clock():
+ m_impl(new Impl{*this})
+{
}
-void
-Clock::on_prepare_for_sleep(GDBusConnection* /*connection*/,
- const gchar* /*sender_name*/,
- const gchar* /*object_path*/,
- const gchar* /*interface_name*/,
- const gchar* /*signal_name*/,
- GVariant* /*parameters*/,
- gpointer gself)
+Clock::~Clock()
{
- static_cast<Clock*>(gself)->minute_changed();
}
/***