Back to index

indicator-power  12.10.0
Classes | Defines | Enumerations | Functions
indicator-power.c File Reference
#include <glib-object.h>
#include <glib/gi18n-lib.h>
#include <gio/gio.h>
#include "dbus-listener.h"
#include "device.h"
#include "indicator-power.h"

Go to the source code of this file.

Classes

struct  _IndicatorPowerPrivate

Defines

#define ICON_POLICY_KEY   "icon-policy"
#define DEFAULT_ICON   "gpm-battery-missing"

Enumerations

enum  { POWER_INDICATOR_ICON_POLICY_PRESENT, POWER_INDICATOR_ICON_POLICY_CHARGE, POWER_INDICATOR_ICON_POLICY_NEVER }

Functions

static INDICATOR_SET_VERSION void indicator_power_dispose (GObject *object)
static void indicator_power_finalize (GObject *object)
static GtkLabel * get_label (IndicatorObject *io)
static GtkImage * get_image (IndicatorObject *io)
static GtkMenu * get_menu (IndicatorObject *io)
static const gchar * get_accessible_desc (IndicatorObject *io)
static const gchar * get_name_hint (IndicatorObject *io)
static void update_visibility (IndicatorPower *self)
static gboolean should_be_visible (IndicatorPower *self)
static void on_entry_added (IndicatorObject *io, IndicatorObjectEntry *entry, gpointer user_data)
 G_DEFINE_TYPE (IndicatorPower, indicator_power, INDICATOR_OBJECT_TYPE)
static void indicator_power_class_init (IndicatorPowerClass *klass)
static void indicator_power_init (IndicatorPower *self)
static void dispose_devices (IndicatorPower *self)
static void spawn_command_line_async (const char *command)
static void option_toggled_cb (GtkCheckMenuItem *item, IndicatorPower *self)
static void refresh_entry_accessible_desc (IndicatorPower *self, IndicatorObjectEntry *entry)
static void set_accessible_desc (IndicatorPower *self, const gchar *desc)
static gboolean menu_add_device (GtkMenu *menu, const IndicatorPowerDevice *device)
static gsize menu_add_devices (GtkMenu *menu, GSList *devices)
static gboolean get_greeter_mode (void)
static void build_menu (IndicatorPower *self)
static IndicatorPowerDevice * get_primary_device (GSList *devices)
static void put_primary_device (IndicatorPower *self, IndicatorPowerDevice *device)
void indicator_power_set_devices (IndicatorPower *self, GSList *devices)
static void count_batteries (GSList *devices, int *total, int *inuse)

Class Documentation

struct _IndicatorPowerPrivate

Definition at line 45 of file indicator-power.c.

Class Members
gchar * accessible_desc
IndicatorPowerDbusListener * dbus_listener
IndicatorPowerDevice * device
GSList * devices
GtkLabel * label
GtkMenu * menu
GSettings * settings
GtkImage * status_image

Define Documentation

#define DEFAULT_ICON   "gpm-battery-missing"

Definition at line 37 of file indicator-power.c.

#define ICON_POLICY_KEY   "icon-policy"

Definition at line 35 of file indicator-power.c.


Enumeration Type Documentation

anonymous enum
Enumerator:
POWER_INDICATOR_ICON_POLICY_PRESENT 
POWER_INDICATOR_ICON_POLICY_CHARGE 
POWER_INDICATOR_ICON_POLICY_NEVER 

Definition at line 39 of file indicator-power.c.


Function Documentation

static void build_menu ( IndicatorPower *  self) [static]

Definition at line 310 of file indicator-power.c.

{
  GtkWidget *item;
  GtkWidget *image;
  GList *children;
  gsize n_devices = 0;
  IndicatorPowerPrivate * priv = self->priv;

  /* remove the existing menuitems */
  children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
  g_list_foreach (children, (GFunc) gtk_widget_destroy, NULL);
  g_list_free (children);

  /* devices */
  n_devices = menu_add_devices (priv->menu, priv->devices);

  if (!get_greeter_mode ()) {
    /* only do the separator if we have at least one device */
    if (n_devices != 0)
      {
        item = gtk_separator_menu_item_new ();
        gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);
      }

    /* options */
    item = gtk_check_menu_item_new_with_label (_("Show Time in Menu Bar"));
    g_signal_connect (item, "toggled", G_CALLBACK(option_toggled_cb), self);
    g_settings_bind (priv->settings, "show-time", item, "active", G_SETTINGS_BIND_DEFAULT);
    gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);

    /* preferences */
    item = gtk_image_menu_item_new_with_label (_("Power Settingsā€¦"));
    image = gtk_image_new_from_icon_name (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU);
    gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
    g_signal_connect_swapped (G_OBJECT (item), "activate",
                              G_CALLBACK (spawn_command_line_async), "gnome-control-center power");
    gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);
  }

  /* show the menu */
  gtk_widget_show_all (GTK_WIDGET (priv->menu));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void count_batteries ( GSList *  devices,
int *  total,
int *  inuse 
) [static]

Definition at line 545 of file indicator-power.c.

{
  GSList * l;

  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)
        {
          ++*total;

          const UpDeviceState state = indicator_power_device_get_state (device);
          if ((state == UP_DEVICE_STATE_CHARGING) || (state == UP_DEVICE_STATE_DISCHARGING))
            ++*inuse;
        }
    }

    g_debug("count_batteries found %d batteries (%d are charging/discharging)", *total, *inuse);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void dispose_devices ( IndicatorPower *  self) [static]

Definition at line 137 of file indicator-power.c.

{
  IndicatorPowerPrivate * priv = self->priv;

  g_clear_object (&priv->device);
  g_slist_free_full (priv->devices, g_object_unref);
  priv->devices = NULL;
}

Here is the caller graph for this function:

G_DEFINE_TYPE ( IndicatorPower  ,
indicator_power  ,
INDICATOR_OBJECT_TYPE   
)
static const gchar * get_accessible_desc ( IndicatorObject *  io) [static]

Definition at line 527 of file indicator-power.c.

{
  IndicatorPower *self = INDICATOR_POWER (io);

  return self->priv->accessible_desc;
}

Here is the caller graph for this function:

static gboolean get_greeter_mode ( void  ) [static]

Definition at line 302 of file indicator-power.c.

{
  const gchar *var;
  var = g_getenv("INDICATOR_GREETER_MODE");
  return (g_strcmp0(var, "1") == 0);
}

Here is the caller graph for this function:

static GtkImage * get_image ( IndicatorObject *  io) [static]

Definition at line 499 of file indicator-power.c.

{
  GIcon *gicon;
  IndicatorPower *self = INDICATOR_POWER (io);
  IndicatorPowerPrivate * priv = self->priv;

  if (priv->status_image == NULL)
  {
    /* Will create the status icon if it doesn't exist already */
    gicon = g_themed_icon_new (DEFAULT_ICON);
    priv->status_image = GTK_IMAGE (gtk_image_new_from_gicon (gicon,
                                                              GTK_ICON_SIZE_LARGE_TOOLBAR));
  }

  return priv->status_image;
}

Here is the caller graph for this function:

static GtkLabel * get_label ( IndicatorObject *  io) [static]

Definition at line 483 of file indicator-power.c.

{
  IndicatorPower *self = INDICATOR_POWER (io);
  IndicatorPowerPrivate * priv = self->priv;

  if (priv->label == NULL)
    {
      /* Create the label if it doesn't exist already */
      priv->label = GTK_LABEL (gtk_label_new (""));
      gtk_widget_set_visible (GTK_WIDGET (priv->label), FALSE);
    }

  return priv->label;
}

Here is the caller graph for this function:

static GtkMenu * get_menu ( IndicatorObject *  io) [static]

Definition at line 517 of file indicator-power.c.

{
  IndicatorPower *self = INDICATOR_POWER (io);

  build_menu (self);

  return GTK_MENU (self->priv->menu);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const gchar * get_name_hint ( IndicatorObject *  io) [static]

Definition at line 535 of file indicator-power.c.

{
  return PACKAGE_NAME;
}

Here is the caller graph for this function:

static IndicatorPowerDevice* get_primary_device ( GSList *  devices) [static]

Definition at line 354 of file indicator-power.c.

{
  IndicatorPowerDevice * primary_device = NULL;
  IndicatorPowerDevice * primary_device_charging = NULL;
  IndicatorPowerDevice * primary_device_discharging = NULL;
  gboolean charging = FALSE;
  gboolean discharging = FALSE;
  guint64 min_discharging_time = G_MAXUINT64;
  guint64 max_charging_time = 0;
  GSList * l;

  for (l=devices; l!=NULL; l=l->next)
    {
      IndicatorPowerDevice * device = INDICATOR_POWER_DEVICE(l->data);
      const UpDeviceKind kind = indicator_power_device_get_kind (device);
      const UpDeviceState state = indicator_power_device_get_state (device);
      const gdouble percentage  = indicator_power_device_get_percentage (device);
      const time_t time = indicator_power_device_get_time (device);

      /* Try to fix the case when we get a empty battery bay as a real battery */
      if (state == UP_DEVICE_STATE_UNKNOWN &&
          percentage == 0)
        continue;

      /* not battery */
      if (kind != UP_DEVICE_KIND_BATTERY)
        continue;

      if (state == UP_DEVICE_STATE_DISCHARGING)
        {
          discharging = TRUE;
          if (time < min_discharging_time)
            {
              min_discharging_time = time;
              primary_device_discharging = device;
            }
        }
      else if (state == UP_DEVICE_STATE_CHARGING)
        {
          charging = TRUE;
          if (time == 0) /* Battery broken */
            {
              primary_device_charging = device;
            }
          if (time > max_charging_time)
            {
              max_charging_time = time;
              primary_device_charging = device;
            }
        }
      else
        {
          primary_device = device;
        }
    }

  if (discharging)
    {
      primary_device = primary_device_discharging;
    }
  else if (charging)
    {
      primary_device = primary_device_charging;
    }

  if (primary_device != NULL)
    g_object_ref (primary_device);

  return primary_device;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void indicator_power_class_init ( IndicatorPowerClass *  klass) [static]

Definition at line 91 of file indicator-power.c.

{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  IndicatorObjectClass *io_class = INDICATOR_OBJECT_CLASS (klass);

  g_type_class_add_private (klass, sizeof (IndicatorPowerPrivate));

  object_class->dispose = indicator_power_dispose;
  object_class->finalize = indicator_power_finalize;

  io_class->get_label = get_label;
  io_class->get_image = get_image;
  io_class->get_menu = get_menu;
  io_class->get_accessible_desc = get_accessible_desc;
  io_class->get_name_hint = get_name_hint;
}

Here is the call graph for this function:

static void indicator_power_dispose ( GObject *  object) [static]

Definition at line 146 of file indicator-power.c.

{
  IndicatorPower *self = INDICATOR_POWER(object);
  IndicatorPowerPrivate * priv = self->priv;

  dispose_devices (self);

  g_clear_object (&priv->dbus_listener);
  g_clear_object (&priv->settings);

  G_OBJECT_CLASS (indicator_power_parent_class)->dispose (object);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void indicator_power_finalize ( GObject *  object) [static]

Definition at line 160 of file indicator-power.c.

{
  IndicatorPower *self = INDICATOR_POWER(object);
  IndicatorPowerPrivate * priv = self->priv;

  g_free (priv->accessible_desc);

  G_OBJECT_CLASS (indicator_power_parent_class)->finalize (object);
}

Here is the caller graph for this function:

static void indicator_power_init ( IndicatorPower *  self) [static]

Definition at line 109 of file indicator-power.c.

{
  IndicatorPowerPrivate * priv;

  priv = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_POWER_TYPE, IndicatorPowerPrivate);

  priv->menu = GTK_MENU(gtk_menu_new());

  priv->accessible_desc = NULL;

  priv->dbus_listener = g_object_new (INDICATOR_POWER_DBUS_LISTENER_TYPE, NULL);
  g_signal_connect_swapped (priv->dbus_listener, INDICATOR_POWER_DBUS_LISTENER_DEVICES_ENUMERATED,
                            G_CALLBACK(indicator_power_set_devices), self);

  priv->settings = g_settings_new ("com.canonical.indicator.power");
  g_signal_connect_swapped (priv->settings, "changed::" ICON_POLICY_KEY,
                            G_CALLBACK(update_visibility), self);
  g_object_set (G_OBJECT(self),
                INDICATOR_OBJECT_DEFAULT_VISIBILITY, FALSE,
                NULL);

  g_signal_connect (INDICATOR_OBJECT(self), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,
                    G_CALLBACK(on_entry_added), NULL);

  self->priv = priv;
}

Here is the call graph for this function:

void indicator_power_set_devices ( IndicatorPower *  self,
GSList *  devices 
)

Definition at line 449 of file indicator-power.c.

{
  /* LCOV_EXCL_START */
  g_return_if_fail (IS_INDICATOR_POWER(self));
  /* LCOV_EXCL_STOP */

  IndicatorPowerPrivate * priv = self->priv;

  /* update our devices & primary device */
  g_slist_foreach (devices, (GFunc)g_object_ref, NULL);
  dispose_devices (self);
  priv->devices = g_slist_copy (devices);
  priv->device = get_primary_device (priv->devices);

  /* and our menus/visibility from the new device list */
  if (priv->device != NULL)
      put_primary_device (self, priv->device);
  else
      g_message ("Couldn't find primary device");
  build_menu (self);
  update_visibility (self);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gboolean menu_add_device ( GtkMenu *  menu,
const IndicatorPowerDevice *  device 
) [static]

Definition at line 236 of file indicator-power.c.

{
  gboolean added = FALSE;
  const UpDeviceKind kind = indicator_power_device_get_kind (device);

  if (kind != UP_DEVICE_KIND_LINE_POWER)
  {
    GtkWidget *icon;
    GtkWidget *item;
    GtkWidget *details_label;
    GtkWidget *grid;
    GIcon *device_gicon;
    gchar *short_details = NULL;
    gchar *details = NULL;
    gchar *accessible_name = NULL;
    AtkObject *atk_object;

    /* Process the data */
    device_gicon = indicator_power_device_get_gicon (device);
    icon = gtk_image_new_from_gicon (device_gicon, GTK_ICON_SIZE_SMALL_TOOLBAR);
    g_clear_object (&device_gicon);

    indicator_power_device_get_time_details (device, &short_details, &details, &accessible_name);

    /* Create menu item */
    item = gtk_image_menu_item_new ();
    atk_object = gtk_widget_get_accessible(item);
    if (atk_object != NULL)
      atk_object_set_name (atk_object, accessible_name);

    grid = gtk_grid_new ();
    gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
    gtk_grid_attach (GTK_GRID (grid), icon, 0, 0, 1, 1);
    details_label = gtk_label_new (details);
    gtk_grid_attach_next_to (GTK_GRID (grid), details_label, icon, GTK_POS_RIGHT, 1, 1);
    gtk_container_add (GTK_CONTAINER (item), grid);
    gtk_widget_show (grid);

    gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
    added = TRUE;

    g_signal_connect_swapped (G_OBJECT (item), "activate",
                              G_CALLBACK (spawn_command_line_async), "gnome-power-statistics");

    g_free (short_details);
    g_free (details);
    g_free (accessible_name);
  }

  return added;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gsize menu_add_devices ( GtkMenu *  menu,
GSList *  devices 
) [static]

Definition at line 289 of file indicator-power.c.

{
  GSList * l;
  gsize n_added = 0;

  for (l=devices; l!=NULL; l=l->next)
    if (menu_add_device (menu, l->data))
      ++n_added;

  return n_added;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void on_entry_added ( IndicatorObject *  io,
IndicatorObjectEntry *  entry,
gpointer user_data  G_GNUC_UNUSED 
) [static]

Definition at line 205 of file indicator-power.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void option_toggled_cb ( GtkCheckMenuItem *  item,
IndicatorPower *  self 
) [static]

Definition at line 184 of file indicator-power.c.

{
  gtk_widget_set_visible (GTK_WIDGET (self->priv->label),
                          gtk_check_menu_item_get_active(item));
}

Here is the caller graph for this function:

static void put_primary_device ( IndicatorPower *  self,
IndicatorPowerDevice *  device 
) [static]

Definition at line 426 of file indicator-power.c.

{
  IndicatorPowerPrivate * priv = self->priv;

  /* set icon */
  GIcon * device_gicon = indicator_power_device_get_gicon (device);
  gtk_image_set_from_gicon (priv->status_image, device_gicon, GTK_ICON_SIZE_LARGE_TOOLBAR);
  g_clear_object (&device_gicon);
  gtk_widget_show (GTK_WIDGET (priv->status_image));

  /* get the description */
  gchar * short_details;
  gchar * details;
  gchar * accessible_name;
  indicator_power_device_get_time_details (device, &short_details, &details, &accessible_name);
  gtk_label_set_label (GTK_LABEL (priv->label), short_details);
  set_accessible_desc (self, accessible_name);
  g_free (accessible_name);
  g_free (details);
  g_free (short_details);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void refresh_entry_accessible_desc ( IndicatorPower *  self,
IndicatorObjectEntry *  entry 
) [static]

Definition at line 192 of file indicator-power.c.

{
  const char * newval = self->priv->accessible_desc;

  if (entry->accessible_desc != newval)
  {
    g_debug ("%s: setting entry %p accessible description to '%s'", G_STRFUNC, entry, newval);
    entry->accessible_desc = newval;
    g_signal_emit (self, INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, 0, entry);
  }
}

Here is the caller graph for this function:

static void set_accessible_desc ( IndicatorPower *  self,
const gchar *  desc 
) [static]

Definition at line 213 of file indicator-power.c.

{
  g_debug ("%s: setting accessible description to '%s'", G_STRFUNC, desc);

  if (desc && *desc)
  {
    /* update our copy of the string */
    char * oldval = self->priv->accessible_desc;
    self->priv->accessible_desc = g_strdup (desc);

    /* ensure that the entries are using self's accessible description */
    GList * l;
    GList * entries = indicator_object_get_entries(INDICATOR_OBJECT(self));
    for (l=entries; l!=NULL; l=l->next)
      refresh_entry_accessible_desc (self, l->data);

    /* cleanup */
    g_list_free (entries);
    g_free (oldval);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gboolean should_be_visible ( IndicatorPower *  self) [static]

Definition at line 567 of file indicator-power.c.

{
  gboolean visible = TRUE;
  IndicatorPowerPrivate * priv = self->priv;

  const int icon_policy = g_settings_get_enum (priv->settings, ICON_POLICY_KEY);

  g_debug ("icon_policy is: %d (present==0, charge==1, never==2)", icon_policy);

  if (icon_policy == POWER_INDICATOR_ICON_POLICY_NEVER)
    {
      visible = FALSE;
    }
    else
    {
      int batteries=0, inuse=0;
      count_batteries (priv->devices, &batteries, &inuse);

      if (icon_policy == POWER_INDICATOR_ICON_POLICY_PRESENT)
        {
          visible = batteries > 0;
        }
      else if (icon_policy == POWER_INDICATOR_ICON_POLICY_CHARGE)
        {
          visible = inuse > 0;
        }
    }

  g_debug ("should_be_visible: %s", visible?"yes":"no");
  return visible;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void spawn_command_line_async ( const char *  command) [static]

Definition at line 175 of file indicator-power.c.

{
  GError * err = NULL;
  if (!g_spawn_command_line_async (command, &err))
      g_warning ("Couldn't execute command \"%s\": %s", command, err->message);
  g_clear_error (&err);
}

Here is the caller graph for this function:

static void update_visibility ( IndicatorPower *  self) [static]

Definition at line 473 of file indicator-power.c.

{
  indicator_object_set_visible (INDICATOR_OBJECT (self),
                                should_be_visible (self));
}

Here is the call graph for this function:

Here is the caller graph for this function: