From 066f1fb2eb23c4abce7ad9e56f9ecbc600ccddde Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 16 Jul 2014 01:06:59 -0500 Subject: in device.h, add #include to pick up needed GIcon declaration --- src/device.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/device.h b/src/device.h index 3a10f89..77d34ef 100644 --- a/src/device.h +++ b/src/device.h @@ -25,6 +25,7 @@ License along with this library. If not, see #define __INDICATOR_POWER_DEVICE_H__ #include +#include /* GIcon */ G_BEGIN_DECLS -- cgit v1.2.3 From 6ea2db56307d04ac8dba4bcf929cd716f4840359 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 16 Jul 2014 01:08:54 -0500 Subject: add first draft of low battery notifications --- src/CMakeLists.txt | 1 + src/main.c | 12 +- src/notifier.c | 336 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/notifier.h | 68 +++++++++++ 4 files changed, 413 insertions(+), 4 deletions(-) create mode 100644 src/notifier.c create mode 100644 src/notifier.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a39b945..4747b12 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,7 @@ set(SERVICE_MANUAL_SOURCES ib-brightness-uscreen-control.c device-provider.c device.c + notifier.c service.c) # generated sources diff --git a/src/main.c b/src/main.c index 7363284..70b7f2a 100644 --- a/src/main.c +++ b/src/main.c @@ -25,6 +25,7 @@ #include "device.h" #include "device-provider-upower.h" +#include "notifier.h" #include "service.h" /*** @@ -41,9 +42,10 @@ on_name_lost (gpointer instance G_GNUC_UNUSED, gpointer loop) int main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) { - GMainLoop * loop; - IndicatorPowerService * service; IndicatorPowerDeviceProvider * device_provider; + IndicatorPowerNotifier * notifier; + IndicatorPowerService * service; + GMainLoop * loop; /* boilerplate i18n */ setlocale (LC_ALL, ""); @@ -52,6 +54,7 @@ main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) /* run */ device_provider = indicator_power_device_provider_upower_new (); + notifier = indicator_power_notifier_new (device_provider); service = indicator_power_service_new (device_provider); loop = g_main_loop_new (NULL, FALSE); g_signal_connect (service, INDICATOR_POWER_SERVICE_SIGNAL_NAME_LOST, @@ -59,8 +62,9 @@ main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) g_main_loop_run (loop); /* cleanup */ - g_clear_object (&device_provider); - g_clear_object (&service); g_main_loop_unref (loop); + g_clear_object (&service); + g_clear_object (¬ifier); + g_clear_object (&device_provider); return 0; } diff --git a/src/notifier.c b/src/notifier.c new file mode 100644 index 0000000..79ea4cc --- /dev/null +++ b/src/notifier.c @@ -0,0 +1,336 @@ +/* + * Copyright 2014 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Authors: + * Charles Kerr + */ + +#include "device.h" +#include "device-provider.h" +#include "notifier.h" +#include "service.h" + +#include + +#include +#include + +G_DEFINE_TYPE(IndicatorPowerNotifier, + indicator_power_notifier, + G_TYPE_OBJECT) + +enum +{ + PROP_0, + PROP_DEVICE_PROVIDER, + LAST_PROP +}; + +static GParamSpec * properties[LAST_PROP]; + +static int n_notifiers = 0; + +struct _IndicatorPowerNotifierPrivate +{ + IndicatorPowerDeviceProvider * device_provider; + IndicatorPowerDevice * primary_device; + gdouble battery_level; + time_t time_remaining; + NotifyNotification* notify_notification; +}; + +typedef IndicatorPowerNotifierPrivate priv_t; + +/*** +**** +***/ + +static void +emit_critical_signal(IndicatorPowerNotifier * self G_GNUC_UNUSED) +{ + g_message("FIXME %s %s", G_STRFUNC, G_STRLOC); +} + +static void +emit_hide_signal(IndicatorPowerNotifier * self G_GNUC_UNUSED) +{ + g_message("FIXME %s %s", G_STRFUNC, G_STRLOC); +} + +static void +emit_show_signal(IndicatorPowerNotifier * self G_GNUC_UNUSED) +{ + g_message("FIXME %s %s", G_STRFUNC, G_STRLOC); +} + +static void +notification_clear(IndicatorPowerNotifier * self) +{ + priv_t * p = self->priv; + + if (p->notify_notification != NULL) + { + notify_notification_clear_actions(p->notify_notification); + g_signal_handlers_disconnect_by_data(p->notify_notification, self); + g_clear_object(&p->notify_notification); + emit_hide_signal(self); + } +} + +static void +on_notification_clicked(NotifyNotification * notify_notification G_GNUC_UNUSED, + char * action G_GNUC_UNUSED, + gpointer gself G_GNUC_UNUSED) +{ + /* no-op */ +} + +static void +notification_show(IndicatorPowerNotifier * self, + IndicatorPowerDevice * device) + +{ + priv_t * p = self->priv; + char * body; + NotifyNotification * nn; + + // if there's already a notification, tear it down + if (p->notify_notification != NULL) + { + notification_clear (self); + } + + // create the notification + body = g_strdup_printf(_("%d%% charge remaining"), (int)indicator_power_device_get_percentage(device)); + p->notify_notification = nn = notify_notification_new(_("Battery Low"), body, NULL); + notify_notification_set_hint(nn, "x-canonical-snap-decisions", g_variant_new_boolean(TRUE)); + notify_notification_set_hint(nn, "x-canonical-private-button-tint", g_variant_new_boolean(TRUE)); + notify_notification_add_action(nn, "OK", _("OK"), on_notification_clicked, self, NULL); + g_signal_connect_swapped(nn, "closed", G_CALLBACK(notification_clear), self); + + // show the notification + GError* error = NULL; + notify_notification_show(nn, &error); + if (error != NULL) + { + g_critical("Unable to show snap decision for '%s': %s", body, error->message); + g_error_free(error); + } + else + { + emit_show_signal(self); + } + + g_free (body); +} + +static void +on_battery_level_changed(IndicatorPowerNotifier * self G_GNUC_UNUSED, + IndicatorPowerDevice * device, + gdouble old_value, + gdouble new_value) +{ + static const double critical_level = 2.0; + static const double very_low_level = 5.0; + static const double low_level = 48.0; + + if (indicator_power_device_get_state(device) != UP_DEVICE_STATE_DISCHARGING) + return; + +g_message ("%s - %s - %f - %f", G_STRFUNC, indicator_power_device_get_object_path(device), old_value, new_value); + + if ((old_value > critical_level) && (new_value <= critical_level)) + { + emit_critical_signal(self); + } + else if ((old_value > very_low_level) && (new_value <= very_low_level)) + { + notification_show(self, device); + } + else if ((old_value > low_level) && (new_value <= low_level)) + { + notification_show(self, device); + } +} + +static void +on_devices_changed(IndicatorPowerNotifier * self) +{ + priv_t * p = self->priv; + GList * devices; + + // find the primary device + devices = indicator_power_device_provider_get_devices(p->device_provider); + g_clear_object(&p->primary_device); + p->primary_device = indicator_power_service_choose_primary_device (devices); + g_list_free_full (devices, (GDestroyNotify)g_object_unref); + + if (p->primary_device != NULL) + { + // test for battery level change + const gdouble old_level = (int)(p->battery_level*1000) ? p->battery_level : 100.0; + const gdouble new_level = indicator_power_device_get_percentage(p->primary_device); + if ((int)(old_level*1000) != (int)(new_level*1000)) + on_battery_level_changed (self, p->primary_device, old_level, new_level); + + p->battery_level = new_level; + p->time_remaining = indicator_power_device_get_time (p->primary_device); + } +} + +/*** +**** GObject virtual functions +***/ + +static void +my_get_property (GObject * o, + guint property_id, + GValue * value, + GParamSpec * pspec) +{ + IndicatorPowerNotifier * self = INDICATOR_POWER_NOTIFIER (o); + priv_t * p = self->priv; + + switch (property_id) + { + case PROP_DEVICE_PROVIDER: + g_value_set_object (value, p->device_provider); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); + } +} + +static void +my_set_property (GObject * o, + guint property_id, + const GValue * value, + GParamSpec * pspec) +{ + IndicatorPowerNotifier * self = INDICATOR_POWER_NOTIFIER (o); + + switch (property_id) + { + case PROP_DEVICE_PROVIDER: + indicator_power_notifier_set_device_provider (self, g_value_get_object (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); + } +} + +static void +my_dispose (GObject * o) +{ + IndicatorPowerNotifier * self = INDICATOR_POWER_NOTIFIER(o); + + indicator_power_notifier_set_device_provider(self, NULL); + notification_clear(self); + + G_OBJECT_CLASS (indicator_power_notifier_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o G_GNUC_UNUSED) +{ + if (!--n_notifiers) + notify_uninit(); +} + +/*** +**** Instantiation +***/ + +static void +indicator_power_notifier_init (IndicatorPowerNotifier * self) +{ + priv_t * p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_POWER_NOTIFIER, + IndicatorPowerNotifierPrivate); + self->priv = p; + + //p->battery_levels = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); + + if (!n_notifiers++ && !notify_init("indicator-power-service")) + g_critical("Unable to initialize libnotify! Notifications might not be shown."); +} + +static void +indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + object_class->get_property = my_get_property; + object_class->set_property = my_set_property; + + g_type_class_add_private (klass, sizeof (IndicatorPowerNotifierPrivate)); + + properties[PROP_0] = NULL; + + properties[PROP_DEVICE_PROVIDER] = g_param_spec_object ( + "device-provider", + "Device Provider", + "Source for power devices", + G_TYPE_OBJECT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, LAST_PROP, properties); +} + +/*** +**** Public API +***/ + +IndicatorPowerNotifier * +indicator_power_notifier_new (IndicatorPowerDeviceProvider * device_provider) +{ + GObject * o = g_object_new (INDICATOR_TYPE_POWER_NOTIFIER, + "device-provider", device_provider, + NULL); + + return INDICATOR_POWER_NOTIFIER (o); +} + +void +indicator_power_notifier_set_device_provider(IndicatorPowerNotifier * self, + IndicatorPowerDeviceProvider * dp) +{ + priv_t * p; + + g_return_if_fail(INDICATOR_IS_POWER_NOTIFIER(self)); + g_return_if_fail(!dp || INDICATOR_IS_POWER_DEVICE_PROVIDER(dp)); + p = self->priv; + + if (p->device_provider != NULL) + { + g_signal_handlers_disconnect_by_data(p->device_provider, self); + g_clear_object(&p->device_provider); + g_clear_object(&p->primary_device); + } + + if (dp != NULL) + { + p->device_provider = g_object_ref(dp); + + g_signal_connect_swapped(p->device_provider, "devices-changed", + G_CALLBACK(on_devices_changed), self); + + on_devices_changed(self); + } +} diff --git a/src/notifier.h b/src/notifier.h new file mode 100644 index 0000000..e8dfaab --- /dev/null +++ b/src/notifier.h @@ -0,0 +1,68 @@ +/* + * Copyright 2014 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Authors: + * Charles Kerr + */ + +#ifndef __INDICATOR_POWER_NOTIFIER_H__ +#define __INDICATOR_POWER_NOTIFIER_H__ + +#include +#include + +#include "device-provider.h" + +G_BEGIN_DECLS + +/* standard GObject macros */ +#define INDICATOR_POWER_NOTIFIER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_POWER_NOTIFIER, IndicatorPowerNotifier)) +#define INDICATOR_TYPE_POWER_NOTIFIER (indicator_power_notifier_get_type()) +#define INDICATOR_IS_POWER_NOTIFIER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_POWER_NOTIFIER)) + +typedef struct _IndicatorPowerNotifier IndicatorPowerNotifier; +typedef struct _IndicatorPowerNotifierClass IndicatorPowerNotifierClass; +typedef struct _IndicatorPowerNotifierPrivate IndicatorPowerNotifierPrivate; + +/** + * The Indicator Power Notifier. + */ +struct _IndicatorPowerNotifier +{ + /*< private >*/ + GObject parent; + IndicatorPowerNotifierPrivate * priv; +}; + +struct _IndicatorPowerNotifierClass +{ + GObjectClass parent_class; +}; + +/*** +**** +***/ + +GType indicator_power_notifier_get_type (void); + +IndicatorPowerNotifier * indicator_power_notifier_new (IndicatorPowerDeviceProvider * provider); + +void indicator_power_notifier_set_device_provider (IndicatorPowerNotifier * self, + IndicatorPowerDeviceProvider * provider); + + +G_END_DECLS + +#endif /* __INDICATOR_POWER_NOTIFIER_H__ */ -- cgit v1.2.3 From b08f9b096f956b528ad974a30828a809b827efef Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 21 Jul 2014 00:50:24 -0500 Subject: second draft of low battery power notifications, still a work in progress --- src/CMakeLists.txt | 4 + src/dbus-shared.h | 28 ++++++ src/main.c | 4 - src/notifier.c | 270 ++++++++++++++++++++++++++++++++++++++++------------- src/notifier.h | 4 + src/service.c | 11 +++ 6 files changed, 252 insertions(+), 69 deletions(-) create mode 100644 src/dbus-shared.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4747b12..7a4a297 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,10 @@ add_gdbus_codegen_with_namespace(SERVICE_GENERATED_SOURCES dbus-upower org.freedesktop Dbus ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.UPower.xml) +add_gdbus_codegen_with_namespace(SERVICE_GENERATED_SOURCES dbus-battery + com.canonical.indicator.power + Dbus + ${CMAKE_SOURCE_DIR}/data/com.canonical.indicator.power.Battery.xml) # add the bin dir to our include path so the code can find the generated header files include_directories(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/src/dbus-shared.h b/src/dbus-shared.h new file mode 100644 index 0000000..bf54034 --- /dev/null +++ b/src/dbus-shared.h @@ -0,0 +1,28 @@ +/* + * Copyright 2014 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Authors: + * Charles Kerr + * Ted Gould + */ + +#ifndef DBUS_SHARED_H +#define DBUS_SHARED_H + +#define BUS_NAME "com.canonical.indicator.power" +#define BUS_PATH "/com/canonical/indicator/power" + +#endif /* DBUS_SHARED_H */ + diff --git a/src/main.c b/src/main.c index 70b7f2a..d7953e6 100644 --- a/src/main.c +++ b/src/main.c @@ -25,7 +25,6 @@ #include "device.h" #include "device-provider-upower.h" -#include "notifier.h" #include "service.h" /*** @@ -43,7 +42,6 @@ int main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) { IndicatorPowerDeviceProvider * device_provider; - IndicatorPowerNotifier * notifier; IndicatorPowerService * service; GMainLoop * loop; @@ -54,7 +52,6 @@ main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) /* run */ device_provider = indicator_power_device_provider_upower_new (); - notifier = indicator_power_notifier_new (device_provider); service = indicator_power_service_new (device_provider); loop = g_main_loop_new (NULL, FALSE); g_signal_connect (service, INDICATOR_POWER_SERVICE_SIGNAL_NAME_LOST, @@ -64,7 +61,6 @@ main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) /* cleanup */ g_main_loop_unref (loop); g_clear_object (&service); - g_clear_object (¬ifier); g_clear_object (&device_provider); return 0; } diff --git a/src/notifier.c b/src/notifier.c index 79ea4cc..897154a 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -17,6 +17,8 @@ * Charles Kerr */ +#include "dbus-battery-info.h" +#include "dbus-shared.h" #include "device.h" #include "device-provider.h" #include "notifier.h" @@ -35,20 +37,41 @@ enum { PROP_0, PROP_DEVICE_PROVIDER, + PROP_IS_WARNING, + PROP_POWER_LEVEL, LAST_PROP }; +#define DEVICE_PROVIDER_NAME "device-provider" +#define IS_WARNING_NAME "is-warning" +#define POWER_LEVEL_NAME "power-level" + static GParamSpec * properties[LAST_PROP]; static int n_notifiers = 0; +typedef enum +{ + POWER_LEVEL_OK, + POWER_LEVEL_LOW, + POWER_LEVEL_VERY_LOW, + POWER_LEVEL_CRITICAL +} +PowerLevel; + struct _IndicatorPowerNotifierPrivate { IndicatorPowerDeviceProvider * device_provider; - IndicatorPowerDevice * primary_device; - gdouble battery_level; - time_t time_remaining; + + IndicatorPowerDevice * battery; NotifyNotification* notify_notification; + gboolean is_warning; + PowerLevel power_level; + + DbusBattery * dbus_battery; + GBinding * is_warning_binding; + GBinding * power_level_binding; + GDBusConnection * bus; }; typedef IndicatorPowerNotifierPrivate priv_t; @@ -57,35 +80,53 @@ typedef IndicatorPowerNotifierPrivate priv_t; **** ***/ +/* implemented here rather than my_set_property() to guard from public use + because this is a read-only property */ static void -emit_critical_signal(IndicatorPowerNotifier * self G_GNUC_UNUSED) +set_is_warning_property (IndicatorPowerNotifier * self, gboolean is_warning) { - g_message("FIXME %s %s", G_STRFUNC, G_STRLOC); -} + priv_t * p = self->priv; -static void -emit_hide_signal(IndicatorPowerNotifier * self G_GNUC_UNUSED) -{ - g_message("FIXME %s %s", G_STRFUNC, G_STRLOC); + if (p->is_warning != is_warning) + { + p->is_warning = is_warning; + + g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_IS_WARNING]); + } } +/* implemented here rather than my_set_property() to guard from public use + because this is a read-only property */ static void -emit_show_signal(IndicatorPowerNotifier * self G_GNUC_UNUSED) +set_power_level_property (IndicatorPowerNotifier * self, PowerLevel power_level) { - g_message("FIXME %s %s", G_STRFUNC, G_STRLOC); + priv_t * p = self->priv; + + if (p->power_level != power_level) + { + p->power_level = power_level; + + g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_POWER_LEVEL]); + } } +/*** +**** +***/ + static void -notification_clear(IndicatorPowerNotifier * self) +notification_clear (IndicatorPowerNotifier * self) { priv_t * p = self->priv; if (p->notify_notification != NULL) { + set_is_warning_property (self, FALSE); + notify_notification_clear_actions(p->notify_notification); g_signal_handlers_disconnect_by_data(p->notify_notification, self); g_clear_object(&p->notify_notification); - emit_hide_signal(self); + } } @@ -107,10 +148,7 @@ notification_show(IndicatorPowerNotifier * self, NotifyNotification * nn; // if there's already a notification, tear it down - if (p->notify_notification != NULL) - { - notification_clear (self); - } + notification_clear (self); // create the notification body = g_strdup_printf(_("%d%% charge remaining"), (int)indicator_power_device_get_percentage(device)); @@ -130,63 +168,75 @@ notification_show(IndicatorPowerNotifier * self, } else { - emit_show_signal(self); + set_is_warning_property (self, TRUE); } g_free (body); } -static void -on_battery_level_changed(IndicatorPowerNotifier * self G_GNUC_UNUSED, - IndicatorPowerDevice * device, - gdouble old_value, - gdouble new_value) +static PowerLevel +get_power_level (const IndicatorPowerDevice * device) { - static const double critical_level = 2.0; - static const double very_low_level = 5.0; - static const double low_level = 48.0; - - if (indicator_power_device_get_state(device) != UP_DEVICE_STATE_DISCHARGING) - return; - -g_message ("%s - %s - %f - %f", G_STRFUNC, indicator_power_device_get_object_path(device), old_value, new_value); + static const double percent_critical = 2.0; + static const double percent_very_low = 5.0; + static const double percent_low = 48.0; + const gdouble p = indicator_power_device_get_percentage(device); + PowerLevel ret; + + if (p <= percent_critical) + ret = POWER_LEVEL_CRITICAL; + else if (p <= percent_very_low) + ret = POWER_LEVEL_VERY_LOW; + else if (p <= percent_low) + ret = POWER_LEVEL_LOW; + else + ret = POWER_LEVEL_OK; - if ((old_value > critical_level) && (new_value <= critical_level)) - { - emit_critical_signal(self); - } - else if ((old_value > very_low_level) && (new_value <= very_low_level)) - { - notification_show(self, device); - } - else if ((old_value > low_level) && (new_value <= low_level)) - { - notification_show(self, device); - } + return ret; } - + static void on_devices_changed(IndicatorPowerNotifier * self) { priv_t * p = self->priv; GList * devices; - - // find the primary device - devices = indicator_power_device_provider_get_devices(p->device_provider); - g_clear_object(&p->primary_device); - p->primary_device = indicator_power_service_choose_primary_device (devices); + IndicatorPowerDevice * primary; + + /* find the primary battery */ + devices = indicator_power_device_provider_get_devices (p->device_provider); + primary = indicator_power_service_choose_primary_device (devices); + g_clear_object (&p->battery); + if ((primary != NULL) && (indicator_power_device_get_kind (primary) == UP_DEVICE_KIND_BATTERY)) + p->battery = g_object_ref (primary); + g_clear_object(&primary); g_list_free_full (devices, (GDestroyNotify)g_object_unref); - if (p->primary_device != NULL) + /* update our state based on the new primary device */ + if (p->battery == NULL) { - // test for battery level change - const gdouble old_level = (int)(p->battery_level*1000) ? p->battery_level : 100.0; - const gdouble new_level = indicator_power_device_get_percentage(p->primary_device); - if ((int)(old_level*1000) != (int)(new_level*1000)) - on_battery_level_changed (self, p->primary_device, old_level, new_level); - - p->battery_level = new_level; - p->time_remaining = indicator_power_device_get_time (p->primary_device); + /* if there's no primary battery, put everything in standby mode */ + set_power_level_property (self, POWER_LEVEL_OK); + notification_clear(self); + } + else + { + const PowerLevel power_level = get_power_level (p->battery); + + if (p->power_level != power_level) + { + set_power_level_property (self, power_level); + + /* maybe update the notifications */ + if ((power_level == POWER_LEVEL_OK) || + (indicator_power_device_get_state(p->battery) != UP_DEVICE_STATE_DISCHARGING)) + { + notification_clear (self); + } + else + { + notification_show (self, p->battery); + } + } } } @@ -209,6 +259,14 @@ my_get_property (GObject * o, g_value_set_object (value, p->device_provider); break; + case PROP_POWER_LEVEL: + g_value_set_int (value, p->power_level); + break; + + case PROP_IS_WARNING: + g_value_set_boolean (value, p->is_warning); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); } @@ -237,16 +295,24 @@ static void my_dispose (GObject * o) { IndicatorPowerNotifier * self = INDICATOR_POWER_NOTIFIER(o); + priv_t * p = self->priv; +g_message ("%s %s dispose %p", G_STRLOC, G_STRFUNC, (void*)o); - indicator_power_notifier_set_device_provider(self, NULL); + indicator_power_notifier_set_bus(self, NULL); notification_clear(self); + indicator_power_notifier_set_device_provider (self, NULL); + + g_clear_pointer (&p->power_level_binding, g_binding_unbind); + g_clear_pointer (&p->is_warning_binding, g_binding_unbind); + g_clear_object (&p->dbus_battery); G_OBJECT_CLASS (indicator_power_notifier_parent_class)->dispose (o); } static void -my_finalize (GObject * o G_GNUC_UNUSED) +my_finalize (GObject * o) { +g_message ("%s %s finalize %p", G_STRLOC, G_STRFUNC, (void*)o); if (!--n_notifiers) notify_uninit(); } @@ -262,8 +328,23 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) INDICATOR_TYPE_POWER_NOTIFIER, IndicatorPowerNotifierPrivate); self->priv = p; +g_message ("%s %s init %p", G_STRLOC, G_STRFUNC, (void*)self); + + p->dbus_battery = dbus_battery_skeleton_new (); + + /* FIXME: own the busname and export the skeleton */ - //p->battery_levels = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); + p->is_warning_binding = g_object_bind_property (self, + IS_WARNING_NAME, + p->dbus_battery, + IS_WARNING_NAME, + G_BINDING_SYNC_CREATE); + + p->power_level_binding = g_object_bind_property (self, + POWER_LEVEL_NAME, + p->dbus_battery, + POWER_LEVEL_NAME, + G_BINDING_SYNC_CREATE); if (!n_notifiers++ && !notify_init("indicator-power-service")) g_critical("Unable to initialize libnotify! Notifications might not be shown."); @@ -284,12 +365,28 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) properties[PROP_0] = NULL; properties[PROP_DEVICE_PROVIDER] = g_param_spec_object ( - "device-provider", + DEVICE_PROVIDER_NAME, "Device Provider", "Source for power devices", G_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + properties[PROP_POWER_LEVEL] = g_param_spec_int ( + POWER_LEVEL_NAME, + "Power Level", + "Power Level of the batteries", + POWER_LEVEL_OK, + POWER_LEVEL_CRITICAL, + POWER_LEVEL_OK, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + properties[PROP_IS_WARNING] = g_param_spec_boolean ( + IS_WARNING_NAME, + "Is Warning", + "Whether or not we're currently warning the user about a low battery", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, LAST_PROP, properties); } @@ -301,7 +398,7 @@ IndicatorPowerNotifier * indicator_power_notifier_new (IndicatorPowerDeviceProvider * device_provider) { GObject * o = g_object_new (INDICATOR_TYPE_POWER_NOTIFIER, - "device-provider", device_provider, + DEVICE_PROVIDER_NAME, device_provider, NULL); return INDICATOR_POWER_NOTIFIER (o); @@ -321,7 +418,7 @@ indicator_power_notifier_set_device_provider(IndicatorPowerNotifier * self, { g_signal_handlers_disconnect_by_data(p->device_provider, self); g_clear_object(&p->device_provider); - g_clear_object(&p->primary_device); + g_clear_object(&p->battery); } if (dp != NULL) @@ -334,3 +431,46 @@ indicator_power_notifier_set_device_provider(IndicatorPowerNotifier * self, on_devices_changed(self); } } + +void +indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, + GDBusConnection * bus) +{ + priv_t * p; + + g_return_if_fail(INDICATOR_IS_POWER_NOTIFIER(self)); + p = self->priv; + + if (p->bus != NULL) + { + if (p->dbus_battery != NULL) + { + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON(p->dbus_battery)); + } + + g_clear_object (&p->bus); + } + + if (bus != NULL) + { + GError * error; + + p->bus = g_object_ref (bus); + + error = NULL; + g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(p->dbus_battery), + bus, + BUS_PATH"/Battery", + &error); + if (error != NULL) + { + g_warning ("Unable to export LowBattery properties: %s", error->message); + g_error_free (error); + } + } +} + + + + + diff --git a/src/notifier.h b/src/notifier.h index e8dfaab..c224b29 100644 --- a/src/notifier.h +++ b/src/notifier.h @@ -22,6 +22,7 @@ #include #include +#include /* GDBusConnection */ #include "device-provider.h" @@ -59,6 +60,9 @@ GType indicator_power_notifier_get_type (void); IndicatorPowerNotifier * indicator_power_notifier_new (IndicatorPowerDeviceProvider * provider); +void indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, + GDBusConnection * connection); + void indicator_power_notifier_set_device_provider (IndicatorPowerNotifier * self, IndicatorPowerDeviceProvider * provider); diff --git a/src/service.c b/src/service.c index 7478d0f..d8f1371 100644 --- a/src/service.c +++ b/src/service.c @@ -22,8 +22,10 @@ #include #include +#include "dbus-shared.h" #include "device.h" #include "device-provider.h" +#include "notifier.h" #include "ib-brightness-control.h" #include "ib-brightness-uscreen-control.h" #include "service.h" @@ -120,6 +122,7 @@ struct _IndicatorPowerServicePrivate GList * devices; /* IndicatorPowerDevice */ IndicatorPowerDeviceProvider * device_provider; + IndicatorPowerNotifier * notifier; }; typedef IndicatorPowerServicePrivate priv_t; @@ -821,6 +824,9 @@ on_bus_acquired (GDBusConnection * connection, p->conn = g_object_ref (G_OBJECT (connection)); + /* export the battery properties */ + indicator_power_notifier_set_bus (p->notifier, connection); + /* export the actions */ if ((id = g_dbus_connection_export_action_group (connection, BUS_PATH, @@ -1001,6 +1007,7 @@ my_dispose (GObject * o) g_clear_object (&p->settings); } + g_clear_object (&p->notifier); g_clear_object (&p->brightness_action); g_clear_object (&p->battery_level_action); g_clear_object (&p->header_action); @@ -1035,6 +1042,8 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); + p->notifier = indicator_power_notifier_new (NULL); + uscreen_proxy = uscreen_get_proxy(&brightness_params); if (uscreen_proxy != NULL) { @@ -1136,6 +1145,8 @@ indicator_power_service_set_device_provider (IndicatorPowerService * self, on_devices_changed (self); } + + indicator_power_notifier_set_device_provider (p->notifier, dp); } /* If a device has multiple batteries and uses only one of them at a time, -- cgit v1.2.3 From 1902911c18a863ca285c53ae323e233119cf0d86 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 21 Jul 2014 11:25:16 -0500 Subject: remove DeviceProvider from Notifier --- src/notifier.c | 260 +++++++++++++++++++++++++-------------------------------- src/notifier.h | 17 +++- src/service.c | 10 ++- 3 files changed, 136 insertions(+), 151 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 897154a..d32008f 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -19,10 +19,7 @@ #include "dbus-battery-info.h" #include "dbus-shared.h" -#include "device.h" -#include "device-provider.h" #include "notifier.h" -#include "service.h" #include @@ -33,40 +30,44 @@ G_DEFINE_TYPE(IndicatorPowerNotifier, indicator_power_notifier, G_TYPE_OBJECT) +/** +*** GObject Properties +**/ + enum { PROP_0, - PROP_DEVICE_PROVIDER, + PROP_BATTERY, PROP_IS_WARNING, PROP_POWER_LEVEL, LAST_PROP }; -#define DEVICE_PROVIDER_NAME "device-provider" +#define BATTERY_NAME "battery" #define IS_WARNING_NAME "is-warning" #define POWER_LEVEL_NAME "power-level" static GParamSpec * properties[LAST_PROP]; -static int n_notifiers = 0; +/** +*** +**/ -typedef enum -{ - POWER_LEVEL_OK, - POWER_LEVEL_LOW, - POWER_LEVEL_VERY_LOW, - POWER_LEVEL_CRITICAL -} -PowerLevel; +static int n_notifiers = 0; struct _IndicatorPowerNotifierPrivate { IndicatorPowerDeviceProvider * device_provider; + /* The battery we're currently watching. + This may be a physical battery or it may be a "merged" battery + synthesized from multiple batteries present on the device. + See indicator_power_service_choose_primary_device() */ IndicatorPowerDevice * battery; + PowerLevel power_level; + NotifyNotification* notify_notification; gboolean is_warning; - PowerLevel power_level; DbusBattery * dbus_battery; GBinding * is_warning_binding; @@ -77,41 +78,7 @@ struct _IndicatorPowerNotifierPrivate typedef IndicatorPowerNotifierPrivate priv_t; /*** -**** -***/ - -/* implemented here rather than my_set_property() to guard from public use - because this is a read-only property */ -static void -set_is_warning_property (IndicatorPowerNotifier * self, gboolean is_warning) -{ - priv_t * p = self->priv; - - if (p->is_warning != is_warning) - { - p->is_warning = is_warning; - - g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_IS_WARNING]); - } -} - -/* implemented here rather than my_set_property() to guard from public use - because this is a read-only property */ -static void -set_power_level_property (IndicatorPowerNotifier * self, PowerLevel power_level) -{ - priv_t * p = self->priv; - - if (p->power_level != power_level) - { - p->power_level = power_level; - - g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_POWER_LEVEL]); - } -} - -/*** -**** +**** Notifications ***/ static void @@ -135,30 +102,38 @@ on_notification_clicked(NotifyNotification * notify_notification G_GNUC_UNUSED, char * action G_GNUC_UNUSED, gpointer gself G_GNUC_UNUSED) { - /* no-op */ + /* no-op because notify_notification_add_action() doesn't like a NULL cb */ } static void -notification_show(IndicatorPowerNotifier * self, - IndicatorPowerDevice * device) - +notification_show(IndicatorPowerNotifier * self) { - priv_t * p = self->priv; + priv_t * p; + IndicatorPowerDevice * battery; char * body; NotifyNotification * nn; - // if there's already a notification, tear it down notification_clear (self); - // create the notification - body = g_strdup_printf(_("%d%% charge remaining"), (int)indicator_power_device_get_percentage(device)); - p->notify_notification = nn = notify_notification_new(_("Battery Low"), body, NULL); - notify_notification_set_hint(nn, "x-canonical-snap-decisions", g_variant_new_boolean(TRUE)); - notify_notification_set_hint(nn, "x-canonical-private-button-tint", g_variant_new_boolean(TRUE)); - notify_notification_add_action(nn, "OK", _("OK"), on_notification_clicked, self, NULL); + p = self->priv; + battery = p->battery; + g_return_if_fail (battery != NULL); + + /* create the notification */ + body = g_strdup_printf(_("%d%% charge remaining"), + (int)indicator_power_device_get_percentage(battery)); + p->notify_notification = nn = notify_notification_new(_("Battery Low"), + body, + NULL); + notify_notification_set_hint(nn, "x-canonical-snap-decisions", + g_variant_new_boolean(TRUE)); + notify_notification_set_hint(nn, "x-canonical-private-button-tint", + g_variant_new_boolean(TRUE)); + notify_notification_add_action(nn, "OK", _("OK"), + on_notification_clicked, self, NULL); g_signal_connect_swapped(nn, "closed", G_CALLBACK(notification_clear), self); - // show the notification + /* show the notification */ GError* error = NULL; notify_notification_show(nn, &error); if (error != NULL) @@ -174,12 +149,16 @@ notification_show(IndicatorPowerNotifier * self, g_free (body); } +/*** +**** +***/ + static PowerLevel get_power_level (const IndicatorPowerDevice * device) { static const double percent_critical = 2.0; static const double percent_very_low = 5.0; - static const double percent_low = 48.0; + static const double percent_low = 10.0; const gdouble p = indicator_power_device_get_percentage(device); PowerLevel ret; @@ -195,50 +174,6 @@ get_power_level (const IndicatorPowerDevice * device) return ret; } -static void -on_devices_changed(IndicatorPowerNotifier * self) -{ - priv_t * p = self->priv; - GList * devices; - IndicatorPowerDevice * primary; - - /* find the primary battery */ - devices = indicator_power_device_provider_get_devices (p->device_provider); - primary = indicator_power_service_choose_primary_device (devices); - g_clear_object (&p->battery); - if ((primary != NULL) && (indicator_power_device_get_kind (primary) == UP_DEVICE_KIND_BATTERY)) - p->battery = g_object_ref (primary); - g_clear_object(&primary); - g_list_free_full (devices, (GDestroyNotify)g_object_unref); - - /* update our state based on the new primary device */ - if (p->battery == NULL) - { - /* if there's no primary battery, put everything in standby mode */ - set_power_level_property (self, POWER_LEVEL_OK); - notification_clear(self); - } - else - { - const PowerLevel power_level = get_power_level (p->battery); - - if (p->power_level != power_level) - { - set_power_level_property (self, power_level); - - /* maybe update the notifications */ - if ((power_level == POWER_LEVEL_OK) || - (indicator_power_device_get_state(p->battery) != UP_DEVICE_STATE_DISCHARGING)) - { - notification_clear (self); - } - else - { - notification_show (self, p->battery); - } - } - } -} /*** **** GObject virtual functions @@ -255,8 +190,8 @@ my_get_property (GObject * o, switch (property_id) { - case PROP_DEVICE_PROVIDER: - g_value_set_object (value, p->device_provider); + case PROP_BATTERY: + g_value_set_object (value, p->battery); break; case PROP_POWER_LEVEL: @@ -282,8 +217,8 @@ my_set_property (GObject * o, switch (property_id) { - case PROP_DEVICE_PROVIDER: - indicator_power_notifier_set_device_provider (self, g_value_get_object (value)); + case PROP_BATTERY: + indicator_power_notifier_set_battery (self, g_value_get_object(value)); break; default: @@ -291,17 +226,43 @@ my_set_property (GObject * o, } } +/* read-only property, so not implemented in my_set_property() */ +static void +set_is_warning_property (IndicatorPowerNotifier * self, gboolean is_warning) +{ + priv_t * p = self->priv; + + if (p->is_warning != is_warning) + { + p->is_warning = is_warning; + + g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_IS_WARNING]); + } +} + +/* read-only property, so not implemented in my_set_property() */ +static void +set_power_level_property (IndicatorPowerNotifier * self, PowerLevel power_level) +{ + priv_t * p = self->priv; + + if (p->power_level != power_level) + { + p->power_level = power_level; + + g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_POWER_LEVEL]); + } +} + static void my_dispose (GObject * o) { IndicatorPowerNotifier * self = INDICATOR_POWER_NOTIFIER(o); priv_t * p = self->priv; -g_message ("%s %s dispose %p", G_STRLOC, G_STRFUNC, (void*)o); - - indicator_power_notifier_set_bus(self, NULL); - notification_clear(self); - indicator_power_notifier_set_device_provider (self, NULL); + indicator_power_notifier_set_bus (self, NULL); + notification_clear (self); + indicator_power_notifier_set_device (self, NULL); g_clear_pointer (&p->power_level_binding, g_binding_unbind); g_clear_pointer (&p->is_warning_binding, g_binding_unbind); g_clear_object (&p->dbus_battery); @@ -310,9 +271,8 @@ g_message ("%s %s dispose %p", G_STRLOC, G_STRFUNC, (void*)o); } static void -my_finalize (GObject * o) +my_finalize (GObject * o G_GNUC_UNUSED) { -g_message ("%s %s finalize %p", G_STRLOC, G_STRFUNC, (void*)o); if (!--n_notifiers) notify_uninit(); } @@ -328,12 +288,9 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) INDICATOR_TYPE_POWER_NOTIFIER, IndicatorPowerNotifierPrivate); self->priv = p; -g_message ("%s %s init %p", G_STRLOC, G_STRFUNC, (void*)self); p->dbus_battery = dbus_battery_skeleton_new (); - /* FIXME: own the busname and export the skeleton */ - p->is_warning_binding = g_object_bind_property (self, IS_WARNING_NAME, p->dbus_battery, @@ -364,17 +321,17 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) properties[PROP_0] = NULL; - properties[PROP_DEVICE_PROVIDER] = g_param_spec_object ( - DEVICE_PROVIDER_NAME, - "Device Provider", - "Source for power devices", + properties[PROP_BATTERY] = g_param_spec_object ( + BATTERY_NAME, + "Battery", + "The current battery", G_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); properties[PROP_POWER_LEVEL] = g_param_spec_int ( POWER_LEVEL_NAME, "Power Level", - "Power Level of the batteries", + "The battery's power level", POWER_LEVEL_OK, POWER_LEVEL_CRITICAL, POWER_LEVEL_OK, @@ -397,50 +354,65 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) IndicatorPowerNotifier * indicator_power_notifier_new (IndicatorPowerDeviceProvider * device_provider) { - GObject * o = g_object_new (INDICATOR_TYPE_POWER_NOTIFIER, - DEVICE_PROVIDER_NAME, device_provider, - NULL); + GObject * o = g_object_new (INDICATOR_TYPE_POWER_NOTIFIER, NULL); return INDICATOR_POWER_NOTIFIER (o); } void -indicator_power_notifier_set_device_provider(IndicatorPowerNotifier * self, - IndicatorPowerDeviceProvider * dp) +indicator_power_notifier_set_battery (IndicatorPowerNotifier * self, + IndicatorPowerDevice * battery) { priv_t * p; g_return_if_fail(INDICATOR_IS_POWER_NOTIFIER(self)); - g_return_if_fail(!dp || INDICATOR_IS_POWER_DEVICE_PROVIDER(dp)); - p = self->priv; + g_return_if_fail((battery == NULL) || INDICATOR_IS_POWER_DEVICE(battery)); + g_return_if_fail((battery == NULL) || (indicator_power_device_get_kind(battery) == UP_DEVICE_KIND_BATTERY)); - if (p->device_provider != NULL) + if (p->battery != NULL) { - g_signal_handlers_disconnect_by_data(p->device_provider, self); - g_clear_object(&p->device_provider); - g_clear_object(&p->battery); + g_clear_object (&p->battery); + set_power_level_property (self, POWER_LEVEL_OK); + notification_clear (self); } - if (dp != NULL) + if (battery != NULL) { - p->device_provider = g_object_ref(dp); + const PowerLevel power_level = get_power_level (battery); - g_signal_connect_swapped(p->device_provider, "devices-changed", - G_CALLBACK(on_devices_changed), self); + p->battery = g_object_ref(battery); - on_devices_changed(self); + if (p->power_level != power_level) + { + set_power_level_property (self, power_level); + + if ((power_level == POWER_LEVEL_OK) || + (indicator_power_device_get_state(battery) != UP_DEVICE_STATE_DISCHARGING)) + { + notification_clear (self); + } + else + { + notification_show (self); + } + } } } void indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, - GDBusConnection * bus) + GDBusConnection * bus) { priv_t * p; g_return_if_fail(INDICATOR_IS_POWER_NOTIFIER(self)); + g_return_if_fail((bus == NULL) || G_IS_DBUS_CONNECTION(bus)); + p = self->priv; + if (p->bus == bus) + return; + if (p->bus != NULL) { if (p->dbus_battery != NULL) diff --git a/src/notifier.h b/src/notifier.h index c224b29..2602171 100644 --- a/src/notifier.h +++ b/src/notifier.h @@ -24,7 +24,7 @@ #include #include /* GDBusConnection */ -#include "device-provider.h" +#include "device.h" G_BEGIN_DECLS @@ -37,6 +37,15 @@ typedef struct _IndicatorPowerNotifier IndicatorPowerNotifier; typedef struct _IndicatorPowerNotifierClass IndicatorPowerNotifierClass; typedef struct _IndicatorPowerNotifierPrivate IndicatorPowerNotifierPrivate; +typedef enum +{ + POWER_LEVEL_OK, + POWER_LEVEL_LOW, + POWER_LEVEL_VERY_LOW, + POWER_LEVEL_CRITICAL +} +PowerLevel; + /** * The Indicator Power Notifier. */ @@ -58,13 +67,13 @@ struct _IndicatorPowerNotifierClass GType indicator_power_notifier_get_type (void); -IndicatorPowerNotifier * indicator_power_notifier_new (IndicatorPowerDeviceProvider * provider); +IndicatorPowerNotifier * indicator_power_notifier_new (void); void indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, GDBusConnection * connection); -void indicator_power_notifier_set_device_provider (IndicatorPowerNotifier * self, - IndicatorPowerDeviceProvider * provider); +void indicator_power_notifier_set_device (IndicatorPowerNotifier * self, + IndicatorPowerDevice * provider); G_END_DECLS diff --git a/src/service.c b/src/service.c index d8f1371..1c1f8f7 100644 --- a/src/service.c +++ b/src/service.c @@ -926,6 +926,12 @@ on_devices_changed (IndicatorPowerService * self) g_clear_object (&p->primary_device); p->primary_device = indicator_power_service_choose_primary_device (p->devices); + /* update the notifier's battery */ + if ((p->primary_device != NULL) || (indicator_power_device_get_kind(p->primary_device) == UP_DEVICE_KIND_BATTERY)) + indicator_power_notifier_set_battery (p->primary_device); + else + indicator_power_notifier_set_battery (NULL); + /* update the battery-level action's state */ if (p->primary_device == NULL) battery_level = 0; @@ -1042,7 +1048,7 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); - p->notifier = indicator_power_notifier_new (NULL); + p->notifier = indicator_power_notifier_new (); uscreen_proxy = uscreen_get_proxy(&brightness_params); if (uscreen_proxy != NULL) @@ -1145,8 +1151,6 @@ indicator_power_service_set_device_provider (IndicatorPowerService * self, on_devices_changed (self); } - - indicator_power_notifier_set_device_provider (p->notifier, dp); } /* If a device has multiple batteries and uses only one of them at a time, -- cgit v1.2.3 From 7b3b8a27aa6e0a9a10f6faec1cd13b10f5b2492a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 21 Jul 2014 12:10:41 -0500 Subject: fix build issues --- src/notifier.c | 13 ++++++++----- src/notifier.h | 4 ++-- src/service.c | 6 +++--- 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index d32008f..1d9428c 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -17,7 +17,7 @@ * Charles Kerr */ -#include "dbus-battery-info.h" +#include "dbus-battery.h" #include "dbus-shared.h" #include "notifier.h" @@ -57,8 +57,6 @@ static int n_notifiers = 0; struct _IndicatorPowerNotifierPrivate { - IndicatorPowerDeviceProvider * device_provider; - /* The battery we're currently watching. This may be a physical battery or it may be a "merged" battery synthesized from multiple batteries present on the device. @@ -77,6 +75,9 @@ struct _IndicatorPowerNotifierPrivate typedef IndicatorPowerNotifierPrivate priv_t; +static void set_is_warning_property (IndicatorPowerNotifier*, gboolean is_warning); +static void set_power_level_property (IndicatorPowerNotifier*, PowerLevel power_level); + /*** **** Notifications ***/ @@ -262,7 +263,7 @@ my_dispose (GObject * o) indicator_power_notifier_set_bus (self, NULL); notification_clear (self); - indicator_power_notifier_set_device (self, NULL); + indicator_power_notifier_set_battery (self, NULL); g_clear_pointer (&p->power_level_binding, g_binding_unbind); g_clear_pointer (&p->is_warning_binding, g_binding_unbind); g_clear_object (&p->dbus_battery); @@ -352,7 +353,7 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) ***/ IndicatorPowerNotifier * -indicator_power_notifier_new (IndicatorPowerDeviceProvider * device_provider) +indicator_power_notifier_new (void) { GObject * o = g_object_new (INDICATOR_TYPE_POWER_NOTIFIER, NULL); @@ -369,6 +370,8 @@ indicator_power_notifier_set_battery (IndicatorPowerNotifier * self, g_return_if_fail((battery == NULL) || INDICATOR_IS_POWER_DEVICE(battery)); g_return_if_fail((battery == NULL) || (indicator_power_device_get_kind(battery) == UP_DEVICE_KIND_BATTERY)); + p = self->priv; + if (p->battery != NULL) { g_clear_object (&p->battery); diff --git a/src/notifier.h b/src/notifier.h index 2602171..c1c5a1b 100644 --- a/src/notifier.h +++ b/src/notifier.h @@ -72,8 +72,8 @@ IndicatorPowerNotifier * indicator_power_notifier_new (void); void indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, GDBusConnection * connection); -void indicator_power_notifier_set_device (IndicatorPowerNotifier * self, - IndicatorPowerDevice * provider); +void indicator_power_notifier_set_battery (IndicatorPowerNotifier * self, + IndicatorPowerDevice * battery); G_END_DECLS diff --git a/src/service.c b/src/service.c index 1c1f8f7..23cef84 100644 --- a/src/service.c +++ b/src/service.c @@ -927,10 +927,10 @@ on_devices_changed (IndicatorPowerService * self) p->primary_device = indicator_power_service_choose_primary_device (p->devices); /* update the notifier's battery */ - if ((p->primary_device != NULL) || (indicator_power_device_get_kind(p->primary_device) == UP_DEVICE_KIND_BATTERY)) - indicator_power_notifier_set_battery (p->primary_device); + if ((p->primary_device != NULL) && (indicator_power_device_get_kind(p->primary_device) == UP_DEVICE_KIND_BATTERY)) + indicator_power_notifier_set_battery (p->notifier, p->primary_device); else - indicator_power_notifier_set_battery (NULL); + indicator_power_notifier_set_battery (p->notifier, NULL); /* update the battery-level action's state */ if (p->primary_device == NULL) -- cgit v1.2.3 From f5bf7f99724796a21dc05676d613ed47c624bfd1 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 21 Jul 2014 13:48:18 -0500 Subject: don't show clickable actions if the Notify server doesn't support them. --- src/notifier.c | 60 +++++++++++++++++++++++++++++++++++++++++----------------- src/notifier.h | 11 ++++++++--- 2 files changed, 51 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 1d9428c..06ab119 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -53,8 +53,6 @@ static GParamSpec * properties[LAST_PROP]; *** **/ -static int n_notifiers = 0; - struct _IndicatorPowerNotifierPrivate { /* The battery we're currently watching. @@ -110,22 +108,22 @@ static void notification_show(IndicatorPowerNotifier * self) { priv_t * p; - IndicatorPowerDevice * battery; char * body; NotifyNotification * nn; notification_clear (self); + /* only show clickable notifications if the Notify server supports them */ + if (!INDICATOR_POWER_NOTIFIER_GET_CLASS(self)->interactive) + return; + p = self->priv; - battery = p->battery; - g_return_if_fail (battery != NULL); /* create the notification */ - body = g_strdup_printf(_("%d%% charge remaining"), - (int)indicator_power_device_get_percentage(battery)); - p->notify_notification = nn = notify_notification_new(_("Battery Low"), - body, - NULL); + body = g_strdup_printf(_("%.0f%% charge remaining"), + indicator_power_device_get_percentage(p->battery)); + nn = notify_notification_new(_("Battery Low"), body, NULL); + p->notify_notification = nn; notify_notification_set_hint(nn, "x-canonical-snap-decisions", g_variant_new_boolean(TRUE)); notify_notification_set_hint(nn, "x-canonical-private-button-tint", @@ -272,9 +270,11 @@ my_dispose (GObject * o) } static void -my_finalize (GObject * o G_GNUC_UNUSED) +my_finalize (GObject * o) { - if (!--n_notifiers) + IndicatorPowerNotifierClass * klass = INDICATOR_POWER_NOTIFIER_GET_CLASS(o); + + if (!--klass->instance_count) notify_uninit(); } @@ -285,9 +285,12 @@ my_finalize (GObject * o G_GNUC_UNUSED) static void indicator_power_notifier_init (IndicatorPowerNotifier * self) { - priv_t * p = G_TYPE_INSTANCE_GET_PRIVATE (self, - INDICATOR_TYPE_POWER_NOTIFIER, - IndicatorPowerNotifierPrivate); + priv_t * p; + IndicatorPowerNotifierClass * klass; + + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_POWER_NOTIFIER, + IndicatorPowerNotifierPrivate); self->priv = p; p->dbus_battery = dbus_battery_skeleton_new (); @@ -304,8 +307,28 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) POWER_LEVEL_NAME, G_BINDING_SYNC_CREATE); - if (!n_notifiers++ && !notify_init("indicator-power-service")) - g_critical("Unable to initialize libnotify! Notifications might not be shown."); + klass = INDICATOR_POWER_NOTIFIER_GET_CLASS(self); + + if (!klass->instance_count++) + { + if (!notify_init("indicator-power-service")) + { + g_critical("Unable to initialize libnotify! Notifications might not be shown."); + } + else + { + /* See if the notification server supports clickable actions... */ + GList * caps; + GList * l; + klass->interactive = FALSE; + caps = notify_get_server_caps(); + for (l=caps; l!=NULL && !klass->interactive; l=l->next) + if (!g_strcmp0 ("actions", (const char*)l->data)) + klass->interactive = TRUE; + g_message ("%s klass->interactive is %d", G_STRLOC, (int)klass->interactive); + g_list_free_full (caps, g_free); + } + } } static void @@ -346,6 +369,9 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, LAST_PROP, properties); + + klass->instance_count = 0; + klass->interactive = FALSE; } /*** diff --git a/src/notifier.h b/src/notifier.h index c1c5a1b..cab053f 100644 --- a/src/notifier.h +++ b/src/notifier.h @@ -29,9 +29,10 @@ G_BEGIN_DECLS /* standard GObject macros */ -#define INDICATOR_POWER_NOTIFIER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_POWER_NOTIFIER, IndicatorPowerNotifier)) -#define INDICATOR_TYPE_POWER_NOTIFIER (indicator_power_notifier_get_type()) -#define INDICATOR_IS_POWER_NOTIFIER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_POWER_NOTIFIER)) +#define INDICATOR_POWER_NOTIFIER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_POWER_NOTIFIER, IndicatorPowerNotifier)) +#define INDICATOR_TYPE_POWER_NOTIFIER (indicator_power_notifier_get_type()) +#define INDICATOR_IS_POWER_NOTIFIER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_POWER_NOTIFIER)) +#define INDICATOR_POWER_NOTIFIER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_POWER_NOTIFIER, IndicatorPowerNotifierClass)) typedef struct _IndicatorPowerNotifier IndicatorPowerNotifier; typedef struct _IndicatorPowerNotifierClass IndicatorPowerNotifierClass; @@ -59,6 +60,10 @@ struct _IndicatorPowerNotifier struct _IndicatorPowerNotifierClass { GObjectClass parent_class; + + /*< private >*/ + gint instance_count; + gboolean interactive; }; /*** -- cgit v1.2.3 From 8c4b964ee9fd6578f3b922357c58b933bf14e6df Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 21 Jul 2014 14:15:28 -0500 Subject: copyediting --- src/notifier.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 06ab119..9dd7550 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -43,9 +43,9 @@ enum LAST_PROP }; -#define BATTERY_NAME "battery" -#define IS_WARNING_NAME "is-warning" -#define POWER_LEVEL_NAME "power-level" +#define PROP_BATTERY_NAME "battery" +#define PROP_IS_WARNING_NAME "is-warning" +#define PROP_POWER_LEVEL_NAME "power-level" static GParamSpec * properties[LAST_PROP]; @@ -101,7 +101,7 @@ on_notification_clicked(NotifyNotification * notify_notification G_GNUC_UNUSED, char * action G_GNUC_UNUSED, gpointer gself G_GNUC_UNUSED) { - /* no-op because notify_notification_add_action() doesn't like a NULL cb */ + /* no-op; notify_notification_add_action() doesn't like NULL callbacks */ } static void @@ -110,6 +110,7 @@ notification_show(IndicatorPowerNotifier * self) priv_t * p; char * body; NotifyNotification * nn; + GError * error; notification_clear (self); @@ -133,7 +134,7 @@ notification_show(IndicatorPowerNotifier * self) g_signal_connect_swapped(nn, "closed", G_CALLBACK(notification_clear), self); /* show the notification */ - GError* error = NULL; + error = NULL; notify_notification_show(nn, &error); if (error != NULL) { @@ -158,6 +159,7 @@ get_power_level (const IndicatorPowerDevice * device) static const double percent_critical = 2.0; static const double percent_very_low = 5.0; static const double percent_low = 10.0; + const gdouble p = indicator_power_device_get_percentage(device); PowerLevel ret; @@ -296,15 +298,15 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) p->dbus_battery = dbus_battery_skeleton_new (); p->is_warning_binding = g_object_bind_property (self, - IS_WARNING_NAME, + PROP_IS_WARNING_NAME, p->dbus_battery, - IS_WARNING_NAME, + PROP_IS_WARNING_NAME, G_BINDING_SYNC_CREATE); p->power_level_binding = g_object_bind_property (self, - POWER_LEVEL_NAME, + PROP_POWER_LEVEL_NAME, p->dbus_battery, - POWER_LEVEL_NAME, + PROP_POWER_LEVEL_NAME, G_BINDING_SYNC_CREATE); klass = INDICATOR_POWER_NOTIFIER_GET_CLASS(self); @@ -346,14 +348,14 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) properties[PROP_0] = NULL; properties[PROP_BATTERY] = g_param_spec_object ( - BATTERY_NAME, + PROP_BATTERY_NAME, "Battery", "The current battery", G_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); properties[PROP_POWER_LEVEL] = g_param_spec_int ( - POWER_LEVEL_NAME, + PROP_POWER_LEVEL_NAME, "Power Level", "The battery's power level", POWER_LEVEL_OK, @@ -362,7 +364,7 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); properties[PROP_IS_WARNING] = g_param_spec_boolean ( - IS_WARNING_NAME, + PROP_IS_WARNING_NAME, "Is Warning", "Whether or not we're currently warning the user about a low battery", FALSE, @@ -433,6 +435,7 @@ indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, GDBusConnection * bus) { priv_t * p; + GDBusInterfaceSkeleton * skel; g_return_if_fail(INDICATOR_IS_POWER_NOTIFIER(self)); g_return_if_fail((bus == NULL) || G_IS_DBUS_CONNECTION(bus)); @@ -442,12 +445,12 @@ indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, if (p->bus == bus) return; + skel = G_DBUS_INTERFACE_SKELETON(p->dbus_battery); + if (p->bus != NULL) { - if (p->dbus_battery != NULL) - { - g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON(p->dbus_battery)); - } + if (skel != NULL) + g_dbus_interface_skeleton_unexport (skel); g_clear_object (&p->bus); } @@ -459,7 +462,7 @@ indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, p->bus = g_object_ref (bus); error = NULL; - g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(p->dbus_battery), + g_dbus_interface_skeleton_export(skel, bus, BUS_PATH"/Battery", &error); -- cgit v1.2.3 From 2cb851b018c5e7a0278dab75f73bb031c7c42422 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 21 Jul 2014 16:08:29 -0500 Subject: add tests to confirm that the DBus object's PowerLevel property changes at the right times (and only at the right times) when the battery is draining --- src/notifier.c | 92 +++++++++++++++++++++++++++++++++++----------------------- src/notifier.h | 1 + 2 files changed, 56 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 9dd7550..c805413 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -153,28 +153,34 @@ notification_show(IndicatorPowerNotifier * self) **** ***/ -static PowerLevel -get_power_level (const IndicatorPowerDevice * device) +static void +on_battery_property_changed (IndicatorPowerNotifier * self) { - static const double percent_critical = 2.0; - static const double percent_very_low = 5.0; - static const double percent_low = 10.0; + priv_t * p; + PowerLevel power_level; - const gdouble p = indicator_power_device_get_percentage(device); - PowerLevel ret; + g_return_if_fail(INDICATOR_IS_POWER_NOTIFIER(self)); + g_return_if_fail(INDICATOR_IS_POWER_DEVICE(self->priv->battery)); - if (p <= percent_critical) - ret = POWER_LEVEL_CRITICAL; - else if (p <= percent_very_low) - ret = POWER_LEVEL_VERY_LOW; - else if (p <= percent_low) - ret = POWER_LEVEL_LOW; - else - ret = POWER_LEVEL_OK; + p = self->priv; - return ret; + power_level = indicator_power_notifier_get_power_level (p->battery); + + if (p->power_level != power_level) + { + set_power_level_property (self, power_level); + + if ((power_level == POWER_LEVEL_OK) || + (indicator_power_device_get_state(p->battery) != UP_DEVICE_STATE_DISCHARGING)) + { + notification_clear (self); + } + else + { + notification_show (self); + } + } } - /*** **** GObject virtual functions @@ -263,10 +269,10 @@ my_dispose (GObject * o) indicator_power_notifier_set_bus (self, NULL); notification_clear (self); - indicator_power_notifier_set_battery (self, NULL); g_clear_pointer (&p->power_level_binding, g_binding_unbind); g_clear_pointer (&p->is_warning_binding, g_binding_unbind); g_clear_object (&p->dbus_battery); + indicator_power_notifier_set_battery (self, NULL); G_OBJECT_CLASS (indicator_power_notifier_parent_class)->dispose (o); } @@ -327,7 +333,6 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) for (l=caps; l!=NULL && !klass->interactive; l=l->next) if (!g_strcmp0 ("actions", (const char*)l->data)) klass->interactive = TRUE; - g_message ("%s klass->interactive is %d", G_STRLOC, (int)klass->interactive); g_list_free_full (caps, g_free); } } @@ -400,8 +405,12 @@ indicator_power_notifier_set_battery (IndicatorPowerNotifier * self, p = self->priv; + if (p->battery == battery) + return; + if (p->battery != NULL) { + g_signal_handlers_disconnect_by_data (p->battery, self); g_clear_object (&p->battery); set_power_level_property (self, POWER_LEVEL_OK); notification_clear (self); @@ -409,24 +418,12 @@ indicator_power_notifier_set_battery (IndicatorPowerNotifier * self, if (battery != NULL) { - const PowerLevel power_level = get_power_level (battery); - - p->battery = g_object_ref(battery); - - if (p->power_level != power_level) - { - set_power_level_property (self, power_level); - - if ((power_level == POWER_LEVEL_OK) || - (indicator_power_device_get_state(battery) != UP_DEVICE_STATE_DISCHARGING)) - { - notification_clear (self); - } - else - { - notification_show (self); - } - } + p->battery = g_object_ref (battery); + g_signal_connect_swapped (p->battery, "notify::"INDICATOR_POWER_DEVICE_PERCENTAGE, + G_CALLBACK(on_battery_property_changed), self); + g_signal_connect_swapped (p->battery, "notify::"INDICATOR_POWER_DEVICE_STATE, + G_CALLBACK(on_battery_property_changed), self); + on_battery_property_changed (self); } } @@ -474,7 +471,28 @@ indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, } } +PowerLevel +indicator_power_notifier_get_power_level (IndicatorPowerDevice * battery) +{ + static const double percent_critical = 2.0; + static const double percent_very_low = 5.0; + static const double percent_low = 10.0; + gdouble p; + PowerLevel ret; + g_return_val_if_fail(battery != NULL, POWER_LEVEL_OK); + g_return_val_if_fail(indicator_power_device_get_kind(battery) == UP_DEVICE_KIND_BATTERY, POWER_LEVEL_OK); + p = indicator_power_device_get_percentage(battery); + if (p <= percent_critical) + ret = POWER_LEVEL_CRITICAL; + else if (p <= percent_very_low) + ret = POWER_LEVEL_VERY_LOW; + else if (p <= percent_low) + ret = POWER_LEVEL_LOW; + else + ret = POWER_LEVEL_OK; + return ret; +} diff --git a/src/notifier.h b/src/notifier.h index cab053f..0e3ad99 100644 --- a/src/notifier.h +++ b/src/notifier.h @@ -80,6 +80,7 @@ void indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, void indicator_power_notifier_set_battery (IndicatorPowerNotifier * self, IndicatorPowerDevice * battery); +PowerLevel indicator_power_notifier_get_power_level (IndicatorPowerDevice * battery); G_END_DECLS -- cgit v1.2.3 From 1bd1b700892a786fd01410a4b81b2f2cc93a89c1 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 21 Jul 2014 17:13:15 -0500 Subject: add tests for events that change whether or not a 'low battery' notification is being shown --- src/notifier.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index c805413..fc54e62 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -157,28 +157,23 @@ static void on_battery_property_changed (IndicatorPowerNotifier * self) { priv_t * p; - PowerLevel power_level; g_return_if_fail(INDICATOR_IS_POWER_NOTIFIER(self)); g_return_if_fail(INDICATOR_IS_POWER_DEVICE(self->priv->battery)); p = self->priv; - power_level = indicator_power_notifier_get_power_level (p->battery); + set_power_level_property (self, + indicator_power_notifier_get_power_level (p->battery)); - if (p->power_level != power_level) + if ((indicator_power_device_get_state(p->battery) == UP_DEVICE_STATE_DISCHARGING) && + (p->power_level != POWER_LEVEL_OK)) { - set_power_level_property (self, power_level); - - if ((power_level == POWER_LEVEL_OK) || - (indicator_power_device_get_state(p->battery) != UP_DEVICE_STATE_DISCHARGING)) - { - notification_clear (self); - } - else - { - notification_show (self); - } + notification_show (self); + } + else + { + notification_clear (self); } } -- cgit v1.2.3 From 51f39c86f79fef81af296ee03d12a1883b7e015f Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 21 Jul 2014 17:27:49 -0500 Subject: in notifier.c, use g_clear_object to unref the GBindings --- src/notifier.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index fc54e62..80db10d 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -264,8 +264,8 @@ my_dispose (GObject * o) indicator_power_notifier_set_bus (self, NULL); notification_clear (self); - g_clear_pointer (&p->power_level_binding, g_binding_unbind); - g_clear_pointer (&p->is_warning_binding, g_binding_unbind); + g_clear_object (&p->power_level_binding); + g_clear_object (&p->is_warning_binding); g_clear_object (&p->dbus_battery); indicator_power_notifier_set_battery (self, NULL); -- cgit v1.2.3 From 9c3d863d5e0ebe35ae69dedb5219519f0ced9339 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 22 Jul 2014 09:53:53 -0500 Subject: copyediting: code cleanup --- src/notifier.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 80db10d..bf52739 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -73,8 +73,11 @@ struct _IndicatorPowerNotifierPrivate typedef IndicatorPowerNotifierPrivate priv_t; -static void set_is_warning_property (IndicatorPowerNotifier*, gboolean is_warning); -static void set_power_level_property (IndicatorPowerNotifier*, PowerLevel power_level); +static void set_is_warning_property (IndicatorPowerNotifier*, + gboolean is_warning); + +static void set_power_level_property (IndicatorPowerNotifier*, + PowerLevel power_level); /*** **** Notifications @@ -101,7 +104,7 @@ on_notification_clicked(NotifyNotification * notify_notification G_GNUC_UNUSED, char * action G_GNUC_UNUSED, gpointer gself G_GNUC_UNUSED) { - /* no-op; notify_notification_add_action() doesn't like NULL callbacks */ + /* no-op: notify_notification_add_action() doesn't like NULL callbacks */ } static void @@ -183,9 +186,9 @@ on_battery_property_changed (IndicatorPowerNotifier * self) static void my_get_property (GObject * o, - guint property_id, - GValue * value, - GParamSpec * pspec) + guint property_id, + GValue * value, + GParamSpec * pspec) { IndicatorPowerNotifier * self = INDICATOR_POWER_NOTIFIER (o); priv_t * p = self->priv; @@ -296,6 +299,8 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) IndicatorPowerNotifierPrivate); self->priv = p; + /* bind the read-only properties so they'll get pushed to the bus */ + p->dbus_battery = dbus_battery_skeleton_new (); p->is_warning_binding = g_object_bind_property (self, @@ -330,6 +335,7 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) klass->interactive = TRUE; g_list_free_full (caps, g_free); } + g_debug ("Will show popups on low battery: %d", (int)klass->interactive); } } -- cgit v1.2.3 From dd5f50b07bea7a5dec515a753cf66f060e1d79c6 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 22 Jul 2014 09:54:36 -0500 Subject: when a device changes, update the header action state even if the menus haven't been created yet. This fixes a startup condition found by the tests. --- src/service.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 23cef84..0cd448b 100644 --- a/src/service.c +++ b/src/service.c @@ -595,14 +595,14 @@ rebuild_now (IndicatorPowerService * self, guint sections) struct ProfileMenuInfo * desktop = &p->menus[PROFILE_DESKTOP]; struct ProfileMenuInfo * greeter = &p->menus[PROFILE_DESKTOP_GREETER]; - if (p->conn == NULL) /* we haven't built the menus yet */ - return; - if (sections & SECTION_HEADER) { g_simple_action_set_state (p->header_action, create_header_state (self)); } + if (p->conn == NULL) /* we haven't built the menus yet */ + return; + if (sections & SECTION_DEVICES) { rebuild_section (desktop->submenu, 0, create_desktop_devices_section (self, PROFILE_DESKTOP)); -- cgit v1.2.3 From 7ecf18c675f4cc65d6e8314e492dba214ec6ae9c Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 22 Jul 2014 11:27:07 -0500 Subject: for now, only show Ephemeral notifications when the battery gets low. --- src/notifier.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index bf52739..2d2730e 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -99,46 +99,36 @@ notification_clear (IndicatorPowerNotifier * self) } } -static void -on_notification_clicked(NotifyNotification * notify_notification G_GNUC_UNUSED, - char * action G_GNUC_UNUSED, - gpointer gself G_GNUC_UNUSED) -{ - /* no-op: notify_notification_add_action() doesn't like NULL callbacks */ -} - static void notification_show(IndicatorPowerNotifier * self) { priv_t * p; char * body; - NotifyNotification * nn; GError * error; notification_clear (self); +#if 0 /* using Ephemeral no-button notifications for right now; + however this will likely change so I'm not tearing the + NotifierClass.interactive code out just yet */ + /* only show clickable notifications if the Notify server supports them */ if (!INDICATOR_POWER_NOTIFIER_GET_CLASS(self)->interactive) return; +#endif p = self->priv; /* create the notification */ body = g_strdup_printf(_("%.0f%% charge remaining"), indicator_power_device_get_percentage(p->battery)); - nn = notify_notification_new(_("Battery Low"), body, NULL); - p->notify_notification = nn; - notify_notification_set_hint(nn, "x-canonical-snap-decisions", - g_variant_new_boolean(TRUE)); - notify_notification_set_hint(nn, "x-canonical-private-button-tint", - g_variant_new_boolean(TRUE)); - notify_notification_add_action(nn, "OK", _("OK"), - on_notification_clicked, self, NULL); - g_signal_connect_swapped(nn, "closed", G_CALLBACK(notification_clear), self); + p->notify_notification = notify_notification_new(_("Battery Low"), body, NULL); + g_signal_connect_swapped(p->notify_notification, "closed", + G_CALLBACK(notification_clear), self); /* show the notification */ error = NULL; - notify_notification_show(nn, &error); + notify_notification_show(p->notify_notification, &error); if (error != NULL) { g_critical("Unable to show snap decision for '%s': %s", body, error->message); -- cgit v1.2.3 From 79a3d892c39ba831e44871ca99a064084bd792e9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 22 Jul 2014 11:59:59 -0500 Subject: Filter out some redundant warnings -- e.g., don't notify when the power percentage drops from 10% to 9%, only when it crosses a PowerLevel threshold --- src/notifier.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 2d2730e..326f5a1 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -61,6 +61,7 @@ struct _IndicatorPowerNotifierPrivate See indicator_power_service_choose_primary_device() */ IndicatorPowerDevice * battery; PowerLevel power_level; + gboolean discharging; NotifyNotification* notify_notification; gboolean is_warning; @@ -150,17 +151,25 @@ static void on_battery_property_changed (IndicatorPowerNotifier * self) { priv_t * p; + PowerLevel old_power_level; + PowerLevel new_power_level; + gboolean old_discharging; + gboolean new_discharging; g_return_if_fail(INDICATOR_IS_POWER_NOTIFIER(self)); g_return_if_fail(INDICATOR_IS_POWER_DEVICE(self->priv->battery)); p = self->priv; - set_power_level_property (self, - indicator_power_notifier_get_power_level (p->battery)); + old_power_level = p->power_level; + new_power_level = indicator_power_notifier_get_power_level (p->battery); - if ((indicator_power_device_get_state(p->battery) == UP_DEVICE_STATE_DISCHARGING) && - (p->power_level != POWER_LEVEL_OK)) + old_discharging = p->discharging; + new_discharging = indicator_power_device_get_state(p->battery) == UP_DEVICE_STATE_DISCHARGING; + + if (new_discharging && + (new_power_level != POWER_LEVEL_OK) && + ((new_power_level != old_power_level) || (new_discharging != old_discharging))) { notification_show (self); } @@ -168,6 +177,9 @@ on_battery_property_changed (IndicatorPowerNotifier * self) { notification_clear (self); } + + set_power_level_property (self, new_power_level); + p->discharging = new_discharging; } /*** -- cgit v1.2.3 From 1f98321fa6139105a1b427a2dac2b4e2b0642dd6 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 22 Jul 2014 12:19:20 -0500 Subject: make the notification popup decision logic simpler & easier to read --- src/notifier.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 326f5a1..81662ca 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -167,9 +167,11 @@ on_battery_property_changed (IndicatorPowerNotifier * self) old_discharging = p->discharging; new_discharging = indicator_power_device_get_state(p->battery) == UP_DEVICE_STATE_DISCHARGING; - if (new_discharging && - (new_power_level != POWER_LEVEL_OK) && - ((new_power_level != old_power_level) || (new_discharging != old_discharging))) + /* pop up a notification for a battery whenever either: + a) it's already discharging, and its PowerLevel worsens, OR + b) it's already got a bad PowerLevel and its state becomes 'discharging */ + if ((new_discharging && (new_power_level > old_power_level)) || + ((new_power_level != POWER_LEVEL_OK) && new_discharging && !old_discharging)) { notification_show (self); } -- cgit v1.2.3 From a8ea5a0304e5ee14ee93532f0bc960c99039356a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 23 Jul 2014 16:04:02 -0500 Subject: remove now-unused code that tests whether the Notify server supports actions --- src/notifier.c | 23 ----------------------- src/notifier.h | 1 - 2 files changed, 24 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 81662ca..f9f3ff6 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -109,15 +109,6 @@ notification_show(IndicatorPowerNotifier * self) notification_clear (self); -#if 0 /* using Ephemeral no-button notifications for right now; - however this will likely change so I'm not tearing the - NotifierClass.interactive code out just yet */ - - /* only show clickable notifications if the Notify server supports them */ - if (!INDICATOR_POWER_NOTIFIER_GET_CLASS(self)->interactive) - return; -#endif - p = self->priv; /* create the notification */ @@ -327,19 +318,6 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) { g_critical("Unable to initialize libnotify! Notifications might not be shown."); } - else - { - /* See if the notification server supports clickable actions... */ - GList * caps; - GList * l; - klass->interactive = FALSE; - caps = notify_get_server_caps(); - for (l=caps; l!=NULL && !klass->interactive; l=l->next) - if (!g_strcmp0 ("actions", (const char*)l->data)) - klass->interactive = TRUE; - g_list_free_full (caps, g_free); - } - g_debug ("Will show popups on low battery: %d", (int)klass->interactive); } } @@ -383,7 +361,6 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) g_object_class_install_properties (object_class, LAST_PROP, properties); klass->instance_count = 0; - klass->interactive = FALSE; } /*** diff --git a/src/notifier.h b/src/notifier.h index 0e3ad99..dddb6e9 100644 --- a/src/notifier.h +++ b/src/notifier.h @@ -63,7 +63,6 @@ struct _IndicatorPowerNotifierClass /*< private >*/ gint instance_count; - gboolean interactive; }; /*** -- cgit v1.2.3 From a62291be0e2ae4e16647d3cdb5c329ef61356fc7 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 23 Jul 2014 16:04:20 -0500 Subject: copyediting --- src/notifier.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index f9f3ff6..364628c 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -96,7 +96,6 @@ notification_clear (IndicatorPowerNotifier * self) notify_notification_clear_actions(p->notify_notification); g_signal_handlers_disconnect_by_data(p->notify_notification, self); g_clear_object(&p->notify_notification); - } } -- cgit v1.2.3 From bf934569374d2f15567e955c058c271d1072df7b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 23 Jul 2014 16:09:00 -0500 Subject: make the notifications click-to-dismiss by adding the 'interactive notification' hint --- src/notifier.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 364628c..8c12dfc 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -26,6 +26,8 @@ #include #include +#define HINT_INTERACTIVE "x-canonical-switch-to-application" + G_DEFINE_TYPE(IndicatorPowerNotifier, indicator_power_notifier, G_TYPE_OBJECT) @@ -114,6 +116,9 @@ notification_show(IndicatorPowerNotifier * self) body = g_strdup_printf(_("%.0f%% charge remaining"), indicator_power_device_get_percentage(p->battery)); p->notify_notification = notify_notification_new(_("Battery Low"), body, NULL); + notify_notification_set_hint(p->notify_notification, + HINT_INTERACTIVE, + g_variant_new_boolean(TRUE)); g_signal_connect_swapped(p->notify_notification, "closed", G_CALLBACK(notification_clear), self); -- cgit v1.2.3 From aba9e6261a6f02c501fa690e12babbbc8eea3a53 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 23 Jul 2014 16:18:33 -0500 Subject: copyediting: slightly better comments. --- src/notifier.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 8c12dfc..62952e6 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -58,9 +58,10 @@ static GParamSpec * properties[LAST_PROP]; struct _IndicatorPowerNotifierPrivate { /* The battery we're currently watching. - This may be a physical battery or it may be a "merged" battery - synthesized from multiple batteries present on the device. - See indicator_power_service_choose_primary_device() */ + This may be a physical battery or it may be an aggregated + battery from multiple batteries present on the device. + See indicator_power_service_choose_primary_device() and + bug #880881 */ IndicatorPowerDevice * battery; PowerLevel power_level; gboolean discharging; @@ -68,10 +69,10 @@ struct _IndicatorPowerNotifierPrivate NotifyNotification* notify_notification; gboolean is_warning; - DbusBattery * dbus_battery; - GBinding * is_warning_binding; - GBinding * power_level_binding; GDBusConnection * bus; + DbusBattery * dbus_battery; /* com.canonical.indicator.power.Battery skeleton */ + GBinding * is_warning_binding; /* pushes our property to dbus_battery */ + GBinding * power_level_binding; /* pushes our property to dbus_battery */ }; typedef IndicatorPowerNotifierPrivate priv_t; @@ -162,7 +163,7 @@ on_battery_property_changed (IndicatorPowerNotifier * self) old_discharging = p->discharging; new_discharging = indicator_power_device_get_state(p->battery) == UP_DEVICE_STATE_DISCHARGING; - /* pop up a notification for a battery whenever either: + /* pop up a 'low battery' notification if either: a) it's already discharging, and its PowerLevel worsens, OR b) it's already got a bad PowerLevel and its state becomes 'discharging */ if ((new_discharging && (new_power_level > old_power_level)) || -- cgit v1.2.3 From d185409f22c859e3c29bf387955d195a5cd884c3 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 23 Jul 2014 16:22:27 -0500 Subject: remove instance_count from IndicatorPowerNotifierClass --- src/notifier.c | 18 ++++++++---------- src/notifier.h | 3 --- 2 files changed, 8 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 62952e6..c6b0025 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -51,6 +51,8 @@ enum static GParamSpec * properties[LAST_PROP]; +static int instance_count = 0; + /** *** **/ @@ -276,11 +278,12 @@ my_dispose (GObject * o) } static void -my_finalize (GObject * o) +my_finalize (GObject * o G_GNUC_UNUSED) { - IndicatorPowerNotifierClass * klass = INDICATOR_POWER_NOTIFIER_GET_CLASS(o); - - if (!--klass->instance_count) + /* FIXME: This is an awkward place to put this. + Ordinarily something like this would go in main(), but we need libnotify + to clean itself up before shutting down the bus in the unit tests as well. */ + if (!--instance_count) notify_uninit(); } @@ -292,7 +295,6 @@ static void indicator_power_notifier_init (IndicatorPowerNotifier * self) { priv_t * p; - IndicatorPowerNotifierClass * klass; p = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_TYPE_POWER_NOTIFIER, @@ -315,9 +317,7 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) PROP_POWER_LEVEL_NAME, G_BINDING_SYNC_CREATE); - klass = INDICATOR_POWER_NOTIFIER_GET_CLASS(self); - - if (!klass->instance_count++) + if (!instance_count++) { if (!notify_init("indicator-power-service")) { @@ -364,8 +364,6 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, LAST_PROP, properties); - - klass->instance_count = 0; } /*** diff --git a/src/notifier.h b/src/notifier.h index dddb6e9..8763ad6 100644 --- a/src/notifier.h +++ b/src/notifier.h @@ -60,9 +60,6 @@ struct _IndicatorPowerNotifier struct _IndicatorPowerNotifierClass { GObjectClass parent_class; - - /*< private >*/ - gint instance_count; }; /*** -- cgit v1.2.3 From f4e1a83d20cad3afa6dd51a4a520ef21ccaff5cd Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 24 Jul 2014 15:14:20 -0500 Subject: in notifier.c, don't keep pointers to the bindings around as they're cleaned up automatically when either of the objects is destroyed. --- src/notifier.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index c6b0025..1986f8c 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -73,8 +73,6 @@ struct _IndicatorPowerNotifierPrivate GDBusConnection * bus; DbusBattery * dbus_battery; /* com.canonical.indicator.power.Battery skeleton */ - GBinding * is_warning_binding; /* pushes our property to dbus_battery */ - GBinding * power_level_binding; /* pushes our property to dbus_battery */ }; typedef IndicatorPowerNotifierPrivate priv_t; @@ -269,8 +267,6 @@ my_dispose (GObject * o) indicator_power_notifier_set_bus (self, NULL); notification_clear (self); - g_clear_object (&p->power_level_binding); - g_clear_object (&p->is_warning_binding); g_clear_object (&p->dbus_battery); indicator_power_notifier_set_battery (self, NULL); @@ -305,17 +301,17 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) p->dbus_battery = dbus_battery_skeleton_new (); - p->is_warning_binding = g_object_bind_property (self, - PROP_IS_WARNING_NAME, - p->dbus_battery, - PROP_IS_WARNING_NAME, - G_BINDING_SYNC_CREATE); - - p->power_level_binding = g_object_bind_property (self, - PROP_POWER_LEVEL_NAME, - p->dbus_battery, - PROP_POWER_LEVEL_NAME, - G_BINDING_SYNC_CREATE); + g_object_bind_property (self, + PROP_IS_WARNING_NAME, + p->dbus_battery, + PROP_IS_WARNING_NAME, + G_BINDING_SYNC_CREATE); + + g_object_bind_property (self, + PROP_POWER_LEVEL_NAME, + p->dbus_battery, + PROP_POWER_LEVEL_NAME, + G_BINDING_SYNC_CREATE); if (!instance_count++) { -- cgit v1.2.3 From 11784e2e354b5538b6fbccd9df1e6259c9ebc6f0 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 24 Jul 2014 15:15:09 -0500 Subject: don't set to zero fields in a struct that's been calloc()ed already. --- src/notifier.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 1986f8c..c091f73 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -334,8 +334,6 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) g_type_class_add_private (klass, sizeof (IndicatorPowerNotifierPrivate)); - properties[PROP_0] = NULL; - properties[PROP_BATTERY] = g_param_spec_object ( PROP_BATTERY_NAME, "Battery", -- cgit v1.2.3 From 62a35de9ca05c71d98680b1e49c2c345a498acda Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 24 Jul 2014 15:17:32 -0500 Subject: check the return value of g_dbus_interface_skeleton_export() directly instead of indirectly testing to see if the GError it used is nonnull. --- src/notifier.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index c091f73..30285d3 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -438,11 +438,10 @@ indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, p->bus = g_object_ref (bus); error = NULL; - g_dbus_interface_skeleton_export(skel, - bus, - BUS_PATH"/Battery", - &error); - if (error != NULL) + if (!g_dbus_interface_skeleton_export(skel, + bus, + BUS_PATH"/Battery", + &error)) { g_warning ("Unable to export LowBattery properties: %s", error->message); g_error_free (error); -- cgit v1.2.3 From 34cf2baf977650c60b53bf5a1e90bfec8b642ec9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 24 Jul 2014 15:20:16 -0500 Subject: remove redundant '#include glib', '#include gobject' calls --- src/device.h | 1 - src/notifier.c | 1 - src/notifier.h | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/device.h b/src/device.h index 77d34ef..d867707 100644 --- a/src/device.h +++ b/src/device.h @@ -24,7 +24,6 @@ License along with this library. If not, see #ifndef __INDICATOR_POWER_DEVICE_H__ #define __INDICATOR_POWER_DEVICE_H__ -#include #include /* GIcon */ G_BEGIN_DECLS diff --git a/src/notifier.c b/src/notifier.c index 30285d3..29f678a 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -24,7 +24,6 @@ #include #include -#include #define HINT_INTERACTIVE "x-canonical-switch-to-application" diff --git a/src/notifier.h b/src/notifier.h index 8763ad6..f473ee7 100644 --- a/src/notifier.h +++ b/src/notifier.h @@ -20,9 +20,7 @@ #ifndef __INDICATOR_POWER_NOTIFIER_H__ #define __INDICATOR_POWER_NOTIFIER_H__ -#include -#include -#include /* GDBusConnection */ +#include #include "device.h" -- cgit v1.2.3 From b715352603062a4a4dbb5bc69388b1db632c34ae Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 24 Jul 2014 21:25:22 -0500 Subject: in notifier, use G_DEFINE_TYPE_WITH_PRIVATE --- src/notifier.c | 51 +++++++++++++++++++++++---------------------------- src/notifier.h | 2 -- 2 files changed, 23 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 29f678a..1ac7e32 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -27,10 +27,6 @@ #define HINT_INTERACTIVE "x-canonical-switch-to-application" -G_DEFINE_TYPE(IndicatorPowerNotifier, - indicator_power_notifier, - G_TYPE_OBJECT) - /** *** GObject Properties **/ @@ -56,7 +52,7 @@ static int instance_count = 0; *** **/ -struct _IndicatorPowerNotifierPrivate +typedef struct { /* The battery we're currently watching. This may be a physical battery or it may be an aggregated @@ -72,10 +68,17 @@ struct _IndicatorPowerNotifierPrivate GDBusConnection * bus; DbusBattery * dbus_battery; /* com.canonical.indicator.power.Battery skeleton */ -}; +} +IndicatorPowerNotifierPrivate; typedef IndicatorPowerNotifierPrivate priv_t; +G_DEFINE_TYPE_WITH_PRIVATE(IndicatorPowerNotifier, + indicator_power_notifier, + G_TYPE_OBJECT) + +#define get_priv(o) ((priv_t*)indicator_power_notifier_get_instance_private(o)) + static void set_is_warning_property (IndicatorPowerNotifier*, gboolean is_warning); @@ -89,7 +92,7 @@ static void set_power_level_property (IndicatorPowerNotifier*, static void notification_clear (IndicatorPowerNotifier * self) { - priv_t * p = self->priv; + priv_t * const p = get_priv(self); if (p->notify_notification != NULL) { @@ -110,7 +113,7 @@ notification_show(IndicatorPowerNotifier * self) notification_clear (self); - p = self->priv; + p = get_priv (self); /* create the notification */ body = g_strdup_printf(_("%.0f%% charge remaining"), @@ -152,9 +155,8 @@ on_battery_property_changed (IndicatorPowerNotifier * self) gboolean new_discharging; g_return_if_fail(INDICATOR_IS_POWER_NOTIFIER(self)); - g_return_if_fail(INDICATOR_IS_POWER_DEVICE(self->priv->battery)); - - p = self->priv; + p = get_priv (self); + g_return_if_fail(INDICATOR_IS_POWER_DEVICE(p->battery)); old_power_level = p->power_level; new_power_level = indicator_power_notifier_get_power_level (p->battery); @@ -189,8 +191,8 @@ my_get_property (GObject * o, GValue * value, GParamSpec * pspec) { - IndicatorPowerNotifier * self = INDICATOR_POWER_NOTIFIER (o); - priv_t * p = self->priv; + IndicatorPowerNotifier * const self = INDICATOR_POWER_NOTIFIER (o); + priv_t * const p = get_priv (self); switch (property_id) { @@ -217,7 +219,7 @@ my_set_property (GObject * o, const GValue * value, GParamSpec * pspec) { - IndicatorPowerNotifier * self = INDICATOR_POWER_NOTIFIER (o); + IndicatorPowerNotifier * const self = INDICATOR_POWER_NOTIFIER (o); switch (property_id) { @@ -234,7 +236,7 @@ my_set_property (GObject * o, static void set_is_warning_property (IndicatorPowerNotifier * self, gboolean is_warning) { - priv_t * p = self->priv; + priv_t * const p = get_priv (self); if (p->is_warning != is_warning) { @@ -248,7 +250,7 @@ set_is_warning_property (IndicatorPowerNotifier * self, gboolean is_warning) static void set_power_level_property (IndicatorPowerNotifier * self, PowerLevel power_level) { - priv_t * p = self->priv; + priv_t * const p = get_priv (self); if (p->power_level != power_level) { @@ -261,8 +263,8 @@ set_power_level_property (IndicatorPowerNotifier * self, PowerLevel power_level) static void my_dispose (GObject * o) { - IndicatorPowerNotifier * self = INDICATOR_POWER_NOTIFIER(o); - priv_t * p = self->priv; + IndicatorPowerNotifier * const self = INDICATOR_POWER_NOTIFIER(o); + priv_t * const p = get_priv (self); indicator_power_notifier_set_bus (self, NULL); notification_clear (self); @@ -289,12 +291,7 @@ my_finalize (GObject * o G_GNUC_UNUSED) static void indicator_power_notifier_init (IndicatorPowerNotifier * self) { - priv_t * p; - - p = G_TYPE_INSTANCE_GET_PRIVATE (self, - INDICATOR_TYPE_POWER_NOTIFIER, - IndicatorPowerNotifierPrivate); - self->priv = p; + priv_t * const p = get_priv (self); /* bind the read-only properties so they'll get pushed to the bus */ @@ -331,8 +328,6 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) object_class->get_property = my_get_property; object_class->set_property = my_set_property; - g_type_class_add_private (klass, sizeof (IndicatorPowerNotifierPrivate)); - properties[PROP_BATTERY] = g_param_spec_object ( PROP_BATTERY_NAME, "Battery", @@ -381,7 +376,7 @@ indicator_power_notifier_set_battery (IndicatorPowerNotifier * self, g_return_if_fail((battery == NULL) || INDICATOR_IS_POWER_DEVICE(battery)); g_return_if_fail((battery == NULL) || (indicator_power_device_get_kind(battery) == UP_DEVICE_KIND_BATTERY)); - p = self->priv; + p = get_priv (self); if (p->battery == battery) return; @@ -415,7 +410,7 @@ indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, g_return_if_fail(INDICATOR_IS_POWER_NOTIFIER(self)); g_return_if_fail((bus == NULL) || G_IS_DBUS_CONNECTION(bus)); - p = self->priv; + p = get_priv (self); if (p->bus == bus) return; diff --git a/src/notifier.h b/src/notifier.h index f473ee7..c23c585 100644 --- a/src/notifier.h +++ b/src/notifier.h @@ -34,7 +34,6 @@ G_BEGIN_DECLS typedef struct _IndicatorPowerNotifier IndicatorPowerNotifier; typedef struct _IndicatorPowerNotifierClass IndicatorPowerNotifierClass; -typedef struct _IndicatorPowerNotifierPrivate IndicatorPowerNotifierPrivate; typedef enum { @@ -52,7 +51,6 @@ struct _IndicatorPowerNotifier { /*< private >*/ GObject parent; - IndicatorPowerNotifierPrivate * priv; }; struct _IndicatorPowerNotifierClass -- cgit v1.2.3 From e9ba47b83251f40234059b1bd2bc25e30b5aa9b2 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 24 Jul 2014 22:51:03 -0500 Subject: in notifier.c, fix potential callchain loop when closing a notification --- src/notifier.c | 68 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 1ac7e32..dc3a186 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -89,56 +89,72 @@ static void set_power_level_property (IndicatorPowerNotifier*, **** Notifications ***/ +static void +on_notify_notification_finalized (gpointer gself, GObject * dead) +{ + IndicatorPowerNotifier * const self = INDICATOR_POWER_NOTIFIER(gself); + priv_t * const p = get_priv(self); + g_return_if_fail ((void*)(p->notify_notification) == (void*)dead); + p->notify_notification = NULL; + set_is_warning_property (self, FALSE); +} + static void notification_clear (IndicatorPowerNotifier * self) { priv_t * const p = get_priv(self); + NotifyNotification * nn; - if (p->notify_notification != NULL) + if ((nn = p->notify_notification)) { - set_is_warning_property (self, FALSE); + GError * error = NULL; + + g_object_weak_unref(G_OBJECT(nn), on_notify_notification_finalized, self); - notify_notification_clear_actions(p->notify_notification); - g_signal_handlers_disconnect_by_data(p->notify_notification, self); - g_clear_object(&p->notify_notification); + if (!notify_notification_close(nn, &error)) + { + g_warning("Unable to close notification: %s", error->message); + g_error_free(error); + } + + p->notify_notification = NULL; + set_is_warning_property(self, FALSE); } } static void notification_show(IndicatorPowerNotifier * self) { - priv_t * p; + priv_t * const p = get_priv(self); + gdouble pct; char * body; + NotifyNotification * nn; GError * error; - notification_clear (self); - - p = get_priv (self); + notification_clear(self); /* create the notification */ - body = g_strdup_printf(_("%.0f%% charge remaining"), - indicator_power_device_get_percentage(p->battery)); - p->notify_notification = notify_notification_new(_("Battery Low"), body, NULL); - notify_notification_set_hint(p->notify_notification, - HINT_INTERACTIVE, - g_variant_new_boolean(TRUE)); - g_signal_connect_swapped(p->notify_notification, "closed", - G_CALLBACK(notification_clear), self); - - /* show the notification */ + pct = indicator_power_device_get_percentage(p->battery); + body = g_strdup_printf(_("%.0f%% charge remaining"), pct); + nn = notify_notification_new(_("Battery Low"), body, NULL); + g_free (body); + notify_notification_set_hint(nn, HINT_INTERACTIVE, g_variant_new_boolean(TRUE)); + + /* if we can show it, keep it */ error = NULL; - notify_notification_show(p->notify_notification, &error); - if (error != NULL) + if (notify_notification_show(nn, &error)) { - g_critical("Unable to show snap decision for '%s': %s", body, error->message); - g_error_free(error); + p->notify_notification = nn; + g_signal_connect(nn, "closed", G_CALLBACK(g_object_unref), NULL); + g_object_weak_ref(G_OBJECT(nn), on_notify_notification_finalized, self); + set_is_warning_property(self, TRUE); } else { - set_is_warning_property (self, TRUE); + g_critical("Unable to show snap decision for '%s': %s", body, error->message); + g_error_free(error); + g_object_unref(nn); } - - g_free (body); } /*** -- cgit v1.2.3 From 079ac51da565af4882b79c14b3a4782e5c919dd3 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 24 Jul 2014 23:13:52 -0500 Subject: in notifier.c, remove unnecessary middleman properties and deal with the dbus-battery properties directly. --- src/notifier.c | 89 +++++----------------------------------------------------- 1 file changed, 7 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index dc3a186..60799f9 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -35,14 +35,10 @@ enum { PROP_0, PROP_BATTERY, - PROP_IS_WARNING, - PROP_POWER_LEVEL, LAST_PROP }; #define PROP_BATTERY_NAME "battery" -#define PROP_IS_WARNING_NAME "is-warning" -#define PROP_POWER_LEVEL_NAME "power-level" static GParamSpec * properties[LAST_PROP]; @@ -63,8 +59,7 @@ typedef struct PowerLevel power_level; gboolean discharging; - NotifyNotification* notify_notification; - gboolean is_warning; + NotifyNotification * notify_notification; GDBusConnection * bus; DbusBattery * dbus_battery; /* com.canonical.indicator.power.Battery skeleton */ @@ -79,12 +74,6 @@ G_DEFINE_TYPE_WITH_PRIVATE(IndicatorPowerNotifier, #define get_priv(o) ((priv_t*)indicator_power_notifier_get_instance_private(o)) -static void set_is_warning_property (IndicatorPowerNotifier*, - gboolean is_warning); - -static void set_power_level_property (IndicatorPowerNotifier*, - PowerLevel power_level); - /*** **** Notifications ***/ @@ -96,7 +85,7 @@ on_notify_notification_finalized (gpointer gself, GObject * dead) priv_t * const p = get_priv(self); g_return_if_fail ((void*)(p->notify_notification) == (void*)dead); p->notify_notification = NULL; - set_is_warning_property (self, FALSE); + dbus_battery_set_is_warning (p->dbus_battery, FALSE); } static void @@ -118,7 +107,7 @@ notification_clear (IndicatorPowerNotifier * self) } p->notify_notification = NULL; - set_is_warning_property(self, FALSE); + dbus_battery_set_is_warning (p->dbus_battery, FALSE); } } @@ -147,7 +136,7 @@ notification_show(IndicatorPowerNotifier * self) p->notify_notification = nn; g_signal_connect(nn, "closed", G_CALLBACK(g_object_unref), NULL); g_object_weak_ref(G_OBJECT(nn), on_notify_notification_finalized, self); - set_is_warning_property(self, TRUE); + dbus_battery_set_is_warning (p->dbus_battery, TRUE); } else { @@ -193,7 +182,7 @@ on_battery_property_changed (IndicatorPowerNotifier * self) notification_clear (self); } - set_power_level_property (self, new_power_level); + dbus_battery_set_power_level (p->dbus_battery, new_power_level); p->discharging = new_discharging; } @@ -216,14 +205,6 @@ my_get_property (GObject * o, g_value_set_object (value, p->battery); break; - case PROP_POWER_LEVEL: - g_value_set_int (value, p->power_level); - break; - - case PROP_IS_WARNING: - g_value_set_boolean (value, p->is_warning); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); } @@ -248,34 +229,6 @@ my_set_property (GObject * o, } } -/* read-only property, so not implemented in my_set_property() */ -static void -set_is_warning_property (IndicatorPowerNotifier * self, gboolean is_warning) -{ - priv_t * const p = get_priv (self); - - if (p->is_warning != is_warning) - { - p->is_warning = is_warning; - - g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_IS_WARNING]); - } -} - -/* read-only property, so not implemented in my_set_property() */ -static void -set_power_level_property (IndicatorPowerNotifier * self, PowerLevel power_level) -{ - priv_t * const p = get_priv (self); - - if (p->power_level != power_level) - { - p->power_level = power_level; - - g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_POWER_LEVEL]); - } -} - static void my_dispose (GObject * o) { @@ -284,8 +237,8 @@ my_dispose (GObject * o) indicator_power_notifier_set_bus (self, NULL); notification_clear (self); - g_clear_object (&p->dbus_battery); indicator_power_notifier_set_battery (self, NULL); + g_clear_object (&p->dbus_battery); G_OBJECT_CLASS (indicator_power_notifier_parent_class)->dispose (o); } @@ -313,18 +266,6 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) p->dbus_battery = dbus_battery_skeleton_new (); - g_object_bind_property (self, - PROP_IS_WARNING_NAME, - p->dbus_battery, - PROP_IS_WARNING_NAME, - G_BINDING_SYNC_CREATE); - - g_object_bind_property (self, - PROP_POWER_LEVEL_NAME, - p->dbus_battery, - PROP_POWER_LEVEL_NAME, - G_BINDING_SYNC_CREATE); - if (!instance_count++) { if (!notify_init("indicator-power-service")) @@ -351,22 +292,6 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) G_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - properties[PROP_POWER_LEVEL] = g_param_spec_int ( - PROP_POWER_LEVEL_NAME, - "Power Level", - "The battery's power level", - POWER_LEVEL_OK, - POWER_LEVEL_CRITICAL, - POWER_LEVEL_OK, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - properties[PROP_IS_WARNING] = g_param_spec_boolean ( - PROP_IS_WARNING_NAME, - "Is Warning", - "Whether or not we're currently warning the user about a low battery", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_properties (object_class, LAST_PROP, properties); } @@ -401,7 +326,7 @@ indicator_power_notifier_set_battery (IndicatorPowerNotifier * self, { g_signal_handlers_disconnect_by_data (p->battery, self); g_clear_object (&p->battery); - set_power_level_property (self, POWER_LEVEL_OK); + dbus_battery_set_power_level (p->dbus_battery, POWER_LEVEL_OK); notification_clear (self); } -- cgit v1.2.3 From f15482d3f189c378d4e4cf2dfc69eefa522b30aa Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 24 Jul 2014 23:31:11 -0500 Subject: on the bus, publish the battery's power_level as strings rather than ints --- src/notifier.c | 81 ++++++++++++++++++++++++++++++++++++++++------------------ src/notifier.h | 15 ++++------- 2 files changed, 61 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 60799f9..7add139 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -27,6 +27,15 @@ #define HINT_INTERACTIVE "x-canonical-switch-to-application" +typedef enum +{ + POWER_LEVEL_OK, + POWER_LEVEL_LOW, + POWER_LEVEL_VERY_LOW, + POWER_LEVEL_CRITICAL +} +PowerLevel; + /** *** GObject Properties **/ @@ -74,6 +83,48 @@ G_DEFINE_TYPE_WITH_PRIVATE(IndicatorPowerNotifier, #define get_priv(o) ((priv_t*)indicator_power_notifier_get_instance_private(o)) +/*** +**** +***/ + +static const char * +power_level_to_dbus_string (const PowerLevel power_level) +{ + switch (power_level) + { + case POWER_LEVEL_LOW: return "low"; + case POWER_LEVEL_VERY_LOW: return "very_low"; + case POWER_LEVEL_CRITICAL: return "critical"; + default: return "ok"; + } +} + +PowerLevel +get_battery_power_level (IndicatorPowerDevice * battery) +{ + static const double percent_critical = 2.0; + static const double percent_very_low = 5.0; + static const double percent_low = 10.0; + gdouble p; + PowerLevel ret; + + g_return_val_if_fail(battery != NULL, POWER_LEVEL_OK); + g_return_val_if_fail(indicator_power_device_get_kind(battery) == UP_DEVICE_KIND_BATTERY, POWER_LEVEL_OK); + + p = indicator_power_device_get_percentage(battery); + + if (p <= percent_critical) + ret = POWER_LEVEL_CRITICAL; + else if (p <= percent_very_low) + ret = POWER_LEVEL_VERY_LOW; + else if (p <= percent_low) + ret = POWER_LEVEL_LOW; + else + ret = POWER_LEVEL_OK; + + return ret; +} + /*** **** Notifications ***/ @@ -164,7 +215,7 @@ on_battery_property_changed (IndicatorPowerNotifier * self) g_return_if_fail(INDICATOR_IS_POWER_DEVICE(p->battery)); old_power_level = p->power_level; - new_power_level = indicator_power_notifier_get_power_level (p->battery); + new_power_level = get_battery_power_level (p->battery); old_discharging = p->discharging; new_discharging = indicator_power_device_get_state(p->battery) == UP_DEVICE_STATE_DISCHARGING; @@ -182,7 +233,7 @@ on_battery_property_changed (IndicatorPowerNotifier * self) notification_clear (self); } - dbus_battery_set_power_level (p->dbus_battery, new_power_level); + dbus_battery_set_power_level (p->dbus_battery, power_level_to_dbus_string (new_power_level)); p->discharging = new_discharging; } @@ -326,7 +377,7 @@ indicator_power_notifier_set_battery (IndicatorPowerNotifier * self, { g_signal_handlers_disconnect_by_data (p->battery, self); g_clear_object (&p->battery); - dbus_battery_set_power_level (p->dbus_battery, POWER_LEVEL_OK); + dbus_battery_set_power_level (p->dbus_battery, power_level_to_dbus_string (POWER_LEVEL_OK)); notification_clear (self); } @@ -384,28 +435,8 @@ indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, } } -PowerLevel +const char * indicator_power_notifier_get_power_level (IndicatorPowerDevice * battery) { - static const double percent_critical = 2.0; - static const double percent_very_low = 5.0; - static const double percent_low = 10.0; - gdouble p; - PowerLevel ret; - - g_return_val_if_fail(battery != NULL, POWER_LEVEL_OK); - g_return_val_if_fail(indicator_power_device_get_kind(battery) == UP_DEVICE_KIND_BATTERY, POWER_LEVEL_OK); - - p = indicator_power_device_get_percentage(battery); - - if (p <= percent_critical) - ret = POWER_LEVEL_CRITICAL; - else if (p <= percent_very_low) - ret = POWER_LEVEL_VERY_LOW; - else if (p <= percent_low) - ret = POWER_LEVEL_LOW; - else - ret = POWER_LEVEL_OK; - - return ret; + return power_level_to_dbus_string (get_battery_power_level (battery)); } diff --git a/src/notifier.h b/src/notifier.h index c23c585..18e25d7 100644 --- a/src/notifier.h +++ b/src/notifier.h @@ -35,15 +35,6 @@ G_BEGIN_DECLS typedef struct _IndicatorPowerNotifier IndicatorPowerNotifier; typedef struct _IndicatorPowerNotifierClass IndicatorPowerNotifierClass; -typedef enum -{ - POWER_LEVEL_OK, - POWER_LEVEL_LOW, - POWER_LEVEL_VERY_LOW, - POWER_LEVEL_CRITICAL -} -PowerLevel; - /** * The Indicator Power Notifier. */ @@ -72,7 +63,11 @@ void indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, void indicator_power_notifier_set_battery (IndicatorPowerNotifier * self, IndicatorPowerDevice * battery); -PowerLevel indicator_power_notifier_get_power_level (IndicatorPowerDevice * battery); +#define POWER_LEVEL_STR_OK "ok" +#define POWER_LEVEL_STR_LOW "low" +#define POWER_LEVEL_STR_VERY_LOW "very_low" +#define POWER_LEVEL_STR_CRITICAL "critical" +const char * indicator_power_notifier_get_power_level (IndicatorPowerDevice * battery); G_END_DECLS -- cgit v1.2.3 From 35a251324cc5256c459ff4287855cd510b30a026 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 24 Jul 2014 23:40:28 -0500 Subject: in notify, reverse the numerical order of the now-private PowerLevel enum so that they have the more intuitive behavior of higher integer values meaning a better power level. --- src/notifier.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 7add139..6557246 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -29,10 +29,10 @@ typedef enum { - POWER_LEVEL_OK, - POWER_LEVEL_LOW, + POWER_LEVEL_CRITICAL, POWER_LEVEL_VERY_LOW, - POWER_LEVEL_CRITICAL + POWER_LEVEL_LOW, + POWER_LEVEL_OK } PowerLevel; @@ -92,10 +92,10 @@ power_level_to_dbus_string (const PowerLevel power_level) { switch (power_level) { - case POWER_LEVEL_LOW: return "low"; - case POWER_LEVEL_VERY_LOW: return "very_low"; - case POWER_LEVEL_CRITICAL: return "critical"; - default: return "ok"; + case POWER_LEVEL_LOW: return POWER_LEVEL_STR_LOW; + case POWER_LEVEL_VERY_LOW: return POWER_LEVEL_STR_VERY_LOW; + case POWER_LEVEL_CRITICAL: return POWER_LEVEL_STR_CRITICAL; + default: return POWER_LEVEL_STR_OK; } } @@ -223,7 +223,7 @@ on_battery_property_changed (IndicatorPowerNotifier * self) /* pop up a 'low battery' notification if either: a) it's already discharging, and its PowerLevel worsens, OR b) it's already got a bad PowerLevel and its state becomes 'discharging */ - if ((new_discharging && (new_power_level > old_power_level)) || + if ((new_discharging && (old_power_level > new_power_level)) || ((new_power_level != POWER_LEVEL_OK) && new_discharging && !old_discharging)) { notification_show (self); @@ -317,6 +317,8 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) p->dbus_battery = dbus_battery_skeleton_new (); + p->power_level = POWER_LEVEL_OK; + if (!instance_count++) { if (!notify_init("indicator-power-service")) -- cgit v1.2.3 From eaf64b2f5d9561b4e113330d24d17c01dfbc92f0 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 25 Jul 2014 00:05:04 -0500 Subject: fix bug introduced in previous commit --- src/notifier.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 6557246..52d8854 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -234,6 +234,7 @@ on_battery_property_changed (IndicatorPowerNotifier * self) } dbus_battery_set_power_level (p->dbus_battery, power_level_to_dbus_string (new_power_level)); + p->power_level = new_power_level; p->discharging = new_discharging; } -- cgit v1.2.3 From 265ab08cace125fc1e307f137f62240f74ae2662 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 25 Jul 2014 00:28:23 -0500 Subject: disable the notification's interactive hint for now --- src/notifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 52d8854..496b416 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -178,7 +178,7 @@ notification_show(IndicatorPowerNotifier * self) body = g_strdup_printf(_("%.0f%% charge remaining"), pct); nn = notify_notification_new(_("Battery Low"), body, NULL); g_free (body); - notify_notification_set_hint(nn, HINT_INTERACTIVE, g_variant_new_boolean(TRUE)); + /*notify_notification_set_hint(nn, HINT_INTERACTIVE, g_variant_new_boolean(TRUE));*/ /* if we can show it, keep it */ error = NULL; -- cgit v1.2.3 From b46ec7d0cc35d10197a1a91f473e0a655188f6eb Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 25 Jul 2014 00:34:59 -0500 Subject: in notify.c, improve the logic for when to tear down a notification --- src/notifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/notifier.c b/src/notifier.c index 496b416..81cd6f1 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -228,7 +228,7 @@ on_battery_property_changed (IndicatorPowerNotifier * self) { notification_show (self); } - else + else if (!new_discharging || (new_power_level == POWER_LEVEL_OK)) { notification_clear (self); } -- cgit v1.2.3