From 5d753a34dcb898d1572f527a95b7ec9b58be1803 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 13 Sep 2014 13:12:04 -0500 Subject: hide Clock's implementation details into an Impl class. --- src/clock.cpp | 138 +++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 97 insertions(+), 41 deletions(-) (limited to 'src/clock.cpp') 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 #include +#include +#include +#include +#include + 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( + 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(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(gself)->remember_subscription(name, bus, tag); } + + static void on_login1_vanished(GDBusConnection * /*system_bus*/, + const gchar * name, + gpointer gself) + { + static_cast(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(gself)->m_owner.minute_changed(); + } + + /*** + **** + ***/ + + Clock& m_owner; + std::set m_watched_names; + std::map>> 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(gself)->minute_changed(); } /*** -- cgit v1.2.3 From 187b660a2a80f4aabf0b87c3fae02cb0841dd2e0 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 13 Sep 2014 13:39:19 -0500 Subject: update the time string when a powerd.Wakeup signal is seen. --- src/clock.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 12 deletions(-) (limited to 'src/clock.cpp') diff --git a/src/clock.cpp b/src/clock.cpp index 748174b..6831732 100644 --- a/src/clock.cpp +++ b/src/clock.cpp @@ -18,6 +18,7 @@ */ #include +#include #include #include @@ -49,6 +50,14 @@ public: on_login1_vanished, this, nullptr); m_watched_names.insert(tag); + + tag = g_bus_watch_name(G_BUS_TYPE_SYSTEM, + BUS_POWERD_NAME, + G_BUS_NAME_WATCHER_FLAGS_NONE, + on_powerd_appeared, + on_powerd_vanished, + this, nullptr); + m_watched_names.insert(tag); } @@ -60,19 +69,18 @@ public: private: - void remember_subscription(const std::string& name, - GDBusConnection* bus, - guint tag) + void remember_subscription(const std::string & name, + GDBusConnection * bus, + guint tag) { - auto subscription = std::shared_ptr( - G_DBUS_CONNECTION(g_object_ref(bus)), - [tag](GDBusConnection* bus){ - g_dbus_connection_signal_unsubscribe(bus, tag); - g_object_unref(G_OBJECT(bus)); - } - ); - - m_subscriptions[name].push_back(subscription); + g_object_ref(bus); + + auto deleter = [tag](GDBusConnection* bus){ + g_dbus_connection_signal_unsubscribe(bus, tag); + g_object_unref(G_OBJECT(bus)); + }; + + m_subscriptions[name].push_back(std::shared_ptr(bus, deleter)); } /** @@ -115,6 +123,53 @@ private: GVariant* /*parameters*/, gpointer gself) { + g_debug("firing clock.minute_changed() due to PrepareForSleep"); + static_cast(gself)->m_owner.minute_changed(); + } + + /** + *** DBus Chatter: com.canonical.powerd + *** + *** Fire Clock::minute_changed() signal when powerd says the system's + *** has awoken from sleep -- the old timestamp is likely out-of-date + **/ + + static void on_powerd_appeared(GDBusConnection * bus, + const gchar * name, + const gchar * name_owner, + gpointer gself) + { + auto tag = g_dbus_connection_signal_subscribe(bus, + name_owner, + BUS_POWERD_INTERFACE, + "Wakeup", // signal name + BUS_POWERD_PATH, + nullptr, // arg0 + G_DBUS_SIGNAL_FLAGS_NONE, + on_wakeup, + gself, // user_data + nullptr); // user_data closure + + + static_cast(gself)->remember_subscription(name, bus, tag); + } + + static void on_powerd_vanished(GDBusConnection * /*bus*/, + const gchar * name, + gpointer gself) + { + static_cast(gself)->m_subscriptions[name].clear(); + } + + static void on_wakeup(GDBusConnection* /*connection*/, + const gchar* /*sender_name*/, + const gchar* /*object_path*/, + const gchar* /*interface_name*/, + const gchar* /*signal_name*/, + GVariant* /*parameters*/, + gpointer gself) + { + g_debug("firing clock.minute_changed() due to powerd.Wakeup"); static_cast(gself)->m_owner.minute_changed(); } -- cgit v1.2.3