From 18fd0fa741f818ed8a6d09b8a2a4623e85d6bbdf Mon Sep 17 00:00:00 2001 From: "Y.C cheng" Date: Mon, 3 Mar 2014 17:18:05 +0800 Subject: set brightness via powerd if it exist (using dbus) --- src/Makefile.am | 2 + src/ib-brightness-powerd-control.c | 166 +++++++++++++++++++++++++++++++++++++ src/ib-brightness-powerd-control.h | 34 ++++++++ src/service.c | 53 ++++++++++-- 4 files changed, 250 insertions(+), 5 deletions(-) create mode 100644 src/ib-brightness-powerd-control.c create mode 100644 src/ib-brightness-powerd-control.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index be746db..2461592 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,6 +46,8 @@ libindciatorpower_upower_a_LDFLAGS = $(COVERAGE_LDFLAGS) libindicatorpower_service_a_SOURCES = \ ib-brightness-control.c \ ib-brightness-control.h \ + ib-brightness-powerd-control.c \ + ib-brightness-powerd-control.h \ device-provider.c \ device-provider.h \ device.c \ diff --git a/src/ib-brightness-powerd-control.c b/src/ib-brightness-powerd-control.c new file mode 100644 index 0000000..3395bda --- /dev/null +++ b/src/ib-brightness-powerd-control.c @@ -0,0 +1,166 @@ +/* + * 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: + * Yuan-Chen Cheng + */ + +#include + +#include +#include +#include +#include + +#include "ib-brightness-powerd-control.h" + +GDBusProxy* +powerd_get_proxy(void) +{ + GError *error = NULL; + GDBusProxy* powerd_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "com.canonical.powerd", + "/com/canonical/powerd", + "com.canonical.powerd", + NULL, + &error); + + if (error != NULL) { + g_error_free (error); + g_debug ("could not connect to powerd: %s", error->message); + return NULL; + } + return powerd_proxy; +} + + +static gboolean +getBrightnessParams(GDBusProxy* powerd_proxy, int *min, int *max, int *dflt, gboolean *ab_supported) +{ + GVariant *ret = NULL; + GError *error = NULL; + + ret = g_dbus_proxy_call_sync(powerd_proxy, + "getBrightnessParams", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + if (!ret) { + g_warning("getBrightnessParams failed: %s", error->message); + g_error_free(error); + return FALSE; + } + + g_variant_get(ret, "((iiib))", min, max, dflt, ab_supported); + g_variant_unref(ret); + return TRUE; +} + +static gboolean setUserBrightness(GDBusProxy* powerd_proxy, int brightness) +{ + GVariant *ret = NULL; + GError *error = NULL; + + ret = g_dbus_proxy_call_sync(powerd_proxy, + "setUserBrightness", + g_variant_new("(i)", brightness), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + if (!ret) { + g_warning("setUserBrightness failed: %s", error->message); + g_error_free(error); + return FALSE; + } else { + g_variant_unref(ret); + return TRUE; + } +} + +struct _IbBrightnessPowerdControl +{ + gboolean inited; + + GDBusProxy *powerd_proxy; + + int min; + int max; + int dflt; + gboolean ab_supported; + + int current; +}; + + +static void ib_brightness_init(IbBrightnessPowerdControl *control) +{ + gboolean ret = getBrightnessParams(control->powerd_proxy, &(control->min), + &(control->max), &(control->dflt), &(control->ab_supported)); + if (! ret) return; + + ib_brightness_powerd_control_set_value(control, control->max); + + control->inited = TRUE; +} + +IbBrightnessPowerdControl* +ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy) +{ + IbBrightnessPowerdControl *control; + + control = g_new0 (IbBrightnessPowerdControl, 1); + control->inited = FALSE; + control->powerd_proxy = powerd_proxy; + + ib_brightness_init(control); + + return control; +} + +void +ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value) +{ + gboolean ret; + if (! self->inited) return; + if (value > self->max || value < self->min) return; + ret = setUserBrightness(self->powerd_proxy, value); + if (ret) + { + self->current = value; + } +} + +gint +ib_brightness_powerd_control_get_value (IbBrightnessPowerdControl* self) +{ + if (! self->inited) return 0; + return self->current; +} + +gint +ib_brightness_powerd_control_get_max_value (IbBrightnessPowerdControl* self) +{ + if (! self->inited) return 0; + return self->max; +} + +void +ib_brightness_powerd_control_free (IbBrightnessPowerdControl *self) +{ + g_object_unref (self->powerd_proxy); + g_free (self); +} + diff --git a/src/ib-brightness-powerd-control.h b/src/ib-brightness-powerd-control.h new file mode 100644 index 0000000..77e44cb --- /dev/null +++ b/src/ib-brightness-powerd-control.h @@ -0,0 +1,34 @@ +/* + * 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: + * Y.C Cheng + */ + +#ifndef __IB_BRIGHTNESS_POWERD_CONTROL_H__ +#define __IB_BRIGHTNESS_POWERD_CONTROL_H__ + +#include +GDBusProxy* powerd_get_proxy(); + +typedef struct _IbBrightnessPowerdControl IbBrightnessPowerdControl; + +IbBrightnessPowerdControl* ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy); +void ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value); +gint ib_brightness_powerd_control_get_value (IbBrightnessPowerdControl* self); +gint ib_brightness_powerd_control_get_max_value (IbBrightnessPowerdControl* self); +void ib_brightness_powerd_control_free (IbBrightnessPowerdControl *self); + +#endif diff --git a/src/service.c b/src/service.c index 982a24e..0f976d1 100644 --- a/src/service.c +++ b/src/service.c @@ -27,6 +27,7 @@ #include "device.h" #include "device-provider.h" #include "ib-brightness-control.h" +#include "ib-brightness-powerd-control.h" #include "service.h" #define BUS_NAME "com.canonical.indicator.power" @@ -104,6 +105,7 @@ struct _IndicatorPowerServicePrivate GSettings * settings; IbBrightnessControl * brightness_control; + IbBrightnessPowerdControl * brightness_powerd_control; guint own_id; guint actions_export_id; @@ -440,7 +442,12 @@ create_phone_devices_section (IndicatorPowerService * self G_GNUC_UNUSED) static void get_brightness_range (IndicatorPowerService * self, gint * low, gint * high) { - const int max = ib_brightness_control_get_max_value (self->priv->brightness_control); + int max = 0; + if (self->priv->brightness_control) { + max = ib_brightness_control_get_max_value (self->priv->brightness_control); + } else { + max = ib_brightness_powerd_control_get_max_value (self->priv->brightness_powerd_control); + } *low = max * 0.05; /* 5% minimum -- don't let the screen go completely dark */ *high = max; } @@ -483,7 +490,15 @@ static GVariant * action_state_for_brightness (IndicatorPowerService * self) { priv_t * p = self->priv; - const gint brightness = ib_brightness_control_get_value (p->brightness_control); + gint brightness = 0; + if (p->brightness_control) + { + brightness = ib_brightness_control_get_value (p->brightness_control); + } + else if (p->brightness_powerd_control) + { + brightness = ib_brightness_powerd_control_get_value (p->brightness_powerd_control); + } return g_variant_new_double (brightness_to_percentage (self, brightness)); } @@ -502,7 +517,16 @@ on_brightness_change_requested (GSimpleAction * action G_GNUC_UNUSED, IndicatorPowerService * self = INDICATOR_POWER_SERVICE (gself); const gdouble percentage = g_variant_get_double (parameter); const int brightness = percentage_to_brightness (self, percentage); - ib_brightness_control_set_value (self->priv->brightness_control, brightness); + + if (self->priv->brightness_control) + { + ib_brightness_control_set_value (self->priv->brightness_control, brightness); + } + else if (self->priv->brightness_powerd_control) + { + ib_brightness_powerd_control_set_value (self->priv->brightness_powerd_control, brightness); + } + update_brightness_action_state (self); } @@ -999,7 +1023,14 @@ my_dispose (GObject * o) g_clear_object (&p->conn); - g_clear_pointer (&p->brightness_control, ib_brightness_control_free); + if (p->brightness_control) + { + g_clear_pointer (&p->brightness_control, ib_brightness_control_free); + } + else if (p->brightness_powerd_control) + { + g_clear_pointer (&p->brightness_powerd_control, ib_brightness_powerd_control_free); + } indicator_power_service_set_device_provider (self, NULL); @@ -1013,6 +1044,7 @@ my_dispose (GObject * o) static void indicator_power_service_init (IndicatorPowerService * self) { + GDBusProxy *powerd_proxy = NULL; priv_t * p = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_TYPE_POWER_SERVICE, IndicatorPowerServicePrivate); @@ -1022,7 +1054,18 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); - p->brightness_control = ib_brightness_control_new (); + p->brightness_control = NULL; + p->brightness_powerd_control = NULL; + + powerd_proxy = powerd_get_proxy(); + if (powerd_proxy != NULL) + { + p->brightness_powerd_control = ib_brightness_powerd_control_new(powerd_proxy); + } + else + { + p->brightness_control = ib_brightness_control_new (); + } init_gactions (self); -- cgit v1.2.3 From 0f47066b171ba99fa7ac68bb3ccf0e92b18e78ab Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 4 Mar 2014 22:57:52 -0600 Subject: update the header / menuitem text / accessible text to reflect the changes in https://wiki.ubuntu.com/Power?action=diff&rev2=44&rev1=43#Title --- src/device.c | 474 ++++++++++++++++++++++++++++++++++++++-------------------- src/device.h | 45 ++++-- src/service.c | 83 +++++----- 3 files changed, 386 insertions(+), 216 deletions(-) (limited to 'src') diff --git a/src/device.c b/src/device.c index 7f1b14f..c941454 100644 --- a/src/device.c +++ b/src/device.c @@ -37,6 +37,11 @@ struct _IndicatorPowerDevicePrivate gchar * object_path; gdouble percentage; time_t time; + + /* Timestamp of when when we first noticed that upower couldn't estimate + the time-remaining field for this device, or 0 if not applicable. + This is used when generating the time-remaining string. */ + GTimer * inestimable; }; #define INDICATOR_POWER_DEVICE_GET_PRIVATE(o) (INDICATOR_POWER_DEVICE(o)->priv) @@ -136,6 +141,11 @@ indicator_power_device_init (IndicatorPowerDevice *self) static void indicator_power_device_dispose (GObject *object) { + IndicatorPowerDevice * self = INDICATOR_POWER_DEVICE(object); + IndicatorPowerDevicePrivate * p = self->priv; + + g_clear_pointer (&p->inestimable, g_timer_destroy); + G_OBJECT_CLASS (indicator_power_device_parent_class)->dispose (object); } @@ -192,35 +202,50 @@ static void set_property (GObject * o, guint prop_id, const GValue * value, GParamSpec * pspec) { IndicatorPowerDevice * self = INDICATOR_POWER_DEVICE(o); - IndicatorPowerDevicePrivate * priv = self->priv; + IndicatorPowerDevicePrivate * p = self->priv; switch (prop_id) { case PROP_KIND: - priv->kind = g_value_get_int (value); + p->kind = g_value_get_int (value); break; case PROP_STATE: - priv->state = g_value_get_int (value); + p->state = g_value_get_int (value); break; case PROP_OBJECT_PATH: - g_free (priv->object_path); - priv->object_path = g_value_dup_string (value); + g_free (p->object_path); + p->object_path = g_value_dup_string (value); break; case PROP_PERCENTAGE: - priv->percentage = g_value_get_double (value); + p->percentage = g_value_get_double (value); break; case PROP_TIME: - priv->time = g_value_get_uint64(value); + p->time = g_value_get_uint64(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(o, prop_id, pspec); break; } + + /* update inestimable_at */ + + const gboolean is_inestimable = (p->time == 0) + && (p->state != UP_DEVICE_STATE_FULLY_CHARGED) + && (p->percentage > 0); + + if (!is_inestimable) + { + g_clear_pointer (&p->inestimable, g_timer_destroy); + } + else if (p->inestimable == NULL) + { + p->inestimable = g_timer_new (); + } } /*** @@ -442,57 +467,6 @@ indicator_power_device_get_gicon (const IndicatorPowerDevice * device) **** ***/ -/* Format time remaining for reading ("H:MM") and speech ("H hours, MM minutes") */ -static void -get_timestring (guint64 time_secs, - gchar **readable_timestring, - gchar **accessible_timestring) -{ - gint hours; - gint minutes; - - /* Add 0.5 to do rounding */ - minutes = (int) ( ( time_secs / 60.0 ) + 0.5 ); - - if (minutes == 0) - { - *readable_timestring = g_strdup (_("Unknown time")); - *accessible_timestring = g_strdup (_("Unknown time")); - - return; - } - - if (minutes < 60) - { - *readable_timestring = g_strdup_printf ("0:%.2i", minutes); - *accessible_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%i minute", - "%i minutes", - minutes), minutes); - return; - } - - hours = minutes / 60; - minutes = minutes % 60; - - *readable_timestring = g_strdup_printf ("%i:%.2i", hours, minutes); - - if (minutes == 0) - { - *accessible_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, - "%i hour", - "%i hours", - hours), hours); - } - else - { - /* TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" - * Swap order with "%2$s %2$i %1$s %1$i if needed */ - *accessible_timestring = g_strdup_printf (_("%i %s %i %s"), - hours, g_dngettext (GETTEXT_PACKAGE, "hour", "hours", hours), - minutes, g_dngettext (GETTEXT_PACKAGE, "minute", "minutes", minutes)); - } -} - static const gchar * device_kind_to_localised_string (UpDeviceKind kind) { @@ -555,149 +529,325 @@ device_kind_to_localised_string (UpDeviceKind kind) return text; } -static char * -join_strings (const char * name, const char * time, const char * percent) +/** + * The '''brief time-remaining string''' for a component should be: + * * the time remaining for it to empty or fully charge, + * if estimable, in H:MM format; otherwise + * * “estimating…” if the time remaining has been inestimable for + * less than 30 seconds; otherwise + * * “unknown” if the time remaining has been inestimable for + * between 30 seconds and one minute; otherwise + * * the empty string. + */ +static void +get_brief_time_remaining (const IndicatorPowerDevice * device, + char * str, + gulong size) { - char * str; - const gboolean have_name = name && *name; - const gboolean have_time = time && *time; - const gboolean have_percent = percent && *percent; - - if (have_name && have_time && have_percent) - str = g_strdup_printf (_("%s (%s, %s)"), name, time, percent); - else if (have_name && have_time) - str = g_strdup_printf (_("%s (%s)"), name, time); - else if (have_name && have_percent) - str = g_strdup_printf (_("%s (%s)"), name, percent); - else if (have_name) - str = g_strdup (name); - else if (have_time && have_percent) - str = g_strdup_printf (_("(%s, %s)"), time, percent); - else if (have_time) - str = g_strdup_printf (_("(%s)"), time); - else if (have_percent) - str = g_strdup_printf (_("(%s)"), percent); - else - str = g_strdup (""); + const IndicatorPowerDevicePrivate * p = device->priv; + + if (p->time > 0) + { + int minutes = p->time / 60; + int hours = minutes / 60; + minutes %= 60; + + g_snprintf (str, size, "%0d:%02d", hours, minutes); + } + else if (p->inestimable != NULL) + { + const double elapsed = g_timer_elapsed (p->inestimable, NULL); - return str; + if (elapsed < 30) + { + g_snprintf (str, size, _("estimating…")); + } + else if (elapsed < 60) + { + g_snprintf (str, size, _("unknown")); + } + else + { + *str = '\0'; + } + } + else + { + *str = '\0'; + } } +/** + * The '''expanded time-remaining string''' for a component should + * be the same as the brief time-remaining string, except that if + * the time is estimable: + * * if the component is charging, it should be “H:MM to charge” + * * if the component is discharging, it should be “H:MM left”. + */ static void -indicator_power_device_get_text (const IndicatorPowerDevice * device, - gboolean show_time_in_header, - gboolean show_percentage_in_header, - gchar ** header, - gchar ** label, - gchar ** a11y) +get_expanded_time_remaining (const IndicatorPowerDevice * device, + char * str, + gulong size) { - if (!INDICATOR_IS_POWER_DEVICE(device)) - { - if (a11y != NULL) *a11y = NULL; - if (label != NULL) *label = NULL; - if (header != NULL) *header = NULL; - g_warning ("%s: %p is not an IndicatorPowerDevice", G_STRFUNC, device); - return; - } + const IndicatorPowerDevicePrivate * p; - const time_t time = indicator_power_device_get_time (device); - const UpDeviceState state = indicator_power_device_get_state (device); - const UpDeviceKind kind = indicator_power_device_get_kind (device); - const gchar * device_name = device_kind_to_localised_string (kind); - const gdouble percentage = indicator_power_device_get_percentage (device); - char pctstr[32] = { '\0' }; - g_snprintf (pctstr, sizeof(pctstr), "%.0lf%%", percentage); + g_return_if_fail (str != NULL); + g_return_if_fail (size > 0); + *str = '\0'; + g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); - GString * terse_time = g_string_new (NULL); - GString * verbose_time = g_string_new (NULL); - GString * accessible_time = g_string_new (NULL); + p = device->priv; - if (time > 0) + if (p->time && ((p->state == UP_DEVICE_STATE_CHARGING) || (p->state == UP_DEVICE_STATE_DISCHARGING))) { - char * readable_timestr = NULL; - char * accessible_timestr = NULL; - get_timestring (time, &readable_timestr, &accessible_timestr); + int minutes = p->time / 60; + int hours = minutes / 60; + minutes %= 60; - if (state == UP_DEVICE_STATE_CHARGING) + if (p->state == UP_DEVICE_STATE_CHARGING) { - g_string_assign (terse_time, readable_timestr); - g_string_printf (verbose_time, _("%s to charge"), readable_timestr); - g_string_printf (accessible_time, _("%s to charge"), accessible_timestr); + g_snprintf (str, size, _("%0d:%02d to charge"), hours, minutes); } - else if ((state == UP_DEVICE_STATE_DISCHARGING) && (time <= (60*60*24))) + else // discharging { - g_string_assign (terse_time, readable_timestr); - g_string_printf (verbose_time, _("%s left"), readable_timestr); - g_string_printf (accessible_time, _("%s left"), accessible_timestr); + g_snprintf (str, size, _("%0d:%02d left"), hours, minutes); } - else + } + else + { + get_brief_time_remaining (device, str, size); + } +} + +/** + * The '''accessible time-remaining string''' for a component + * should be the same as the expanded time-remaining string, + * except the H:MM time should be rendered as “''H'' hours ''M'' minutes”, + * or just as “''M'' * minutes” if the time is less than one hour. + */ +static void +get_accessible_time_remaining (const IndicatorPowerDevice * device, + char * str, + gulong size) +{ + const IndicatorPowerDevicePrivate * p; + + g_return_if_fail (str != NULL); + g_return_if_fail (size > 0); + *str = '\0'; + g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); + + p = device->priv; + + if (p->time && ((p->state == UP_DEVICE_STATE_CHARGING) || (p->state == UP_DEVICE_STATE_DISCHARGING))) + { + int minutes = p->time / 60; + int hours = minutes / 60; + minutes %= 60; + + if (p->state == UP_DEVICE_STATE_CHARGING) { - /* if there's more than 24 hours remaining, we don't show it */ + if (hours) + g_snprintf (str, size, _("%d %s %d %s to charge"), + hours, g_dngettext (NULL, "hour", "hours", hours), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + else + g_snprintf (str, size, _("%d %s to charge"), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + } + else // discharging + { + if (hours) + g_snprintf (str, size, _("%d %s %d %s left"), + hours, g_dngettext (NULL, "hour", "hours", hours), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + else + g_snprintf (str, size, _("%d %s left"), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); } - - g_free (readable_timestr); - g_free (accessible_timestr); } - else if (state == UP_DEVICE_STATE_FULLY_CHARGED) + else { - g_string_assign (verbose_time, _("charged")); - g_string_assign (accessible_time, _("charged")); + get_brief_time_remaining (device, str, size); } - else if (percentage > 0) +} + +/** + * The time is relevant for a device if either (a) the component is charging, + * or (b) the component is discharging and the estimated time is less than + * 24 hours. (A time greater than 24 hours is probably a mistaken calculation.) + */ +static gboolean +time_is_relevant (const IndicatorPowerDevice * device) +{ + const IndicatorPowerDevicePrivate * p = device->priv; + + if (p->state == UP_DEVICE_STATE_CHARGING) + return TRUE; + + if ((p->state == UP_DEVICE_STATE_DISCHARGING) && (p->time<(24*60*60))) + return TRUE; + + return FALSE; +} + +/** + * The menu item for each chargeable component should consist of ... + * Text representing the name of the component (“Battery”, “Mouse”, + * “UPS”, “Alejandra’s iPod”, etc) and the charge status in brackets: + * + * * “X (charged)” if it is fully charged and not discharging; + * * “X (expanded time-remaining string)” if it is charging, + * or discharging with less than 24 hours left; + * * “X” if it is discharging with 24 hours or more left. + * + * The accessible label for the menu item should be the same as the + * visible label, except with the accessible time-remaining string + * instead of the expanded time-remaining string. + */ +static void +get_menuitem_text (const IndicatorPowerDevice * device, + gchar * str, + gulong size, + gboolean accessible) +{ + const IndicatorPowerDevicePrivate * p = device->priv; + const char * kind_str = device_kind_to_localised_string (p->kind); + + if (p->state == UP_DEVICE_STATE_FULLY_CHARGED) { - g_string_assign (terse_time, _("estimating…")); - g_string_assign (verbose_time, _("estimating…")); - g_string_assign (accessible_time, _("estimating…")); + g_snprintf (str, size, _("%s (charged)"), kind_str); } else { - *pctstr = '\0'; + char buf[64]; - if (kind != UP_DEVICE_KIND_LINE_POWER) + if (time_is_relevant (device)) { - g_string_assign (verbose_time, _("not present")); - g_string_assign (accessible_time, _("not present")); + if (accessible) + get_accessible_time_remaining (device, buf, sizeof(buf)); + else + get_expanded_time_remaining (device, buf, sizeof(buf)); } + else + { + *buf = '\0'; + } + + if (*buf) + g_snprintf (str, size, _("%s (%s)"), kind_str, buf); + else + g_strlcpy (str, kind_str, size); } +} - if (header != NULL) - *header = join_strings (NULL, - show_time_in_header ? terse_time->str : "", - show_percentage_in_header ? pctstr : ""); +void +indicator_power_device_get_readable_text (const IndicatorPowerDevice * device, + gchar * str, + gulong size) +{ + g_return_if_fail (str != NULL); + g_return_if_fail (size > 0); + *str = '\0'; + g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); - if (label != NULL) - *label = join_strings (device_name, - verbose_time->str, - NULL); + get_menuitem_text (device, str, size, FALSE); +} - if (a11y != NULL) - *a11y = join_strings (device_name, - accessible_time->str, - pctstr); +void +indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device, + gchar * str, + gulong size) +{ + g_return_if_fail (str != NULL); + g_return_if_fail (size > 0); + *str = '\0'; + g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); - g_string_free (terse_time, TRUE); - g_string_free (verbose_time, TRUE); - g_string_free (accessible_time, TRUE); + get_menuitem_text (device, str, size, TRUE); } -gchar * -indicator_power_device_get_label (const IndicatorPowerDevice * device) +#if 0 +- If the time is relevant, the brackets should contain the time-remaining string for that component. ++ If the time is relevant, the brackets should contain the brief time-remaining string for that component. + +- Regardless, the accessible name for the whole menu title should be the same as the accessible name for that thing’s component inside the menu itself. ++ The accessible name for the whole menu title should be the same as the except using the accessible time-remaining string instead of the brief time-remaining string. +#endif + +/** + * If the time is relevant and/or “Show Percentage in Menu Bar” is checked, + * the icon should be followed by brackets. + * + * If the time is relevant, the brackets should contain the time-remaining + * string for that component. + * + * If “Show Percentage in Menu Bar” is checked (as it should not be by default), + * the brackets should contain the percentage charge for that device. + * + * If both conditions are true, the time and percentage should be separated by a space. + */ +void +indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, + gchar * str, + gulong size, + gboolean want_time, + gboolean want_percent) { - gchar * label = NULL; - indicator_power_device_get_text (device, FALSE, FALSE, - NULL, &label, NULL); - return label; + char tr[64]; + const IndicatorPowerDevicePrivate * p; + + g_return_if_fail (str != NULL); + g_return_if_fail (size > 0); + *str = '\0'; + g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); + + p = device->priv; + + if (want_time && !time_is_relevant (device)) + want_time = FALSE; + + if (p->percentage < 0.01) + want_percent = FALSE; + + if (want_time) + { + get_brief_time_remaining (device, tr, sizeof(tr)); + + if (!*tr) + want_time = FALSE; + } + + if (want_time && want_percent) + { + g_snprintf (str, size, _("(%s, %.0lf%%)"), tr, p->percentage); + } + else if (want_time) + { + g_snprintf (str, size, _("(%s)"), tr); + } + else if (want_percent) + { + g_snprintf (str, size, _("(%.0lf%%)"), p->percentage); + } + else + { + *str = '\0'; + } } +/** + * Regardless, the accessible name for the whole menu title should be the same + * as the accessible name for that thing’s component inside the menu itself. + */ void -indicator_power_device_get_header (const IndicatorPowerDevice * device, - gboolean show_time, - gboolean show_percentage, - gchar ** header, - gchar ** a11y) +indicator_power_device_get_accessible_title (const IndicatorPowerDevice * device, + gchar * str, + gulong size, + gboolean want_time G_GNUC_UNUSED, + gboolean want_percent G_GNUC_UNUSED) { - indicator_power_device_get_text (device, show_time, show_percentage, - header, NULL, a11y); + indicator_power_device_get_accessible_text (device, str, size); } /*** diff --git a/src/device.h b/src/device.h index 1f395a1..65c6767 100644 --- a/src/device.h +++ b/src/device.h @@ -116,22 +116,35 @@ IndicatorPowerDevice* indicator_power_device_new (const gchar * object_path, IndicatorPowerDevice* indicator_power_device_new_from_variant (GVariant * variant); -UpDeviceKind indicator_power_device_get_kind (const IndicatorPowerDevice * device); -UpDeviceState indicator_power_device_get_state (const IndicatorPowerDevice * device); -const gchar * indicator_power_device_get_object_path (const IndicatorPowerDevice * device); -gdouble indicator_power_device_get_percentage (const IndicatorPowerDevice * device); -time_t indicator_power_device_get_time (const IndicatorPowerDevice * device); - -GStrv indicator_power_device_get_icon_names (const IndicatorPowerDevice * device); -GIcon * indicator_power_device_get_gicon (const IndicatorPowerDevice * device); - -gchar * indicator_power_device_get_label (const IndicatorPowerDevice * device); - -void indicator_power_device_get_header (const IndicatorPowerDevice * device, - gboolean show_time, - gboolean show_percentage, - gchar ** header, - gchar ** a11y); +UpDeviceKind indicator_power_device_get_kind (const IndicatorPowerDevice * device); +UpDeviceState indicator_power_device_get_state (const IndicatorPowerDevice * device); +const gchar * indicator_power_device_get_object_path (const IndicatorPowerDevice * device); +gdouble indicator_power_device_get_percentage (const IndicatorPowerDevice * device); +time_t indicator_power_device_get_time (const IndicatorPowerDevice * device); + +GStrv indicator_power_device_get_icon_names (const IndicatorPowerDevice * device); +GIcon * indicator_power_device_get_gicon (const IndicatorPowerDevice * device); + + +void indicator_power_device_get_readable_text (const IndicatorPowerDevice * device, + gchar * str, + gulong size); + +void indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device, + gchar * str, + gulong size); + +void indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, + gchar * str, + gulong size, + gboolean want_time, + gboolean want_percent); + +void indicator_power_device_get_accessible_title (const IndicatorPowerDevice * device, + gchar * str, + gulong size, + gboolean want_time, + gboolean want_percent); G_END_DECLS diff --git a/src/service.c b/src/service.c index 982a24e..248f953 100644 --- a/src/service.c +++ b/src/service.c @@ -312,21 +312,7 @@ static GVariant * create_header_state (IndicatorPowerService * self) { GVariantBuilder b; - gchar * label = NULL; - gchar * a11y = NULL; - GIcon * icon = NULL; - priv_t * p = self->priv; - - if (p->primary_device != NULL) - { - indicator_power_device_get_header (p->primary_device, - g_settings_get_boolean (p->settings, SETTINGS_SHOW_TIME_S), - g_settings_get_boolean (p->settings, SETTINGS_SHOW_PERCENTAGE_S), - &label, - &a11y); - - icon = indicator_power_device_get_gicon (p->primary_device); - } + const priv_t * const p = self->priv; g_variant_builder_init (&b, G_VARIANT_TYPE("a{sv}")); @@ -335,24 +321,42 @@ create_header_state (IndicatorPowerService * self) g_variant_builder_add (&b, "{sv}", "visible", g_variant_new_boolean (should_be_visible (self))); - if (label != NULL) - g_variant_builder_add (&b, "{sv}", "label", g_variant_new_take_string (label)); - - if (icon != NULL) + if (p->primary_device != NULL) { - GVariant * v; + char buf[128]; + GIcon * icon; + const gboolean want_time = g_settings_get_boolean (p->settings, SETTINGS_SHOW_TIME_S); + const gboolean want_percent = g_settings_get_boolean (p->settings, SETTINGS_SHOW_PERCENTAGE_S); + + indicator_power_device_get_readable_title (p->primary_device, + buf, sizeof(buf), + want_time, + want_percent); + if (*buf) + g_variant_builder_add (&b, "{sv}", "label", g_variant_new_string (buf)); + + + indicator_power_device_get_accessible_title (p->primary_device, + buf, sizeof(buf), + want_time, + want_percent); + if (*buf) + g_variant_builder_add (&b, "{sv}", "accessible-desc", g_variant_new_string (buf)); - if ((v = g_icon_serialize (icon))) + + if ((icon = indicator_power_device_get_gicon (p->primary_device))) { - g_variant_builder_add (&b, "{sv}", "icon", v); - g_variant_unref (v); - } + GVariant * serialized_icon = g_icon_serialize (icon); - g_object_unref (icon); - } + if (serialized_icon != NULL) + { + g_variant_builder_add (&b, "{sv}", "icon", serialized_icon); + g_variant_unref (serialized_icon); + } - if (a11y != NULL) - g_variant_builder_add (&b, "{sv}", "accessible-desc", g_variant_new_take_string (a11y)); + g_object_unref (icon); + } + } return g_variant_builder_end (&b); } @@ -371,28 +375,31 @@ append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device) if (kind != UP_DEVICE_KIND_LINE_POWER) { - char * label; + char buf[128]; GMenuItem * item; GIcon * icon; - label = indicator_power_device_get_label (device); - item = g_menu_item_new (label, "indicator.activate-statistics"); - g_free (label); - g_menu_item_set_action_and_target(item, "indicator.activate-statistics", "s", - indicator_power_device_get_object_path (device)); + indicator_power_device_get_readable_text (device, buf, sizeof(buf)); + item = g_menu_item_new (buf, "indicator.activate-statistics"); if ((icon = indicator_power_device_get_gicon (device))) { - GVariant * v; - if ((v = g_icon_serialize (icon))) + GVariant * serialized_icon = g_icon_serialize (icon); + + if (serialized_icon != NULL) { - g_menu_item_set_attribute_value (item, G_MENU_ATTRIBUTE_ICON, v); - g_variant_unref (v); + g_menu_item_set_attribute_value (item, + G_MENU_ATTRIBUTE_ICON, + serialized_icon); + g_variant_unref (serialized_icon); } g_object_unref (icon); } + g_menu_item_set_action_and_target(item, "indicator.activate-statistics", "s", + indicator_power_device_get_object_path (device)); + g_menu_append_item (menu, item); g_object_unref (item); } -- cgit v1.2.3 From 065169e1bb80fa1b7b0bcc1059c68d2ba934116b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 4 Mar 2014 23:09:42 -0600 Subject: slightly better comments --- src/device.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/device.c b/src/device.c index c941454..e7384ee 100644 --- a/src/device.c +++ b/src/device.c @@ -232,7 +232,11 @@ set_property (GObject * o, guint prop_id, const GValue * value, GParamSpec * psp break; } - /* update inestimable_at */ + /** + * Check to see if the time-remaining value is estimable. + * When it first becomes inestimable, kick off a timer because + * we need to track that to generate the appropriate title text. + */ const gboolean is_inestimable = (p->time == 0) && (p->state != UP_DEVICE_STATE_FULLY_CHARGED) @@ -601,7 +605,7 @@ get_expanded_time_remaining (const IndicatorPowerDevice * device, if (p->time && ((p->state == UP_DEVICE_STATE_CHARGING) || (p->state == UP_DEVICE_STATE_DISCHARGING))) { int minutes = p->time / 60; - int hours = minutes / 60; + const int hours = minutes / 60; minutes %= 60; if (p->state == UP_DEVICE_STATE_CHARGING) @@ -642,12 +646,12 @@ get_accessible_time_remaining (const IndicatorPowerDevice * device, if (p->time && ((p->state == UP_DEVICE_STATE_CHARGING) || (p->state == UP_DEVICE_STATE_DISCHARGING))) { int minutes = p->time / 60; - int hours = minutes / 60; + const int hours = minutes / 60; minutes %= 60; if (p->state == UP_DEVICE_STATE_CHARGING) { - if (hours) + if (hours > 0) g_snprintf (str, size, _("%d %s %d %s to charge"), hours, g_dngettext (NULL, "hour", "hours", hours), minutes, g_dngettext (NULL, "minute", "minutes", minutes)); @@ -657,7 +661,7 @@ get_accessible_time_remaining (const IndicatorPowerDevice * device, } else // discharging { - if (hours) + if (hours > 0) g_snprintf (str, size, _("%d %s %d %s left"), hours, g_dngettext (NULL, "hour", "hours", hours), minutes, g_dngettext (NULL, "minute", "minutes", minutes)); @@ -767,14 +771,6 @@ indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device, get_menuitem_text (device, str, size, TRUE); } -#if 0 -- If the time is relevant, the brackets should contain the time-remaining string for that component. -+ If the time is relevant, the brackets should contain the brief time-remaining string for that component. - -- Regardless, the accessible name for the whole menu title should be the same as the accessible name for that thing’s component inside the menu itself. -+ The accessible name for the whole menu title should be the same as the except using the accessible time-remaining string instead of the brief time-remaining string. -#endif - /** * If the time is relevant and/or “Show Percentage in Menu Bar” is checked, * the icon should be followed by brackets. @@ -804,12 +800,15 @@ indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, p = device->priv; + // if we can't provide time-remaining, turn off the time flag if (want_time && !time_is_relevant (device)) want_time = FALSE; + // if we can't provide percent, turn off the percent flag if (p->percentage < 0.01) want_percent = FALSE; + // try to build the time-remaining string if (want_time) { get_brief_time_remaining (device, tr, sizeof(tr)); -- cgit v1.2.3 From 6a577e1b2d6941af7eef77a7a6a8c4c064dcbcf4 Mon Sep 17 00:00:00 2001 From: "Y.C cheng" Date: Wed, 5 Mar 2014 13:32:26 +0800 Subject: clean up / wrong code fix --- src/ib-brightness-powerd-control.c | 27 +++++++++++++++++++-------- src/service.c | 28 ++++++++++++---------------- 2 files changed, 31 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/ib-brightness-powerd-control.c b/src/ib-brightness-powerd-control.c index 3395bda..e7d4e0e 100644 --- a/src/ib-brightness-powerd-control.c +++ b/src/ib-brightness-powerd-control.c @@ -40,8 +40,8 @@ powerd_get_proxy(void) &error); if (error != NULL) { - g_error_free (error); g_debug ("could not connect to powerd: %s", error->message); + g_error_free (error); return NULL; } return powerd_proxy; @@ -109,11 +109,12 @@ static void ib_brightness_init(IbBrightnessPowerdControl *control) { gboolean ret = getBrightnessParams(control->powerd_proxy, &(control->min), &(control->max), &(control->dflt), &(control->ab_supported)); - if (! ret) return; - - ib_brightness_powerd_control_set_value(control, control->max); + if (! ret) + return; control->inited = TRUE; + + ib_brightness_powerd_control_set_value(control, control->max * 8 / 10); } IbBrightnessPowerdControl* @@ -134,8 +135,16 @@ void ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value) { gboolean ret; - if (! self->inited) return; - if (value > self->max || value < self->min) return; + if (! self->inited) + return; + if (value > self->max) + { + value = self->max; + } + else if (value < self->min) + { + value = self->min; + } ret = setUserBrightness(self->powerd_proxy, value); if (ret) { @@ -146,14 +155,16 @@ ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint va gint ib_brightness_powerd_control_get_value (IbBrightnessPowerdControl* self) { - if (! self->inited) return 0; + if (! self->inited) + return 0; return self->current; } gint ib_brightness_powerd_control_get_max_value (IbBrightnessPowerdControl* self) { - if (! self->inited) return 0; + if (! self->inited) + return 0; return self->max; } diff --git a/src/service.c b/src/service.c index 0f976d1..959e316 100644 --- a/src/service.c +++ b/src/service.c @@ -442,12 +442,16 @@ create_phone_devices_section (IndicatorPowerService * self G_GNUC_UNUSED) static void get_brightness_range (IndicatorPowerService * self, gint * low, gint * high) { + priv_t * p = self->priv; int max = 0; - if (self->priv->brightness_control) { - max = ib_brightness_control_get_max_value (self->priv->brightness_control); - } else { - max = ib_brightness_powerd_control_get_max_value (self->priv->brightness_powerd_control); - } + if (p->brightness_control) + { + max = ib_brightness_control_get_max_value (self->priv->brightness_control); + } + else if (p->brightness_powerd_control) + { + max = ib_brightness_powerd_control_get_max_value (self->priv->brightness_powerd_control); + } *low = max * 0.05; /* 5% minimum -- don't let the screen go completely dark */ *high = max; } @@ -1023,14 +1027,9 @@ my_dispose (GObject * o) g_clear_object (&p->conn); - if (p->brightness_control) - { - g_clear_pointer (&p->brightness_control, ib_brightness_control_free); - } - else if (p->brightness_powerd_control) - { - g_clear_pointer (&p->brightness_powerd_control, ib_brightness_powerd_control_free); - } + // g_clear_pointer has NULL check inside. + g_clear_pointer (&p->brightness_control, ib_brightness_control_free); + g_clear_pointer (&p->brightness_powerd_control, ib_brightness_powerd_control_free); indicator_power_service_set_device_provider (self, NULL); @@ -1054,9 +1053,6 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); - p->brightness_control = NULL; - p->brightness_powerd_control = NULL; - powerd_proxy = powerd_get_proxy(); if (powerd_proxy != NULL) { -- cgit v1.2.3 From 237ba715a189e550f86b3b2ac11e4aefa43e3955 Mon Sep 17 00:00:00 2001 From: "Y.C cheng" Date: Wed, 5 Mar 2014 16:09:10 +0800 Subject: brightness parameters as necessary condition to use powerd --- src/ib-brightness-powerd-control.c | 57 ++++++++++++++++++++------------------ src/ib-brightness-powerd-control.h | 12 ++++++-- src/service.c | 5 ++-- 3 files changed, 43 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/ib-brightness-powerd-control.c b/src/ib-brightness-powerd-control.c index e7d4e0e..461bb54 100644 --- a/src/ib-brightness-powerd-control.c +++ b/src/ib-brightness-powerd-control.c @@ -26,10 +26,18 @@ #include "ib-brightness-powerd-control.h" +static gboolean getBrightnessParams(GDBusProxy* powerd_proxy, int *min, int *max, + int *dflt, gboolean *ab_supported); + GDBusProxy* -powerd_get_proxy(void) +powerd_get_proxy(brightness_params_t *params) { GError *error = NULL; + gboolean ret; + + if (params == NULL) + return NULL; + GDBusProxy* powerd_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, @@ -39,11 +47,23 @@ powerd_get_proxy(void) NULL, &error); - if (error != NULL) { + if (error != NULL) + { g_debug ("could not connect to powerd: %s", error->message); g_error_free (error); return NULL; } + + ret = getBrightnessParams(powerd_proxy, &(params->min), &(params->max), + &(params->dflt), &(params->ab_supported)); + + if (! ret) + { + g_debug ("can't get brightness parameters from powerd"); + g_object_unref (powerd_proxy); + return NULL; + } + return powerd_proxy; } @@ -58,7 +78,7 @@ getBrightnessParams(GDBusProxy* powerd_proxy, int *min, int *max, int *dflt, gbo "getBrightnessParams", NULL, G_DBUS_CALL_FLAGS_NONE, - -1, NULL, &error); + 400, NULL, &error); // timeout: 400 ms if (!ret) { g_warning("getBrightnessParams failed: %s", error->message); g_error_free(error); @@ -92,8 +112,6 @@ static gboolean setUserBrightness(GDBusProxy* powerd_proxy, int brightness) struct _IbBrightnessPowerdControl { - gboolean inited; - GDBusProxy *powerd_proxy; int min; @@ -104,29 +122,20 @@ struct _IbBrightnessPowerdControl int current; }; - -static void ib_brightness_init(IbBrightnessPowerdControl *control) -{ - gboolean ret = getBrightnessParams(control->powerd_proxy, &(control->min), - &(control->max), &(control->dflt), &(control->ab_supported)); - if (! ret) - return; - - control->inited = TRUE; - - ib_brightness_powerd_control_set_value(control, control->max * 8 / 10); -} - IbBrightnessPowerdControl* -ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy) +ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy, brightness_params_t params) { IbBrightnessPowerdControl *control; control = g_new0 (IbBrightnessPowerdControl, 1); - control->inited = FALSE; control->powerd_proxy = powerd_proxy; - ib_brightness_init(control); + control->min = params.min; + control->max = params.max; + control->dflt = params.dflt; + control->ab_supported = params.ab_supported; + + ib_brightness_powerd_control_set_value(control, control->max * 8 / 10); return control; } @@ -135,8 +144,6 @@ void ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value) { gboolean ret; - if (! self->inited) - return; if (value > self->max) { value = self->max; @@ -155,16 +162,12 @@ ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint va gint ib_brightness_powerd_control_get_value (IbBrightnessPowerdControl* self) { - if (! self->inited) - return 0; return self->current; } gint ib_brightness_powerd_control_get_max_value (IbBrightnessPowerdControl* self) { - if (! self->inited) - return 0; return self->max; } diff --git a/src/ib-brightness-powerd-control.h b/src/ib-brightness-powerd-control.h index 77e44cb..77f6c8d 100644 --- a/src/ib-brightness-powerd-control.h +++ b/src/ib-brightness-powerd-control.h @@ -21,11 +21,19 @@ #define __IB_BRIGHTNESS_POWERD_CONTROL_H__ #include -GDBusProxy* powerd_get_proxy(); + +typedef struct { + int max; + int min; + int dflt; + gboolean ab_supported; +} brightness_params_t; + +GDBusProxy* powerd_get_proxy(brightness_params_t *); typedef struct _IbBrightnessPowerdControl IbBrightnessPowerdControl; -IbBrightnessPowerdControl* ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy); +IbBrightnessPowerdControl* ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy, brightness_params_t params); void ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value); gint ib_brightness_powerd_control_get_value (IbBrightnessPowerdControl* self); gint ib_brightness_powerd_control_get_max_value (IbBrightnessPowerdControl* self); diff --git a/src/service.c b/src/service.c index 959e316..9be5eca 100644 --- a/src/service.c +++ b/src/service.c @@ -1044,6 +1044,7 @@ static void indicator_power_service_init (IndicatorPowerService * self) { GDBusProxy *powerd_proxy = NULL; + brightness_params_t powerd_brigtness_params; priv_t * p = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_TYPE_POWER_SERVICE, IndicatorPowerServicePrivate); @@ -1053,10 +1054,10 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); - powerd_proxy = powerd_get_proxy(); + powerd_proxy = powerd_get_proxy(&powerd_brigtness_params); if (powerd_proxy != NULL) { - p->brightness_powerd_control = ib_brightness_powerd_control_new(powerd_proxy); + p->brightness_powerd_control = ib_brightness_powerd_control_new(powerd_proxy, powerd_brigtness_params); } else { -- cgit v1.2.3 From a046fce39f86760337af2666bd8a883e42dc4fcf Mon Sep 17 00:00:00 2001 From: "Y.C cheng" Date: Wed, 5 Mar 2014 17:16:36 +0800 Subject: add GCancellable and cancel it before free --- src/ib-brightness-powerd-control.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ib-brightness-powerd-control.c b/src/ib-brightness-powerd-control.c index 461bb54..96afe7d 100644 --- a/src/ib-brightness-powerd-control.c +++ b/src/ib-brightness-powerd-control.c @@ -90,7 +90,7 @@ getBrightnessParams(GDBusProxy* powerd_proxy, int *min, int *max, int *dflt, gbo return TRUE; } -static gboolean setUserBrightness(GDBusProxy* powerd_proxy, int brightness) +static gboolean setUserBrightness(GDBusProxy* powerd_proxy, GCancellable *gcancel, int brightness) { GVariant *ret = NULL; GError *error = NULL; @@ -99,7 +99,7 @@ static gboolean setUserBrightness(GDBusProxy* powerd_proxy, int brightness) "setUserBrightness", g_variant_new("(i)", brightness), G_DBUS_CALL_FLAGS_NONE, - -1, NULL, &error); + -1, gcancel, &error); if (!ret) { g_warning("setUserBrightness failed: %s", error->message); g_error_free(error); @@ -113,6 +113,7 @@ static gboolean setUserBrightness(GDBusProxy* powerd_proxy, int brightness) struct _IbBrightnessPowerdControl { GDBusProxy *powerd_proxy; + GCancellable *gcancel; int min; int max; @@ -129,6 +130,7 @@ ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy, brightness_params_t control = g_new0 (IbBrightnessPowerdControl, 1); control->powerd_proxy = powerd_proxy; + control->gcancel = g_cancellable_new(); control->min = params.min; control->max = params.max; @@ -152,7 +154,7 @@ ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint va { value = self->min; } - ret = setUserBrightness(self->powerd_proxy, value); + ret = setUserBrightness(self->powerd_proxy, self->gcancel, value); if (ret) { self->current = value; @@ -174,6 +176,8 @@ ib_brightness_powerd_control_get_max_value (IbBrightnessPowerdControl* self) void ib_brightness_powerd_control_free (IbBrightnessPowerdControl *self) { + g_cancellable_cancel (self->gcancel); + g_object_unref (self->gcancel); g_object_unref (self->powerd_proxy); g_free (self); } -- cgit v1.2.3 From a67018fec5c2d6ffa54cff364c513223844559f3 Mon Sep 17 00:00:00 2001 From: "Y.C cheng" Date: Thu, 6 Mar 2014 11:27:12 +0800 Subject: refine and use default value as initial brightness value --- src/ib-brightness-powerd-control.c | 43 ++++++++++++++++++-------------------- src/service.c | 8 +++---- 2 files changed, 24 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/ib-brightness-powerd-control.c b/src/ib-brightness-powerd-control.c index 96afe7d..2136fcd 100644 --- a/src/ib-brightness-powerd-control.c +++ b/src/ib-brightness-powerd-control.c @@ -17,13 +17,6 @@ * Yuan-Chen Cheng */ -#include - -#include -#include -#include -#include - #include "ib-brightness-powerd-control.h" static gboolean getBrightnessParams(GDBusProxy* powerd_proxy, int *min, int *max, @@ -35,8 +28,7 @@ powerd_get_proxy(brightness_params_t *params) GError *error = NULL; gboolean ret; - if (params == NULL) - return NULL; + g_return_val_if_fail (params != NULL, NULL); GDBusProxy* powerd_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, @@ -79,9 +71,16 @@ getBrightnessParams(GDBusProxy* powerd_proxy, int *min, int *max, int *dflt, gbo NULL, G_DBUS_CALL_FLAGS_NONE, 400, NULL, &error); // timeout: 400 ms - if (!ret) { - g_warning("getBrightnessParams failed: %s", error->message); - g_error_free(error); + if (!ret) + { + if (error != NULL) + { + if (!g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) + { + g_warning("getBrightnessParams from powerd failed: %s", error->message); + } + g_error_free(error); + } return FALSE; } @@ -101,7 +100,7 @@ static gboolean setUserBrightness(GDBusProxy* powerd_proxy, GCancellable *gcance G_DBUS_CALL_FLAGS_NONE, -1, gcancel, &error); if (!ret) { - g_warning("setUserBrightness failed: %s", error->message); + g_warning("setUserBrightness via powerd failed: %s", error->message); g_error_free(error); return FALSE; } else { @@ -117,7 +116,7 @@ struct _IbBrightnessPowerdControl int min; int max; - int dflt; + int dflt; // defalut value gboolean ab_supported; int current; @@ -137,7 +136,11 @@ ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy, brightness_params_t control->dflt = params.dflt; control->ab_supported = params.ab_supported; - ib_brightness_powerd_control_set_value(control, control->max * 8 / 10); + // XXX: set the brightness value is the only way to sync the brightness value with + // powerd, and we should set the user prefered / last set brightness value upon startup. + // Before we have code to store last set brightness value or other mechanism, we set + // it to default brightness that powerd proposed. + ib_brightness_powerd_control_set_value(control, control->dflt); return control; } @@ -146,14 +149,8 @@ void ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value) { gboolean ret; - if (value > self->max) - { - value = self->max; - } - else if (value < self->min) - { - value = self->min; - } + + value = CLAMP(value, self->min, self->max); ret = setUserBrightness(self->powerd_proxy, self->gcancel, value); if (ret) { diff --git a/src/service.c b/src/service.c index 9be5eca..f6653f4 100644 --- a/src/service.c +++ b/src/service.c @@ -1043,8 +1043,8 @@ my_dispose (GObject * o) static void indicator_power_service_init (IndicatorPowerService * self) { - GDBusProxy *powerd_proxy = NULL; - brightness_params_t powerd_brigtness_params; + GDBusProxy *powerd_proxy; + brightness_params_t powerd_brightness_params; priv_t * p = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_TYPE_POWER_SERVICE, IndicatorPowerServicePrivate); @@ -1054,10 +1054,10 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); - powerd_proxy = powerd_get_proxy(&powerd_brigtness_params); + powerd_proxy = powerd_get_proxy(&powerd_brightness_params); if (powerd_proxy != NULL) { - p->brightness_powerd_control = ib_brightness_powerd_control_new(powerd_proxy, powerd_brigtness_params); + p->brightness_powerd_control = ib_brightness_powerd_control_new(powerd_proxy, powerd_brightness_params); } else { -- cgit v1.2.3 From 9936e22d5e70cd10988f328e8d86b1e5bc93ede9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 13 Mar 2014 09:05:34 -0500 Subject: in the new indicator_power_device_get_*() functions, use heap-allocated strings rather than relying on g_snprintf(). --- src/device.c | 147 ++++++++++++++++++++++++---------------------------------- src/device.h | 16 ++----- src/service.c | 43 ++++++++++------- 3 files changed, 89 insertions(+), 117 deletions(-) (limited to 'src') diff --git a/src/device.c b/src/device.c index e7384ee..37b1d8b 100644 --- a/src/device.c +++ b/src/device.c @@ -543,11 +543,10 @@ device_kind_to_localised_string (UpDeviceKind kind) * between 30 seconds and one minute; otherwise * * the empty string. */ -static void -get_brief_time_remaining (const IndicatorPowerDevice * device, - char * str, - gulong size) +static char * +get_brief_time_remaining (const IndicatorPowerDevice * device) { + gchar * str = NULL; const IndicatorPowerDevicePrivate * p = device->priv; if (p->time > 0) @@ -556,7 +555,7 @@ get_brief_time_remaining (const IndicatorPowerDevice * device, int hours = minutes / 60; minutes %= 60; - g_snprintf (str, size, "%0d:%02d", hours, minutes); + str = g_strdup_printf("%0d:%02d", hours, minutes); } else if (p->inestimable != NULL) { @@ -564,21 +563,15 @@ get_brief_time_remaining (const IndicatorPowerDevice * device, if (elapsed < 30) { - g_snprintf (str, size, _("estimating…")); + str = g_strdup_printf (_("estimating…")); } else if (elapsed < 60) { - g_snprintf (str, size, _("unknown")); + str = g_strdup_printf (_("unknown")); } - else - { - *str = '\0'; - } - } - else - { - *str = '\0'; } + + return str; } /** @@ -588,16 +581,12 @@ get_brief_time_remaining (const IndicatorPowerDevice * device, * * if the component is charging, it should be “H:MM to charge” * * if the component is discharging, it should be “H:MM left”. */ -static void -get_expanded_time_remaining (const IndicatorPowerDevice * device, - char * str, - gulong size) +static char* +get_expanded_time_remaining (const IndicatorPowerDevice * device) { + char * str = NULL; const IndicatorPowerDevicePrivate * p; - g_return_if_fail (str != NULL); - g_return_if_fail (size > 0); - *str = '\0'; g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); p = device->priv; @@ -610,35 +599,33 @@ get_expanded_time_remaining (const IndicatorPowerDevice * device, if (p->state == UP_DEVICE_STATE_CHARGING) { - g_snprintf (str, size, _("%0d:%02d to charge"), hours, minutes); + str = g_strdup_printf (_("%0d:%02d to charge"), hours, minutes); } else // discharging { - g_snprintf (str, size, _("%0d:%02d left"), hours, minutes); + str = g_strdup_printf (_("%0d:%02d left"), hours, minutes); } } else { - get_brief_time_remaining (device, str, size); + str = get_brief_time_remaining (device); } + + return str; } /** * The '''accessible time-remaining string''' for a component * should be the same as the expanded time-remaining string, * except the H:MM time should be rendered as “''H'' hours ''M'' minutes”, - * or just as “''M'' * minutes” if the time is less than one hour. + * or just as “''M'' minutes” if the time is less than one hour. */ -static void -get_accessible_time_remaining (const IndicatorPowerDevice * device, - char * str, - gulong size) +static char * +get_accessible_time_remaining (const IndicatorPowerDevice * device) { + char * str = NULL; const IndicatorPowerDevicePrivate * p; - g_return_if_fail (str != NULL); - g_return_if_fail (size > 0); - *str = '\0'; g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); p = device->priv; @@ -652,28 +639,30 @@ get_accessible_time_remaining (const IndicatorPowerDevice * device, if (p->state == UP_DEVICE_STATE_CHARGING) { if (hours > 0) - g_snprintf (str, size, _("%d %s %d %s to charge"), + str = g_strdup_printf (_("%d %s %d %s to charge"), hours, g_dngettext (NULL, "hour", "hours", hours), minutes, g_dngettext (NULL, "minute", "minutes", minutes)); else - g_snprintf (str, size, _("%d %s to charge"), + str = g_strdup_printf (_("%d %s to charge"), minutes, g_dngettext (NULL, "minute", "minutes", minutes)); } else // discharging { if (hours > 0) - g_snprintf (str, size, _("%d %s %d %s left"), + str = g_strdup_printf (_("%d %s %d %s left"), hours, g_dngettext (NULL, "hour", "hours", hours), minutes, g_dngettext (NULL, "minute", "minutes", minutes)); else - g_snprintf (str, size, _("%d %s left"), + str = g_strdup_printf (_("%d %s left"), minutes, g_dngettext (NULL, "minute", "minutes", minutes)); } } else { - get_brief_time_remaining (device, str, size); + str = get_brief_time_remaining (device); } + + return str; } /** @@ -709,66 +698,55 @@ time_is_relevant (const IndicatorPowerDevice * device) * visible label, except with the accessible time-remaining string * instead of the expanded time-remaining string. */ -static void +static char * get_menuitem_text (const IndicatorPowerDevice * device, - gchar * str, - gulong size, gboolean accessible) { + char * str = NULL; const IndicatorPowerDevicePrivate * p = device->priv; const char * kind_str = device_kind_to_localised_string (p->kind); if (p->state == UP_DEVICE_STATE_FULLY_CHARGED) { - g_snprintf (str, size, _("%s (charged)"), kind_str); + str = g_strdup_printf (_("%s (charged)"), kind_str); } else { - char buf[64]; + char * time_str = NULL; if (time_is_relevant (device)) { if (accessible) - get_accessible_time_remaining (device, buf, sizeof(buf)); + time_str = get_accessible_time_remaining (device); else - get_expanded_time_remaining (device, buf, sizeof(buf)); - } - else - { - *buf = '\0'; + time_str = get_expanded_time_remaining (device); } - if (*buf) - g_snprintf (str, size, _("%s (%s)"), kind_str, buf); + if (time_str && *time_str) + str = g_strdup_printf (_("%s (%s)"), kind_str, time_str); else - g_strlcpy (str, kind_str, size); + str = g_strdup (kind_str); + + g_free (time_str); } + + return str; } -void -indicator_power_device_get_readable_text (const IndicatorPowerDevice * device, - gchar * str, - gulong size) +char * +indicator_power_device_get_readable_text (const IndicatorPowerDevice * device) { - g_return_if_fail (str != NULL); - g_return_if_fail (size > 0); - *str = '\0'; g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); - get_menuitem_text (device, str, size, FALSE); + return get_menuitem_text (device, FALSE); } -void -indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device, - gchar * str, - gulong size) +char * +indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device) { - g_return_if_fail (str != NULL); - g_return_if_fail (size > 0); - *str = '\0'; g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); - get_menuitem_text (device, str, size, TRUE); + return get_menuitem_text (device, TRUE); } /** @@ -783,19 +761,15 @@ indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device, * * If both conditions are true, the time and percentage should be separated by a space. */ -void +char* indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, - gchar * str, - gulong size, gboolean want_time, gboolean want_percent) { - char tr[64]; + char * str = NULL; + char * time_str = NULL; const IndicatorPowerDevicePrivate * p; - g_return_if_fail (str != NULL); - g_return_if_fail (size > 0); - *str = '\0'; g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); p = device->priv; @@ -811,42 +785,41 @@ indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, // try to build the time-remaining string if (want_time) { - get_brief_time_remaining (device, tr, sizeof(tr)); - - if (!*tr) - want_time = FALSE; + time_str = get_brief_time_remaining (device); + want_time = time_str && *time_str; } if (want_time && want_percent) { - g_snprintf (str, size, _("(%s, %.0lf%%)"), tr, p->percentage); + str = g_strdup_printf (_("(%s, %.0lf%%)"), time_str, p->percentage); } else if (want_time) { - g_snprintf (str, size, _("(%s)"), tr); + str = g_strdup_printf (_("(%s)"), time_str); } else if (want_percent) { - g_snprintf (str, size, _("(%.0lf%%)"), p->percentage); + str = g_strdup_printf (_("(%.0lf%%)"), p->percentage); } else { - *str = '\0'; + str = NULL; } + + g_free (time_str); + return str; } /** * Regardless, the accessible name for the whole menu title should be the same * as the accessible name for that thing’s component inside the menu itself. */ -void +char * indicator_power_device_get_accessible_title (const IndicatorPowerDevice * device, - gchar * str, - gulong size, gboolean want_time G_GNUC_UNUSED, gboolean want_percent G_GNUC_UNUSED) { - indicator_power_device_get_accessible_text (device, str, size); + return indicator_power_device_get_accessible_text (device); } /*** diff --git a/src/device.h b/src/device.h index 65c6767..3a10f89 100644 --- a/src/device.h +++ b/src/device.h @@ -126,23 +126,15 @@ GStrv indicator_power_device_get_icon_names (const IndicatorPower GIcon * indicator_power_device_get_gicon (const IndicatorPowerDevice * device); -void indicator_power_device_get_readable_text (const IndicatorPowerDevice * device, - gchar * str, - gulong size); +char * indicator_power_device_get_readable_text (const IndicatorPowerDevice * device); -void indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device, - gchar * str, - gulong size); +char * indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device); -void indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, - gchar * str, - gulong size, +char * indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, gboolean want_time, gboolean want_percent); -void indicator_power_device_get_accessible_title (const IndicatorPowerDevice * device, - gchar * str, - gulong size, +char * indicator_power_device_get_accessible_title (const IndicatorPowerDevice * device, gboolean want_time, gboolean want_percent); diff --git a/src/service.c b/src/service.c index 248f953..405ad96 100644 --- a/src/service.c +++ b/src/service.c @@ -323,26 +323,32 @@ create_header_state (IndicatorPowerService * self) if (p->primary_device != NULL) { - char buf[128]; + char * title; GIcon * icon; const gboolean want_time = g_settings_get_boolean (p->settings, SETTINGS_SHOW_TIME_S); const gboolean want_percent = g_settings_get_boolean (p->settings, SETTINGS_SHOW_PERCENTAGE_S); - indicator_power_device_get_readable_title (p->primary_device, - buf, sizeof(buf), - want_time, - want_percent); - if (*buf) - g_variant_builder_add (&b, "{sv}", "label", g_variant_new_string (buf)); - - - indicator_power_device_get_accessible_title (p->primary_device, - buf, sizeof(buf), - want_time, - want_percent); - if (*buf) - g_variant_builder_add (&b, "{sv}", "accessible-desc", g_variant_new_string (buf)); + title = indicator_power_device_get_readable_title (p->primary_device, + want_time, + want_percent); + if (title) + { + if (*title) + g_variant_builder_add (&b, "{sv}", "label", g_variant_new_take_string (title)); + else + g_free (title); + } + title = indicator_power_device_get_accessible_title (p->primary_device, + want_time, + want_percent); + if (title) + { + if (*title) + g_variant_builder_add (&b, "{sv}", "accessible-desc", g_variant_new_take_string (title)); + else + g_free (title); + } if ((icon = indicator_power_device_get_gicon (p->primary_device))) { @@ -375,12 +381,13 @@ append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device) if (kind != UP_DEVICE_KIND_LINE_POWER) { - char buf[128]; + char * label; GMenuItem * item; GIcon * icon; - indicator_power_device_get_readable_text (device, buf, sizeof(buf)); - item = g_menu_item_new (buf, "indicator.activate-statistics"); + label = indicator_power_device_get_readable_text (device); + item = g_menu_item_new (label, "indicator.activate-statistics"); + g_free (label); if ((icon = indicator_power_device_get_gicon (device))) { -- cgit v1.2.3 From 3c4a789e9607a312d7230b797d875f9dab02d2d1 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 13 Mar 2014 09:15:27 -0500 Subject: remove INDICATOR_IS_POWER_DEVICE(device) tests from private functions --- src/device.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/device.c b/src/device.c index 37b1d8b..d07f6c5 100644 --- a/src/device.c +++ b/src/device.c @@ -585,11 +585,7 @@ static char* get_expanded_time_remaining (const IndicatorPowerDevice * device) { char * str = NULL; - const IndicatorPowerDevicePrivate * p; - - g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); - - p = device->priv; + const IndicatorPowerDevicePrivate * p = device->priv; if (p->time && ((p->state == UP_DEVICE_STATE_CHARGING) || (p->state == UP_DEVICE_STATE_DISCHARGING))) { @@ -624,11 +620,7 @@ static char * get_accessible_time_remaining (const IndicatorPowerDevice * device) { char * str = NULL; - const IndicatorPowerDevicePrivate * p; - - g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); - - p = device->priv; + const IndicatorPowerDevicePrivate * p = device->priv; if (p->time && ((p->state == UP_DEVICE_STATE_CHARGING) || (p->state == UP_DEVICE_STATE_DISCHARGING))) { -- cgit v1.2.3 From a49c013fd0340bc4e6f8bb9dd6f4b7efdb20994a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 13 Mar 2014 09:16:54 -0500 Subject: copyediting: add const, fix misaligned whitespace --- src/device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/device.c b/src/device.c index d07f6c5..854dbfb 100644 --- a/src/device.c +++ b/src/device.c @@ -552,7 +552,7 @@ get_brief_time_remaining (const IndicatorPowerDevice * device) if (p->time > 0) { int minutes = p->time / 60; - int hours = minutes / 60; + const int hours = minutes / 60; minutes %= 60; str = g_strdup_printf("%0d:%02d", hours, minutes); @@ -604,7 +604,7 @@ get_expanded_time_remaining (const IndicatorPowerDevice * device) } else { - str = get_brief_time_remaining (device); + str = get_brief_time_remaining (device); } return str; -- cgit v1.2.3 From bee479452605a446567e4e4d0c0ae6d008ae8015 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 13 Mar 2014 10:31:33 -0500 Subject: in the new indicator_power_device_get_*() functions, use g_return_val_if_fail(foo, NULL) rather than g_return_if_fail(foo) --- src/device.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/device.c b/src/device.c index 854dbfb..ed3c399 100644 --- a/src/device.c +++ b/src/device.c @@ -728,7 +728,7 @@ get_menuitem_text (const IndicatorPowerDevice * device, char * indicator_power_device_get_readable_text (const IndicatorPowerDevice * device) { - g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); + g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), NULL); return get_menuitem_text (device, FALSE); } @@ -736,7 +736,7 @@ indicator_power_device_get_readable_text (const IndicatorPowerDevice * device) char * indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device) { - g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); + g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), NULL); return get_menuitem_text (device, TRUE); } @@ -762,7 +762,7 @@ indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, char * time_str = NULL; const IndicatorPowerDevicePrivate * p; - g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); + g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), NULL); p = device->priv; @@ -811,6 +811,8 @@ indicator_power_device_get_accessible_title (const IndicatorPowerDevice * device gboolean want_time G_GNUC_UNUSED, gboolean want_percent G_GNUC_UNUSED) { + g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), NULL); + return indicator_power_device_get_accessible_text (device); } -- cgit v1.2.3 From d6159805fc552643902321b3d41d1a0a53594f05 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 13 Mar 2014 17:27:29 -0500 Subject: add lp:~charlesk/indicator-power/lp-1256872 --- src/service.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 405ad96..1d8ba3e 100644 --- a/src/service.c +++ b/src/service.c @@ -375,7 +375,7 @@ create_header_state (IndicatorPowerService * self) ***/ static void -append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device) +append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device, int profile) { const UpDeviceKind kind = indicator_power_device_get_kind (device); @@ -386,7 +386,7 @@ append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device) GIcon * icon; label = indicator_power_device_get_readable_text (device); - item = g_menu_item_new (label, "indicator.activate-statistics"); + item = g_menu_item_new (label, NULL); g_free (label); if ((icon = indicator_power_device_get_gicon (device))) @@ -404,8 +404,11 @@ append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device) g_object_unref (icon); } - g_menu_item_set_action_and_target(item, "indicator.activate-statistics", "s", - indicator_power_device_get_object_path (device)); + if (profile == PROFILE_DESKTOP) + { + g_menu_item_set_action_and_target(item, "indicator.activate-statistics", "s", + indicator_power_device_get_object_path (device)); + } g_menu_append_item (menu, item); g_object_unref (item); @@ -414,13 +417,13 @@ append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device) static GMenuModel * -create_desktop_devices_section (IndicatorPowerService * self) +create_desktop_devices_section (IndicatorPowerService * self, int profile) { GList * l; GMenu * menu = g_menu_new (); for (l=self->priv->devices; l!=NULL; l=l->next) - append_device_to_menu (menu, l->data); + append_device_to_menu (menu, l->data, profile); return G_MENU_MODEL (menu); } @@ -595,8 +598,8 @@ rebuild_now (IndicatorPowerService * self, guint sections) if (sections & SECTION_DEVICES) { - rebuild_section (desktop->submenu, 0, create_desktop_devices_section (self)); - rebuild_section (greeter->submenu, 0, create_desktop_devices_section (self)); + rebuild_section (desktop->submenu, 0, create_desktop_devices_section (self, PROFILE_DESKTOP)); + rebuild_section (greeter->submenu, 0, create_desktop_devices_section (self, PROFILE_DESKTOP_GREETER)); } if (sections & SECTION_SETTINGS) @@ -647,12 +650,12 @@ create_menu (IndicatorPowerService * self, int profile) break; case PROFILE_DESKTOP: - sections[n++] = create_desktop_devices_section (self); + sections[n++] = create_desktop_devices_section (self, PROFILE_DESKTOP); sections[n++] = create_desktop_settings_section (self); break; case PROFILE_DESKTOP_GREETER: - sections[n++] = create_desktop_devices_section (self); + sections[n++] = create_desktop_devices_section (self, PROFILE_DESKTOP_GREETER); break; } -- cgit v1.2.3 From b3ec90e07e00f3f28665207987bb9fb73153664b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 19 Mar 2014 14:15:54 -0500 Subject: when choosing a primary device and more than one battery is found, accumulate their percentages and time-remaining properties as per the spec revisions in bug #880881. --- src/service.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 125 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 248f953..e042e9e 100644 --- a/src/service.c +++ b/src/service.c @@ -1125,6 +1125,129 @@ indicator_power_service_set_device_provider (IndicatorPowerService * self, } } +/* If a device has multiple batteries and uses only one of them at a time, + they should be presented as separate items inside the battery menu, + but everywhere else they should be aggregated (bug 880881). + Their percentages should be averaged. If any are discharging, + the aggregated time remaining should be the maximum of the times + for all those that are discharging, plus the sum of the times + for all those that are idle. Otherwise, the aggregated time remaining + should be the the maximum of the times for all those that are charging. */ +static IndicatorPowerDevice * +create_totalled_battery_device (const GList * devices) +{ + const GList * l; + guint n_charged = 0; + guint n_charging = 0; + guint n_discharging = 0; + guint n_batteries = 0; + double sum_percent = 0; + time_t max_discharge_time = 0; + time_t max_charge_time = 0; + time_t sum_charged_time = 0; + IndicatorPowerDevice * device = NULL; + + for (l=devices; l!=NULL; l=l->next) + { + const IndicatorPowerDevice * device = INDICATOR_POWER_DEVICE(l->data); + + if (indicator_power_device_get_kind(device) == UP_DEVICE_KIND_BATTERY) + { + const double percent = indicator_power_device_get_percentage (device); + const time_t t = indicator_power_device_get_time (device); + const UpDeviceState state = indicator_power_device_get_state (device); + + ++n_batteries; + + if (percent > 0.01) + sum_percent += percent; + + if (state == UP_DEVICE_STATE_CHARGING) + { + ++n_charging; + max_charge_time = MAX(max_charge_time, t); + } + else if (state == UP_DEVICE_STATE_DISCHARGING) + { + ++n_discharging; + max_discharge_time = MAX(max_discharge_time, t); + } + else if (state == UP_DEVICE_STATE_FULLY_CHARGED) + { + ++n_charged; + sum_charged_time += t; + } + } + } + + if (n_batteries > 1) + { + const double percent = sum_percent / n_batteries; + UpDeviceState state; + time_t time_left; + + if (n_discharging > 0) + { + state = UP_DEVICE_STATE_DISCHARGING; + time_left = max_discharge_time + sum_charged_time; + } + else if (n_charging > 0) + { + state = UP_DEVICE_STATE_CHARGING; + time_left = max_charge_time; + } + else if (n_charged > 0) + { + state = UP_DEVICE_STATE_FULLY_CHARGED; + time_left = 0; + } + else + { + state = UP_DEVICE_STATE_UNKNOWN; + time_left = 0; + } + + device = indicator_power_device_new (NULL, + UP_DEVICE_KIND_BATTERY, + percent, + state, + time_left); + } + + return device; +} + +/** + * If there are multiple UP_DEVICE_KIND_BATTERY devices in the list, + * they're merged into a new 'totalled' device representing the sum of them. + * + * Returns: (element-type IndicatorPowerDevice)(transfer full): a list of devices + */ +static GList* +merge_batteries_together (GList * devices) +{ + GList * ret; + IndicatorPowerDevice * merged_device; + + if ((merged_device = create_totalled_battery_device (devices))) + { + GList * l; + + ret = g_list_append (NULL, merged_device); + + for (l=devices; l!=NULL; l=l->next) + if (indicator_power_device_get_kind(INDICATOR_POWER_DEVICE(l->data)) != UP_DEVICE_KIND_BATTERY) + ret = g_list_append (ret, g_object_ref(l->data)); + } + else /* not enough batteries to merge */ + { + ret = g_list_copy (devices); + g_list_foreach (ret, (GFunc)g_object_ref, NULL); + } + + return ret; +} + IndicatorPowerDevice * indicator_power_service_choose_primary_device (GList * devices) { @@ -1132,13 +1255,10 @@ indicator_power_service_choose_primary_device (GList * devices) if (devices != NULL) { - GList * tmp; - - tmp = g_list_copy (devices); + GList * tmp = merge_batteries_together (devices); tmp = g_list_sort (tmp, device_compare_func); primary = g_object_ref (tmp->data); - - g_list_free (tmp); + g_list_free_full (tmp, (GDestroyNotify)g_object_unref); } return primary; -- cgit v1.2.3 From 9b33101ad8a9fc093e226c25e497fd8b1d51aee5 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Mar 2014 14:35:17 -0500 Subject: add translator comments to the new translatable strings. --- src/device.c | 53 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/device.c b/src/device.c index e7384ee..8b97ef5 100644 --- a/src/device.c +++ b/src/device.c @@ -610,10 +610,12 @@ get_expanded_time_remaining (const IndicatorPowerDevice * device, if (p->state == UP_DEVICE_STATE_CHARGING) { + /* TRANSLATORS: H:MM (hours, minutes) to charge the battery. Example: "1:30 to charge" */ g_snprintf (str, size, _("%0d:%02d to charge"), hours, minutes); } else // discharging { + /* TRANSLATORS: H:MM (hours, minutes) to discharge the battery. Example: "1:30 left"*/ g_snprintf (str, size, _("%0d:%02d left"), hours, minutes); } } @@ -652,22 +654,38 @@ get_accessible_time_remaining (const IndicatorPowerDevice * device, if (p->state == UP_DEVICE_STATE_CHARGING) { if (hours > 0) - g_snprintf (str, size, _("%d %s %d %s to charge"), - hours, g_dngettext (NULL, "hour", "hours", hours), - minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + { + /* TRANSLATORS: "X (hour,hours) Y (minute,minutes) to charge" the battery. + Example: "1 hour 10 minutes to charge" */ + g_snprintf (str, size, _("%d %s %d %s to charge"), + hours, g_dngettext (NULL, "hour", "hours", hours), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + } else - g_snprintf (str, size, _("%d %s to charge"), - minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + { + /* TRANSLATORS: "Y (minute,minutes) to charge" the battery. + Example: "59 minutes to charge" */ + g_snprintf (str, size, _("%d %s to charge"), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + } } else // discharging { if (hours > 0) - g_snprintf (str, size, _("%d %s %d %s left"), - hours, g_dngettext (NULL, "hour", "hours", hours), - minutes, g_dngettext (NULL, "minute", "minutes", minutes)); - else - g_snprintf (str, size, _("%d %s left"), - minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + { + /* TRANSLATORS: "X (hour,hours) Y (minute,minutes) left" until the battery's empty. + Example: "1 hour 10 minutes left" */ + g_snprintf (str, size, _("%d %s %d %s left"), + hours, g_dngettext (NULL, "hour", "hours", hours), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + } + else + { + /* TRANSLATORS: "Y (minute,minutes) left" until the battery's empty. + Example: "59 minutes left" */ + g_snprintf (str, size, _("%d %s left"), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + } } } else @@ -720,6 +738,7 @@ get_menuitem_text (const IndicatorPowerDevice * device, if (p->state == UP_DEVICE_STATE_FULLY_CHARGED) { + /* TRANSLATORS: example: "battery (charged)" */ g_snprintf (str, size, _("%s (charged)"), kind_str); } else @@ -739,9 +758,14 @@ get_menuitem_text (const IndicatorPowerDevice * device, } if (*buf) - g_snprintf (str, size, _("%s (%s)"), kind_str, buf); + { + /* TRANSLATORS: example: "battery (time remaining)" */ + g_snprintf (str, size, _("%s (%s)"), kind_str, buf); + } else - g_strlcpy (str, kind_str, size); + { + g_strlcpy (str, kind_str, size); + } } } @@ -819,14 +843,17 @@ indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, if (want_time && want_percent) { + /* TRANSLATORS: after the icon, a time-remaining string + battery %. Example: "(0:59, 33%)" */ g_snprintf (str, size, _("(%s, %.0lf%%)"), tr, p->percentage); } else if (want_time) { + /* TRANSLATORS: after the icon, a time-remaining string Example: "(0:59)" */ g_snprintf (str, size, _("(%s)"), tr); } else if (want_percent) { + /* TRANSLATORS: after the icon, a battery %. Example: "(33%)" */ g_snprintf (str, size, _("(%.0lf%%)"), p->percentage); } else -- cgit v1.2.3 From 0b58eeb4ac217053c261444accc1124463e1ee3f Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 27 Mar 2014 13:17:22 +0100 Subject: Use com.canonical.indicator.basic menu item for device items That menu item can handle non-square icons. --- src/service.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/service.c b/src/service.c index 1d8ba3e..1a4e24a 100644 --- a/src/service.c +++ b/src/service.c @@ -389,6 +389,8 @@ append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device, int pr item = g_menu_item_new (label, NULL); g_free (label); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.basic"); + if ((icon = indicator_power_device_get_gicon (device))) { GVariant * serialized_icon = g_icon_serialize (icon); -- cgit v1.2.3 From b36744ef3a292f8027d90ebecded9f751c199af7 Mon Sep 17 00:00:00 2001 From: Iain Lane Date: Tue, 15 Apr 2014 14:08:08 +0100 Subject: Don't add the brightness entry to the phone profile; it's been removed by design --- src/service.c | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 00efe9b..46ad802 100644 --- a/src/service.c +++ b/src/service.c @@ -491,24 +491,6 @@ percentage_to_brightness (IndicatorPowerService * self, double percentage) return (int)(lo + (percentage*(hi-lo))); } -static GMenuItem * -create_brightness_menuitem (IndicatorPowerService * self) -{ - int lo, hi; - GMenuItem * item; - - get_brightness_range (self, &lo, &hi); - - item = g_menu_item_new (NULL, "indicator.brightness"); - g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.unity.slider"); - g_menu_item_set_attribute (item, "min-value", "d", brightness_to_percentage (self, lo)); - g_menu_item_set_attribute (item, "max-value", "d", brightness_to_percentage (self, hi)); - g_menu_item_set_attribute (item, "min-icon", "s", "torch-off" ); - g_menu_item_set_attribute (item, "max-icon", "s", "torch-on" ); - - return item; -} - static GVariant * action_state_for_brightness (IndicatorPowerService * self) { @@ -574,18 +556,12 @@ create_desktop_settings_section (IndicatorPowerService * self G_GNUC_UNUSED) } static GMenuModel * -create_phone_settings_section (IndicatorPowerService * self G_GNUC_UNUSED) +create_phone_settings_section (IndicatorPowerService * self) { GMenu * section; - GMenuItem * item; section = g_menu_new (); - - item = create_brightness_menuitem (self); - g_menu_append_item (section, item); update_brightness_action_state (self); - g_object_unref (item); - g_menu_append (section, _("Battery settings…"), "indicator.activate-phone-settings"); return G_MENU_MODEL (section); -- cgit v1.2.3 From bab79c8d63dbe42a6ee3128b3aa55f17fd0dce89 Mon Sep 17 00:00:00 2001 From: Ricardo Salveti de Araujo Date: Mon, 28 Apr 2014 16:15:18 -0700 Subject: updating code to reflect latest powerd dbus API changes --- src/ib-brightness-powerd-control.c | 14 ++++++++------ src/ib-brightness-powerd-control.h | 3 ++- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ib-brightness-powerd-control.c b/src/ib-brightness-powerd-control.c index 2136fcd..9e8815b 100644 --- a/src/ib-brightness-powerd-control.c +++ b/src/ib-brightness-powerd-control.c @@ -19,8 +19,8 @@ #include "ib-brightness-powerd-control.h" -static gboolean getBrightnessParams(GDBusProxy* powerd_proxy, int *min, int *max, - int *dflt, gboolean *ab_supported); +static gboolean getBrightnessParams(GDBusProxy* powerd_proxy, int *dim, int *min, + int *max, int *dflt, gboolean *ab_supported); GDBusProxy* powerd_get_proxy(brightness_params_t *params) @@ -46,8 +46,8 @@ powerd_get_proxy(brightness_params_t *params) return NULL; } - ret = getBrightnessParams(powerd_proxy, &(params->min), &(params->max), - &(params->dflt), &(params->ab_supported)); + ret = getBrightnessParams(powerd_proxy, &(params->dim), &(params->min), + &(params->max), &(params->dflt), &(params->ab_supported)); if (! ret) { @@ -61,7 +61,7 @@ powerd_get_proxy(brightness_params_t *params) static gboolean -getBrightnessParams(GDBusProxy* powerd_proxy, int *min, int *max, int *dflt, gboolean *ab_supported) +getBrightnessParams(GDBusProxy* powerd_proxy, int *dim, int *min, int *max, int *dflt, gboolean *ab_supported) { GVariant *ret = NULL; GError *error = NULL; @@ -84,7 +84,7 @@ getBrightnessParams(GDBusProxy* powerd_proxy, int *min, int *max, int *dflt, gbo return FALSE; } - g_variant_get(ret, "((iiib))", min, max, dflt, ab_supported); + g_variant_get(ret, "((iiiib))", dim, min, max, dflt, ab_supported); g_variant_unref(ret); return TRUE; } @@ -114,6 +114,7 @@ struct _IbBrightnessPowerdControl GDBusProxy *powerd_proxy; GCancellable *gcancel; + int dim; int min; int max; int dflt; // defalut value @@ -131,6 +132,7 @@ ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy, brightness_params_t control->powerd_proxy = powerd_proxy; control->gcancel = g_cancellable_new(); + control->dim = params.dim; control->min = params.min; control->max = params.max; control->dflt = params.dflt; diff --git a/src/ib-brightness-powerd-control.h b/src/ib-brightness-powerd-control.h index 77f6c8d..95de1f4 100644 --- a/src/ib-brightness-powerd-control.h +++ b/src/ib-brightness-powerd-control.h @@ -23,8 +23,9 @@ #include typedef struct { - int max; + int dim; int min; + int max; int dflt; gboolean ab_supported; } brightness_params_t; -- cgit v1.2.3 From 8c874cb5a9f58ab9d1885dabb24e548afaa9b711 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 5 May 2014 10:21:42 -0500 Subject: prefer the 'battery-020-charging' icon to the 'battery-low-charging' one because the former is more precise so its icon is more likely to be close to the actual actual battery level. --- src/device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/device.c b/src/device.c index e3b655a..8780d72 100644 --- a/src/device.c +++ b/src/device.c @@ -416,8 +416,9 @@ indicator_power_device_get_icon_names (const IndicatorPowerDevice * device) case UP_DEVICE_STATE_CHARGING: suffix_str = get_device_icon_suffix (percentage); index_str = get_device_icon_index (percentage); - g_ptr_array_add (names, g_strdup_printf ("%s-%s-charging-symbolic", kind_str, suffix_str)); + g_ptr_array_add (names, g_strdup_printf ("%s-%s-charging", kind_str, index_str)); g_ptr_array_add (names, g_strdup_printf ("gpm-%s-%s-charging", kind_str, index_str)); + g_ptr_array_add (names, g_strdup_printf ("%s-%s-charging-symbolic", kind_str, suffix_str)); g_ptr_array_add (names, g_strdup_printf ("%s-%s-charging", kind_str, suffix_str)); break; -- cgit v1.2.3 From 2769c7f764177e69870e92dabd207bb352cff0bc Mon Sep 17 00:00:00 2001 From: Alberto Aguirre Date: Mon, 16 Jun 2014 22:58:17 -0500 Subject: Changes to address setBrightness interface moving from powerd to unity-system-compositor --- src/ib-brightness-powerd-control.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ib-brightness-powerd-control.c b/src/ib-brightness-powerd-control.c index 9e8815b..ef18ad6 100644 --- a/src/ib-brightness-powerd-control.c +++ b/src/ib-brightness-powerd-control.c @@ -55,8 +55,26 @@ powerd_get_proxy(brightness_params_t *params) g_object_unref (powerd_proxy); return NULL; } - - return powerd_proxy; + + g_object_unref (powerd_proxy); + + GDBusProxy* uscreen_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "com.canonical.Unity.Screen", + "/com/canonical/Unity/Screen", + "com.canonical.Unity.Screen", + NULL, + &error); + + if (error != NULL) + { + g_debug ("could not connect to unity screen: %s", error->message); + g_error_free (error); + return NULL; + } + + return uscreen_proxy; } -- cgit v1.2.3 From 9e9a0da8c20c64dd394d98b94955e58911b2c53e Mon Sep 17 00:00:00 2001 From: Alberto Aguirre Date: Thu, 19 Jun 2014 10:04:01 -0500 Subject: Remove references to powerd since the brightness interface is now provided by Unity.Screen --- src/Makefile.am | 4 +- src/ib-brightness-powerd-control.c | 201 ----------------------------------- src/ib-brightness-powerd-control.h | 43 -------- src/ib-brightness-uscreen-control.c | 202 ++++++++++++++++++++++++++++++++++++ src/ib-brightness-uscreen-control.h | 43 ++++++++ src/service.c | 28 ++--- 6 files changed, 261 insertions(+), 260 deletions(-) delete mode 100644 src/ib-brightness-powerd-control.c delete mode 100644 src/ib-brightness-powerd-control.h create mode 100644 src/ib-brightness-uscreen-control.c create mode 100644 src/ib-brightness-uscreen-control.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 2461592..3f71b60 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,8 +46,8 @@ libindciatorpower_upower_a_LDFLAGS = $(COVERAGE_LDFLAGS) libindicatorpower_service_a_SOURCES = \ ib-brightness-control.c \ ib-brightness-control.h \ - ib-brightness-powerd-control.c \ - ib-brightness-powerd-control.h \ + ib-brightness-uscreen-control.c \ + ib-brightness-uscreen-control.h \ device-provider.c \ device-provider.h \ device.c \ diff --git a/src/ib-brightness-powerd-control.c b/src/ib-brightness-powerd-control.c deleted file mode 100644 index ef18ad6..0000000 --- a/src/ib-brightness-powerd-control.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * 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: - * Yuan-Chen Cheng - */ - -#include "ib-brightness-powerd-control.h" - -static gboolean getBrightnessParams(GDBusProxy* powerd_proxy, int *dim, int *min, - int *max, int *dflt, gboolean *ab_supported); - -GDBusProxy* -powerd_get_proxy(brightness_params_t *params) -{ - GError *error = NULL; - gboolean ret; - - g_return_val_if_fail (params != NULL, NULL); - - GDBusProxy* powerd_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "com.canonical.powerd", - "/com/canonical/powerd", - "com.canonical.powerd", - NULL, - &error); - - if (error != NULL) - { - g_debug ("could not connect to powerd: %s", error->message); - g_error_free (error); - return NULL; - } - - ret = getBrightnessParams(powerd_proxy, &(params->dim), &(params->min), - &(params->max), &(params->dflt), &(params->ab_supported)); - - if (! ret) - { - g_debug ("can't get brightness parameters from powerd"); - g_object_unref (powerd_proxy); - return NULL; - } - - g_object_unref (powerd_proxy); - - GDBusProxy* uscreen_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "com.canonical.Unity.Screen", - "/com/canonical/Unity/Screen", - "com.canonical.Unity.Screen", - NULL, - &error); - - if (error != NULL) - { - g_debug ("could not connect to unity screen: %s", error->message); - g_error_free (error); - return NULL; - } - - return uscreen_proxy; -} - - -static gboolean -getBrightnessParams(GDBusProxy* powerd_proxy, int *dim, int *min, int *max, int *dflt, gboolean *ab_supported) -{ - GVariant *ret = NULL; - GError *error = NULL; - - ret = g_dbus_proxy_call_sync(powerd_proxy, - "getBrightnessParams", - NULL, - G_DBUS_CALL_FLAGS_NONE, - 400, NULL, &error); // timeout: 400 ms - if (!ret) - { - if (error != NULL) - { - if (!g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) - { - g_warning("getBrightnessParams from powerd failed: %s", error->message); - } - g_error_free(error); - } - return FALSE; - } - - g_variant_get(ret, "((iiiib))", dim, min, max, dflt, ab_supported); - g_variant_unref(ret); - return TRUE; -} - -static gboolean setUserBrightness(GDBusProxy* powerd_proxy, GCancellable *gcancel, int brightness) -{ - GVariant *ret = NULL; - GError *error = NULL; - - ret = g_dbus_proxy_call_sync(powerd_proxy, - "setUserBrightness", - g_variant_new("(i)", brightness), - G_DBUS_CALL_FLAGS_NONE, - -1, gcancel, &error); - if (!ret) { - g_warning("setUserBrightness via powerd failed: %s", error->message); - g_error_free(error); - return FALSE; - } else { - g_variant_unref(ret); - return TRUE; - } -} - -struct _IbBrightnessPowerdControl -{ - GDBusProxy *powerd_proxy; - GCancellable *gcancel; - - int dim; - int min; - int max; - int dflt; // defalut value - gboolean ab_supported; - - int current; -}; - -IbBrightnessPowerdControl* -ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy, brightness_params_t params) -{ - IbBrightnessPowerdControl *control; - - control = g_new0 (IbBrightnessPowerdControl, 1); - control->powerd_proxy = powerd_proxy; - control->gcancel = g_cancellable_new(); - - control->dim = params.dim; - control->min = params.min; - control->max = params.max; - control->dflt = params.dflt; - control->ab_supported = params.ab_supported; - - // XXX: set the brightness value is the only way to sync the brightness value with - // powerd, and we should set the user prefered / last set brightness value upon startup. - // Before we have code to store last set brightness value or other mechanism, we set - // it to default brightness that powerd proposed. - ib_brightness_powerd_control_set_value(control, control->dflt); - - return control; -} - -void -ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value) -{ - gboolean ret; - - value = CLAMP(value, self->min, self->max); - ret = setUserBrightness(self->powerd_proxy, self->gcancel, value); - if (ret) - { - self->current = value; - } -} - -gint -ib_brightness_powerd_control_get_value (IbBrightnessPowerdControl* self) -{ - return self->current; -} - -gint -ib_brightness_powerd_control_get_max_value (IbBrightnessPowerdControl* self) -{ - return self->max; -} - -void -ib_brightness_powerd_control_free (IbBrightnessPowerdControl *self) -{ - g_cancellable_cancel (self->gcancel); - g_object_unref (self->gcancel); - g_object_unref (self->powerd_proxy); - g_free (self); -} - diff --git a/src/ib-brightness-powerd-control.h b/src/ib-brightness-powerd-control.h deleted file mode 100644 index 95de1f4..0000000 --- a/src/ib-brightness-powerd-control.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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: - * Y.C Cheng - */ - -#ifndef __IB_BRIGHTNESS_POWERD_CONTROL_H__ -#define __IB_BRIGHTNESS_POWERD_CONTROL_H__ - -#include - -typedef struct { - int dim; - int min; - int max; - int dflt; - gboolean ab_supported; -} brightness_params_t; - -GDBusProxy* powerd_get_proxy(brightness_params_t *); - -typedef struct _IbBrightnessPowerdControl IbBrightnessPowerdControl; - -IbBrightnessPowerdControl* ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy, brightness_params_t params); -void ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value); -gint ib_brightness_powerd_control_get_value (IbBrightnessPowerdControl* self); -gint ib_brightness_powerd_control_get_max_value (IbBrightnessPowerdControl* self); -void ib_brightness_powerd_control_free (IbBrightnessPowerdControl *self); - -#endif diff --git a/src/ib-brightness-uscreen-control.c b/src/ib-brightness-uscreen-control.c new file mode 100644 index 0000000..4f8cd3e --- /dev/null +++ b/src/ib-brightness-uscreen-control.c @@ -0,0 +1,202 @@ +/* + * 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: + * Yuan-Chen Cheng + */ + +#include "ib-brightness-uscreen-control.h" + +static gboolean getBrightnessParams(GDBusProxy* powerd_proxy, int *dim, int *min, + int *max, int *dflt, gboolean *ab_supported); + +GDBusProxy* +uscreen_get_proxy(brightness_params_t *params) +{ + GError *error = NULL; + gboolean ret; + + g_return_val_if_fail (params != NULL, NULL); + + /* For now we still need to obtain the brigthness params from powerd */ + GDBusProxy* powerd_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "com.canonical.powerd", + "/com/canonical/powerd", + "com.canonical.powerd", + NULL, + &error); + + if (error != NULL) + { + g_debug ("could not connect to powerd: %s", error->message); + g_error_free (error); + return NULL; + } + + ret = getBrightnessParams(powerd_proxy, &(params->dim), &(params->min), + &(params->max), &(params->dflt), &(params->ab_supported)); + + if (! ret) + { + g_debug ("can't get brightness parameters from powerd"); + g_object_unref (powerd_proxy); + return NULL; + } + + g_clear_object (&powerd_proxy); + + GDBusProxy* uscreen_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "com.canonical.Unity.Screen", + "/com/canonical/Unity/Screen", + "com.canonical.Unity.Screen", + NULL, + &error); + + if (error != NULL) + { + g_debug ("could not connect to unity screen: %s", error->message); + g_error_free (error); + return NULL; + } + + return uscreen_proxy; +} + + +static gboolean +getBrightnessParams(GDBusProxy* powerd_proxy, int *dim, int *min, int *max, int *dflt, gboolean *ab_supported) +{ + GVariant *ret = NULL; + GError *error = NULL; + + ret = g_dbus_proxy_call_sync(powerd_proxy, + "getBrightnessParams", + NULL, + G_DBUS_CALL_FLAGS_NONE, + 400, NULL, &error); // timeout: 400 ms + if (!ret) + { + if (error != NULL) + { + if (!g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) + { + g_warning("getBrightnessParams from powerd failed: %s", error->message); + } + g_error_free(error); + } + return FALSE; + } + + g_variant_get(ret, "((iiiib))", dim, min, max, dflt, ab_supported); + g_variant_unref(ret); + return TRUE; +} + +static gboolean setUserBrightness(GDBusProxy* uscreen_proxy, GCancellable *gcancel, int brightness) +{ + GVariant *ret = NULL; + GError *error = NULL; + + ret = g_dbus_proxy_call_sync(uscreen_proxy, + "setUserBrightness", + g_variant_new("(i)", brightness), + G_DBUS_CALL_FLAGS_NONE, + -1, gcancel, &error); + if (!ret) { + g_warning("setUserBrightness via powerd failed: %s", error->message); + g_error_free(error); + return FALSE; + } else { + g_variant_unref(ret); + return TRUE; + } +} + +struct _IbBrightnessUScreenControl +{ + GDBusProxy *uscreen_proxy; + GCancellable *gcancel; + + int dim; + int min; + int max; + int dflt; // defalut value + gboolean ab_supported; + + int current; +}; + +IbBrightnessUscreenControl* +ib_brightness_uscreen_control_new (GDBusProxy* uscreen_proxy, brightness_params_t params) +{ + IbBrightnessUscreenControl *control; + + control = g_new0 (IbBrightnessUscreenControl, 1); + control->uscreen_proxy = uscreen_proxy; + control->gcancel = g_cancellable_new(); + + control->dim = params.dim; + control->min = params.min; + control->max = params.max; + control->dflt = params.dflt; + control->ab_supported = params.ab_supported; + + // XXX: set the brightness value is the only way to sync the brightness value with + // unity.screen, and we should set the user prefered / last set brightness value upon startup. + // Before we have code to store last set brightness value or other mechanism, we set + // it to default brightness that powerd proposed. + ib_brightness_uscreen_control_set_value(control, control->dflt); + + return control; +} + +void +ib_brightness_uscreen_control_set_value (IbBrightnessUscreenControl* self, gint value) +{ + gboolean ret; + + value = CLAMP(value, self->min, self->max); + ret = setUserBrightness(self->uscreen_proxy, self->gcancel, value); + if (ret) + { + self->current = value; + } +} + +gint +ib_brightness_uscreen_control_get_value (IbBrightnessUscreenControl* self) +{ + return self->current; +} + +gint +ib_brightness_uscreen_control_get_max_value (IbBrightnessUscreenControl* self) +{ + return self->max; +} + +void +ib_brightness_uscreen_control_free (IbBrightnessUscreenControl *self) +{ + g_cancellable_cancel (self->gcancel); + g_object_unref (self->gcancel); + g_object_unref (self->uscreen_proxy); + g_free (self); +} + diff --git a/src/ib-brightness-uscreen-control.h b/src/ib-brightness-uscreen-control.h new file mode 100644 index 0000000..3d026a9 --- /dev/null +++ b/src/ib-brightness-uscreen-control.h @@ -0,0 +1,43 @@ +/* + * 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: + * Y.C Cheng + */ + +#ifndef __IB_BRIGHTNESS_USCREEN_CONTROL_H__ +#define __IB_BRIGHTNESS_USCREEN_CONTROL_H__ + +#include + +typedef struct { + int dim; + int min; + int max; + int dflt; + gboolean ab_supported; +} brightness_params_t; + +GDBusProxy* uscreen_get_proxy(brightness_params_t *); + +typedef struct _IbBrightnessUScreenControl IbBrightnessUscreenControl; + +IbBrightnessUscreenControl* ib_brightness_uscreen_control_new (GDBusProxy* uscreen_proxy, brightness_params_t params); +void ib_brightness_uscreen_control_set_value (IbBrightnessUscreenControl* self, gint value); +gint ib_brightness_uscreen_control_get_value (IbBrightnessUscreenControl* self); +gint ib_brightness_uscreen_control_get_max_value (IbBrightnessUscreenControl* self); +void ib_brightness_uscreen_control_free (IbBrightnessUscreenControl *self); + +#endif diff --git a/src/service.c b/src/service.c index 46ad802..6438c9a 100644 --- a/src/service.c +++ b/src/service.c @@ -27,7 +27,7 @@ #include "device.h" #include "device-provider.h" #include "ib-brightness-control.h" -#include "ib-brightness-powerd-control.h" +#include "ib-brightness-uscreen-control.h" #include "service.h" #define BUS_NAME "com.canonical.indicator.power" @@ -105,7 +105,7 @@ struct _IndicatorPowerServicePrivate GSettings * settings; IbBrightnessControl * brightness_control; - IbBrightnessPowerdControl * brightness_powerd_control; + IbBrightnessUscreenControl * brightness_uscreen_control; guint own_id; guint actions_export_id; @@ -467,9 +467,9 @@ get_brightness_range (IndicatorPowerService * self, gint * low, gint * high) { max = ib_brightness_control_get_max_value (self->priv->brightness_control); } - else if (p->brightness_powerd_control) + else if (p->brightness_uscreen_control) { - max = ib_brightness_powerd_control_get_max_value (self->priv->brightness_powerd_control); + max = ib_brightness_uscreen_control_get_max_value (self->priv->brightness_uscreen_control); } *low = max * 0.05; /* 5% minimum -- don't let the screen go completely dark */ *high = max; @@ -500,9 +500,9 @@ action_state_for_brightness (IndicatorPowerService * self) { brightness = ib_brightness_control_get_value (p->brightness_control); } - else if (p->brightness_powerd_control) + else if (p->brightness_uscreen_control) { - brightness = ib_brightness_powerd_control_get_value (p->brightness_powerd_control); + brightness = ib_brightness_uscreen_control_get_value (p->brightness_uscreen_control); } return g_variant_new_double (brightness_to_percentage (self, brightness)); } @@ -527,9 +527,9 @@ on_brightness_change_requested (GSimpleAction * action G_GNUC_UNUSED, { ib_brightness_control_set_value (self->priv->brightness_control, brightness); } - else if (self->priv->brightness_powerd_control) + else if (self->priv->brightness_uscreen_control) { - ib_brightness_powerd_control_set_value (self->priv->brightness_powerd_control, brightness); + ib_brightness_uscreen_control_set_value (self->priv->brightness_uscreen_control, brightness); } update_brightness_action_state (self); @@ -1024,7 +1024,7 @@ my_dispose (GObject * o) // g_clear_pointer has NULL check inside. g_clear_pointer (&p->brightness_control, ib_brightness_control_free); - g_clear_pointer (&p->brightness_powerd_control, ib_brightness_powerd_control_free); + g_clear_pointer (&p->brightness_uscreen_control, ib_brightness_uscreen_control_free); indicator_power_service_set_device_provider (self, NULL); @@ -1038,8 +1038,8 @@ my_dispose (GObject * o) static void indicator_power_service_init (IndicatorPowerService * self) { - GDBusProxy *powerd_proxy; - brightness_params_t powerd_brightness_params; + GDBusProxy *uscreen_proxy; + brightness_params_t brightness_params; priv_t * p = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_TYPE_POWER_SERVICE, IndicatorPowerServicePrivate); @@ -1049,10 +1049,10 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); - powerd_proxy = powerd_get_proxy(&powerd_brightness_params); - if (powerd_proxy != NULL) + uscreen_proxy = uscreen_get_proxy(&brightness_params); + if (uscreen_proxy != NULL) { - p->brightness_powerd_control = ib_brightness_powerd_control_new(powerd_proxy, powerd_brightness_params); + p->brightness_uscreen_control = ib_brightness_uscreen_control_new(uscreen_proxy, brightness_params); } else { -- cgit v1.2.3 From cd9a40f956e09e7985cac3ea68786f738d53fb96 Mon Sep 17 00:00:00 2001 From: Alberto Aguirre Date: Thu, 19 Jun 2014 10:23:42 -0500 Subject: Remove powerd reference in message --- src/ib-brightness-uscreen-control.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ib-brightness-uscreen-control.c b/src/ib-brightness-uscreen-control.c index 4f8cd3e..ad2c155 100644 --- a/src/ib-brightness-uscreen-control.c +++ b/src/ib-brightness-uscreen-control.c @@ -119,7 +119,7 @@ static gboolean setUserBrightness(GDBusProxy* uscreen_proxy, GCancellable *gcanc G_DBUS_CALL_FLAGS_NONE, -1, gcancel, &error); if (!ret) { - g_warning("setUserBrightness via powerd failed: %s", error->message); + g_warning("setUserBrightness via unity.screen failed: %s", error->message); g_error_free(error); return FALSE; } else { -- cgit v1.2.3 From 3f29c1a35113bfd2461dca76235f1812c8dfd6ef Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 13 Jul 2014 23:33:16 -0500 Subject: fix some compiler warnings generated by clang static analyzer --- src/device-provider-upower.c | 10 ++++------ src/device-provider.c | 2 +- src/device.c | 18 ++++++++---------- src/ib-brightness-control.c | 6 +++--- src/main.c | 2 -- src/service.c | 33 +++++++++------------------------ 6 files changed, 25 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/device-provider-upower.c b/src/device-provider-upower.c index 7c12beb..400a060 100644 --- a/src/device-provider-upower.c +++ b/src/device-provider-upower.c @@ -17,8 +17,6 @@ * with this program. If not, see . */ -#include "config.h" - #include "dbus-upower.h" #include "device.h" #include "device-provider.h" @@ -60,7 +58,7 @@ G_DEFINE_TYPE_WITH_CODE ( indicator_power_device_provider_upower, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (INDICATOR_TYPE_POWER_DEVICE_PROVIDER, - indicator_power_device_provider_interface_init)); + indicator_power_device_provider_interface_init)) /*** **** UPOWER DBUS @@ -102,7 +100,7 @@ on_device_properties_ready (GObject * o, GAsyncResult * res, gpointer gdata) gdouble percentage = 0; gint64 time_to_empty = 0; gint64 time_to_full = 0; - time_t time; + gint64 time; IndicatorPowerDevice * device; IndicatorPowerDeviceProviderUPowerPriv * p = data->self->priv; GVariant * dict = g_variant_get_child_value (response, 0); @@ -120,7 +118,7 @@ on_device_properties_ready (GObject * o, GAsyncResult * res, gpointer gdata) INDICATOR_POWER_DEVICE_STATE, (gint)state, INDICATOR_POWER_DEVICE_OBJECT_PATH, data->path, INDICATOR_POWER_DEVICE_PERCENTAGE, percentage, - INDICATOR_POWER_DEVICE_TIME, (guint64)time, + INDICATOR_POWER_DEVICE_TIME, time, NULL); } else @@ -129,7 +127,7 @@ on_device_properties_ready (GObject * o, GAsyncResult * res, gpointer gdata) kind, percentage, state, - time); + (time_t)time); g_hash_table_insert (p->devices, g_strdup (data->path), diff --git a/src/device-provider.c b/src/device-provider.c index 81a8eec..46fcfad 100644 --- a/src/device-provider.c +++ b/src/device-provider.c @@ -29,7 +29,7 @@ static guint signals[SIGNAL_LAST] = { 0 }; G_DEFINE_INTERFACE (IndicatorPowerDeviceProvider, indicator_power_device_provider, - 0); + 0) static void indicator_power_device_provider_default_init (IndicatorPowerDeviceProviderInterface * klass) diff --git a/src/device.c b/src/device.c index 8780d72..f37aa7d 100644 --- a/src/device.c +++ b/src/device.c @@ -44,8 +44,6 @@ struct _IndicatorPowerDevicePrivate GTimer * inestimable; }; -#define INDICATOR_POWER_DEVICE_GET_PRIVATE(o) (INDICATOR_POWER_DEVICE(o)->priv) - /* Properties */ /* Enum for the properties so that they can be quickly found and looked up. */ enum { @@ -69,7 +67,7 @@ static void set_property (GObject*, guint prop_id, const GValue*, GParamSpec* ); static void get_property (GObject*, guint prop_id, GValue*, GParamSpec* ); /* LCOV_EXCL_START */ -G_DEFINE_TYPE (IndicatorPowerDevice, indicator_power_device, G_TYPE_OBJECT); +G_DEFINE_TYPE (IndicatorPowerDevice, indicator_power_device, G_TYPE_OBJECT) /* LCOV_EXCL_STOP */ static void @@ -189,7 +187,7 @@ get_property (GObject * o, guint prop_id, GValue * value, GParamSpec * pspec) break; case PROP_TIME: - g_value_set_uint64 (value, priv->time); + g_value_set_uint64 (value, (guint64)priv->time); break; default: @@ -207,11 +205,11 @@ set_property (GObject * o, guint prop_id, const GValue * value, GParamSpec * psp switch (prop_id) { case PROP_KIND: - p->kind = g_value_get_int (value); + p->kind = (UpDeviceKind) g_value_get_int (value); break; case PROP_STATE: - p->state = g_value_get_int (value); + p->state = (UpDeviceState) g_value_get_int (value); break; case PROP_OBJECT_PATH: @@ -224,7 +222,7 @@ set_property (GObject * o, guint prop_id, const GValue * value, GParamSpec * psp break; case PROP_TIME: - p->time = g_value_get_uint64(value); + p->time = (time_t) g_value_get_uint64(value); break; default: @@ -627,8 +625,8 @@ get_accessible_time_remaining (const IndicatorPowerDevice * device) if (p->time && ((p->state == UP_DEVICE_STATE_CHARGING) || (p->state == UP_DEVICE_STATE_DISCHARGING))) { - int minutes = p->time / 60; - const int hours = minutes / 60; + guint minutes = (guint)p->time / 60u; + const guint hours = minutes / 60u; minutes %= 60; if (p->state == UP_DEVICE_STATE_CHARGING) @@ -889,5 +887,5 @@ indicator_power_device_new_from_variant (GVariant * v) kind, percentage, state, - time); + (time_t)time); } diff --git a/src/ib-brightness-control.c b/src/ib-brightness-control.c index 4fb6bc5..67da10c 100644 --- a/src/ib-brightness-control.c +++ b/src/ib-brightness-control.c @@ -76,7 +76,7 @@ ib_brightness_control_set_value (IbBrightnessControl* self, gint value) gint fd; gchar *filename; gchar *svalue; - gint length; + size_t length; gint err; if (self->path == NULL) @@ -95,7 +95,7 @@ ib_brightness_control_set_value (IbBrightnessControl* self, gint value) err = errno; errno = 0; - if (write (fd, svalue, length) != length) { + if (write (fd, svalue, length) != (ssize_t)length) { g_warning ("Fail to write brightness information: %s", g_strerror(errno)); } errno = err; @@ -105,7 +105,7 @@ ib_brightness_control_set_value (IbBrightnessControl* self, gint value) g_free (filename); } -gint +static gint ib_brightness_control_get_value_from_file (IbBrightnessControl *self, const gchar *file) { GError *error; diff --git a/src/main.c b/src/main.c index ef615dc..7363284 100644 --- a/src/main.c +++ b/src/main.c @@ -17,8 +17,6 @@ * with this program. If not, see . */ -#include "config.h" - #include #include /* exit() */ diff --git a/src/service.c b/src/service.c index 6438c9a..7478d0f 100644 --- a/src/service.c +++ b/src/service.c @@ -18,8 +18,6 @@ * with this program. If not, see . */ -#include "config.h" - #include #include #include @@ -471,7 +469,7 @@ get_brightness_range (IndicatorPowerService * self, gint * low, gint * high) { max = ib_brightness_uscreen_control_get_max_value (self->priv->brightness_uscreen_control); } - *low = max * 0.05; /* 5% minimum -- don't let the screen go completely dark */ + *low = (gint)(max * 0.05); /* 5% minimum -- don't let the screen go completely dark */ *high = max; } @@ -621,18 +619,6 @@ rebuild_header_now (IndicatorPowerService * self) rebuild_now (self, SECTION_HEADER); } -static inline void -rebuild_devices_section_now (IndicatorPowerService * self) -{ - rebuild_now (self, SECTION_DEVICES); -} - -static inline void -rebuild_settings_section_now (IndicatorPowerService * self) -{ - rebuild_now (self, SECTION_SETTINGS); -} - static void create_menu (IndicatorPowerService * self, int profile) { @@ -938,7 +924,7 @@ on_devices_changed (IndicatorPowerService * self) if (p->primary_device == NULL) battery_level = 0; else - battery_level = (int)(indicator_power_device_get_percentage (p->primary_device) + 0.5); + battery_level = (guint32)(indicator_power_device_get_percentage (p->primary_device) + 0.5); g_simple_action_set_state (p->battery_level_action, g_variant_new_uint32 (battery_level)); rebuild_now (self, SECTION_HEADER | SECTION_DEVICES); @@ -1131,9 +1117,8 @@ indicator_power_service_set_device_provider (IndicatorPowerService * self, if (p->device_provider != NULL) { - g_signal_handlers_disconnect_by_func (p->device_provider, - G_CALLBACK(on_devices_changed), - self); + g_signal_handlers_disconnect_by_data (p->device_provider, self); + g_clear_object (&p->device_provider); g_clear_object (&p->primary_device); @@ -1177,13 +1162,13 @@ create_totalled_battery_device (const GList * devices) for (l=devices; l!=NULL; l=l->next) { - const IndicatorPowerDevice * device = INDICATOR_POWER_DEVICE(l->data); + const IndicatorPowerDevice * walk = INDICATOR_POWER_DEVICE(l->data); - if (indicator_power_device_get_kind(device) == UP_DEVICE_KIND_BATTERY) + if (indicator_power_device_get_kind(walk) == UP_DEVICE_KIND_BATTERY) { - const double percent = indicator_power_device_get_percentage (device); - const time_t t = indicator_power_device_get_time (device); - const UpDeviceState state = indicator_power_device_get_state (device); + const double percent = indicator_power_device_get_percentage (walk); + const time_t t = indicator_power_device_get_time (walk); + const UpDeviceState state = indicator_power_device_get_state (walk); ++n_batteries; -- cgit v1.2.3 From 35a8b1720631a6b700bf9a234d0444c3457ce197 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 13 Jul 2014 23:43:41 -0500 Subject: replace autoconf/automake with cmake --- src/CMakeLists.txt | 45 ++++++++++++++++++++++++ src/Makefile.am | 83 -------------------------------------------- src/device-provider-upower.h | 2 ++ 3 files changed, 47 insertions(+), 83 deletions(-) create mode 100644 src/CMakeLists.txt delete mode 100644 src/Makefile.am (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..a39b945 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,45 @@ +set (SERVICE_LIB "indicatorpowerservice") +set (SERVICE_EXEC "indicator-power-service") + +add_definitions(-DG_LOG_DOMAIN="Indicator-Power") + +# handwritten sources +set(SERVICE_MANUAL_SOURCES + device-provider-upower.c + ib-brightness-control.c + ib-brightness-uscreen-control.c + device-provider.c + device.c + service.c) + +# generated sources +include(GdbusCodegen) +set(SERVICE_GENERATED_SOURCES) +add_gdbus_codegen_with_namespace(SERVICE_GENERATED_SOURCES dbus-upower + org.freedesktop + Dbus + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.UPower.xml) +# add the bin dir to our include path so the code can find the generated header files +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + + +# add warnings/coverage info on handwritten files +# but not the autogenerated ones... +set(C_WARNING_ARGS "${C_WARNING_ARGS} -Wno-bad-function-cast") # g_clear_object() +set(C_WARNING_ARGS "${C_WARNING_ARGS} -Wno-disabled-macro-expansion") # G_DEFINE_TYPE +set(C_WARNING_ARGS "${C_WARNING_ARGS} -Wno-assign-enum") # GParamFlags +set(C_WARNING_ARGS "${C_WARNING_ARGS} -Wno-switch-enum") +set_source_files_properties(${SERVICE_MANUAL_SOURCES} + PROPERTIES COMPILE_FLAGS "${C_WARNING_ARGS} ${GCOV_FLAGS} -g -std=c99") + +# the service library for tests to link against (basically, everything except main()) +add_library(${SERVICE_LIB} STATIC ${SERVICE_MANUAL_SOURCES} ${SERVICE_GENERATED_SOURCES}) +include_directories(${CMAKE_SOURCE_DIR}) +link_directories(${SERVICE_DEPS_LIBRARY_DIRS}) + +# the executable: lib + main() +add_executable (${SERVICE_EXEC} main.c) +set_source_files_properties(${SERVICE_SOURCES} main.c PROPERTIES COMPILE_FLAGS "${C_WARNING_ARGS} -g -std=c99") +target_link_libraries (${SERVICE_EXEC} ${SERVICE_LIB} ${SERVICE_DEPS_LIBRARIES} ${GCOV_LIBS}) +install (TARGETS ${SERVICE_EXEC} RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}) + diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index 3f71b60..0000000 --- a/src/Makefile.am +++ /dev/null @@ -1,83 +0,0 @@ -BUILT_SOURCES = -EXTRA_DIST = -CLEANFILES = - -SHARED_CFLAGS = \ - -Wall -Wextra -Werror \ - $(SERVICE_DEPS_CFLAGS) \ - -DG_LOG_DOMAIN=\"Indicator-Power\" - -### -### - -upower_dbus_sources = \ - dbus-upower.c \ - dbus-upower.h - -$(upower_dbus_sources): org.freedesktop.UPower.xml - $(AM_V_GEN) gdbus-codegen \ - --c-namespace Dbus \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-upower \ - $^ - -BUILT_SOURCES += $(upower_dbus_sources) -CLEANFILES += $(upower_dbus_sources) -EXTRA_DIST += org.freedesktop.UPower.xml - -### -### -### - -noinst_LIBRARIES = libindicatorpower-upower.a libindicatorpower-service.a - -libindicatorpower_upower_a_SOURCES = \ - $(upower_dbus_sources) \ - device-provider-upower.c \ - device-provider-upower.h - -libindicatorpower_upower_a_CFLAGS = \ - $(SHARED_CFLAGS) \ - -Wno-unused-parameter \ - $(COVERAGE_CFLAGS) - -libindciatorpower_upower_a_LDFLAGS = $(COVERAGE_LDFLAGS) - -libindicatorpower_service_a_SOURCES = \ - ib-brightness-control.c \ - ib-brightness-control.h \ - ib-brightness-uscreen-control.c \ - ib-brightness-uscreen-control.h \ - device-provider.c \ - device-provider.h \ - device.c \ - device.h \ - service.c \ - service.h - -libindicatorpower_service_a_CFLAGS = \ - $(SHARED_CFLAGS) \ - -Wno-missing-field-initializers \ - $(COVERAGE_CFLAGS) - -libindicatorpower_service_a_LDFLAGS = $(COVERAGE_LDFLAGS) - -### -### -### - -pkglibexec_PROGRAMS = indicator-power-service - -indicator_power_service_SOURCES = main.c - -indicator_power_service_CFLAGS = \ - $(SHARED_CFLAGS) \ - $(COVERAGE_CFLAGS) - -indicator_power_service_LDADD = \ - libindicatorpower-upower.a \ - libindicatorpower-service.a \ - $(SERVICE_DEPS_LIBS) - -indicator_power_service_LDFLAGS = \ - $(COVERAGE_LDFLAGS) diff --git a/src/device-provider-upower.h b/src/device-provider-upower.h index 7bdd5d5..7bfecd9 100644 --- a/src/device-provider-upower.h +++ b/src/device-provider-upower.h @@ -65,6 +65,8 @@ struct _IndicatorPowerDeviceProviderUPowerClass GObjectClass parent_class; }; +GType indicator_power_device_provider_upower_get_type (void); + IndicatorPowerDeviceProvider * indicator_power_device_provider_upower_new (void); G_END_DECLS -- cgit v1.2.3 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 From b04239b60c7684a0ee0f5dccbeda0d00540c0ee9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 29 Jul 2014 09:49:19 -0500 Subject: show the icon that most closely matches the battery charge percentage. --- src/device.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src') diff --git a/src/device.c b/src/device.c index f37aa7d..eff76d1 100644 --- a/src/device.c +++ b/src/device.c @@ -353,13 +353,6 @@ device_kind_to_string (UpDeviceKind kind) indicator_power_device_get_icon_names: @device: #IndicatorPowerDevice from which to generate the icon names - This function's logic differs from GSD's power plugin in some ways: - - 1. For discharging batteries, we decide whether or not to use the 'caution' - icon based on whether or not we have <= 30 minutes remaining, rather than - looking at the battery's percentage left. - - See also indicator_power_device_get_gicon(). Return value: (array zero-terminated=1) (transfer full): @@ -423,13 +416,6 @@ indicator_power_device_get_icon_names (const IndicatorPowerDevice * device) case UP_DEVICE_STATE_PENDING_CHARGE: case UP_DEVICE_STATE_DISCHARGING: case UP_DEVICE_STATE_PENDING_DISCHARGE: - /* Don't show the caution/red icons unless we have <=30 min left. - - Themes use the caution color when the percentage is 0% or 20%, - so if we have >30 min left, use 30% as the icon's percentage floor */ - if (indicator_power_device_get_time (device) > (30*60)) - percentage = MAX(percentage, 30); - suffix_str = get_device_icon_suffix (percentage); index_str = get_device_icon_index (percentage); g_ptr_array_add (names, g_strdup_printf ("%s-%s", kind_str, index_str)); -- cgit v1.2.3