Skip to content
Snippets Groups Projects
power-manager-button.c 55.3 KiB
Newer Older
Eric Koegel's avatar
Eric Koegel committed
 * * Copyright (C) 2014 Eric Koegel <eric@xfce.org>
 * * Copyright (C) 2019 Kacper Piwiński
 *
 * Licensed under the GNU General Public License Version 2
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifdef HAVE_CONFIG_H
Gaël Bonithon's avatar
Gaël Bonithon committed
#include "config.h"
Gaël Bonithon's avatar
Gaël Bonithon committed
#include "power-manager-button.h"
#include "scalemenuitem.h"
Gaël Bonithon's avatar
Gaël Bonithon committed
#include "common/xfpm-brightness.h"
#include "common/xfpm-common.h"
#include "common/xfpm-config.h"
#include "common/xfpm-debug.h"
#include "common/xfpm-enum-glib.h"
Gaël Bonithon's avatar
Gaël Bonithon committed
#include "common/xfpm-icons.h"
#include "common/xfpm-power-common.h"

#ifdef XFPM_SYSTRAY
#include "src/xfpm-inhibit.h"
#endif
Gaël Bonithon's avatar
Gaël Bonithon committed
#include <libxfce4ui/libxfce4ui.h>
#include <libxfce4util/libxfce4util.h>
#include <upower.h>
#include <xfconf/xfconf.h>
Eric Koegel's avatar
Eric Koegel committed

#define SET_LEVEL_TIMEOUT (50)
struct PowerManagerButtonPrivate
#ifdef XFCE_PLUGIN
Simon Steinbeiss's avatar
Simon Steinbeiss committed
  XfcePanelPlugin *plugin;
Gaël Bonithon's avatar
Gaël Bonithon committed
  GDBusProxy *inhibit_proxy;
Gaël Bonithon's avatar
Gaël Bonithon committed
  XfpmInhibit *inhibit;
Gaël Bonithon's avatar
Gaël Bonithon committed
  XfconfChannel *channel;
Simon Steinbeiss's avatar
Simon Steinbeiss committed

Gaël Bonithon's avatar
Gaël Bonithon committed
  UpClient *upower;
Simon Steinbeiss's avatar
Simon Steinbeiss committed

  /* A list of BatteryDevices  */
Gaël Bonithon's avatar
Gaël Bonithon committed
  GList *devices;
Simon Steinbeiss's avatar
Simon Steinbeiss committed

  /* The left-click popup menu, if one is being displayed */
Gaël Bonithon's avatar
Gaël Bonithon committed
  GtkWidget *menu;
Simon Steinbeiss's avatar
Simon Steinbeiss committed

  /* The actual panel icon image */
Gaël Bonithon's avatar
Gaël Bonithon committed
  GtkWidget *panel_icon_image;
  GtkWidget *panel_presentation_mode;
  GtkWidget *panel_label;
  GtkWidget *hbox;
Simon Steinbeiss's avatar
Simon Steinbeiss committed
  /* Keep track of icon name to redisplay during size changes */
Gaël Bonithon's avatar
Gaël Bonithon committed
  gchar *panel_icon_name;
  gchar *panel_fallback_icon_name;
Simon Steinbeiss's avatar
Simon Steinbeiss committed
  /* Keep track of the last icon size for use during updates */
Gaël Bonithon's avatar
Gaël Bonithon committed
  gint panel_icon_width;
Simon Steinbeiss's avatar
Simon Steinbeiss committed
  /* Keep track of the tooltip */
Gaël Bonithon's avatar
Gaël Bonithon committed
  gchar *tooltip;
Simon Steinbeiss's avatar
Simon Steinbeiss committed

  /* Upower 0.99 has a display device that can be used for the
   * panel image and tooltip description */
Gaël Bonithon's avatar
Gaël Bonithon committed
  UpDevice *display_device;
Simon Steinbeiss's avatar
Simon Steinbeiss committed

Gaël Bonithon's avatar
Gaël Bonithon committed
  XfpmBrightness *brightness;
Simon Steinbeiss's avatar
Simon Steinbeiss committed

  /* display brightness slider widget */
Gaël Bonithon's avatar
Gaël Bonithon committed
  GtkWidget *range;
Simon Steinbeiss's avatar
Simon Steinbeiss committed

  /* filter range value changed events for snappier UI feedback */
Gaël Bonithon's avatar
Gaël Bonithon committed
  guint set_level_timeout;
Gaël Bonithon's avatar
Gaël Bonithon committed
  gint show_panel_label;
  gboolean presentation_mode;
  gboolean show_presentation_indicator;
typedef struct
Gaël Bonithon's avatar
Gaël Bonithon committed
  cairo_surface_t *surface; /* Icon */
  GtkWidget *img; /* Icon image in the menu */
  gchar *details; /* Description of the device + state */
  gchar *object_path; /* UpDevice object path */
  UpDevice *device; /* Pointer to the UpDevice */
  gulong changed_signal_id; /* device changed callback id */
  gulong expose_signal_id; /* expose-event callback id */
  GtkWidget *menu_item; /* The device's item on the menu (if shown) */
} BatteryDevice;
Simon Steinbeiss's avatar
Simon Steinbeiss committed
  PROP_0 = 0,
  PROP_SHOW_PANEL_LABEL,
  PROP_PRESENTATION_MODE,
  PROP_SHOW_PRESENTATION_INDICATOR,
} POWER_MANAGER_BUTTON_PROPERTIES;

Simon Steinbeiss's avatar
Simon Steinbeiss committed
  SIG_ICON_NAME_CHANGED = 0,
  SIG_TOOLTIP_CHANGED,
  SIG_N_SIGNALS,
Gaël Bonithon's avatar
Gaël Bonithon committed
static guint __signals[SIG_N_SIGNALS] = { 0 };
G_DEFINE_TYPE_WITH_PRIVATE (PowerManagerButton, power_manager_button, GTK_TYPE_TOGGLE_BUTTON)
Gaël Bonithon's avatar
Gaël Bonithon committed
static void
power_manager_button_finalize (GObject *object);
static GList *
find_device_in_list (PowerManagerButton *button,
                     const gchar *object_path);
static gboolean
power_manager_button_device_icon_draw (GtkWidget *img,
                                       cairo_t *cr,
                                       gpointer userdata);
static void
power_manager_button_set_icon (PowerManagerButton *button);
static void
power_manager_button_set_label (PowerManagerButton *button,
                                gdouble percentage,
                                guint64 time_to_empty_or_full);
#ifdef XFCE_PLUGIN
Gaël Bonithon's avatar
Gaël Bonithon committed
static void
power_manager_button_toggle_presentation_mode (GtkMenuItem *mi,
                                               GtkSwitch *sw);
static void
power_manager_button_update_presentation_indicator (PowerManagerButton *button);
#endif
Gaël Bonithon's avatar
Gaël Bonithon committed
static void
power_manager_button_update_label (PowerManagerButton *button,
                                   UpDevice *device);
static gboolean
power_manager_button_press_event (GtkWidget *widget,
                                  GdkEventButton *event);
static gboolean
power_manager_button_menu_add_device (PowerManagerButton *button,
                                      BatteryDevice *battery_device,
                                      gboolean append);
static void
battery_device_remove_surface (BatteryDevice *battery_device);
Gaël Bonithon's avatar
Gaël Bonithon committed
static BatteryDevice *
get_display_device (PowerManagerButton *button)
Simon Steinbeiss's avatar
Simon Steinbeiss committed
  GList *item = NULL;
  gdouble highest_percentage = 0;
  BatteryDevice *display_device = NULL;
Gaël Bonithon's avatar
Gaël Bonithon committed
  g_return_val_if_fail (POWER_MANAGER_IS_BUTTON (button), NULL);
Simon Steinbeiss's avatar
Simon Steinbeiss committed
  if (button->priv->display_device)
  {
    item = find_device_in_list (button, up_device_get_object_path (button->priv->display_device));
    if (item)
Simon Steinbeiss's avatar
Simon Steinbeiss committed
      return item->data;
Simon Steinbeiss's avatar
Simon Steinbeiss committed
  }
Simon Steinbeiss's avatar
Simon Steinbeiss committed
  /* We want to find the battery or ups device with the highest percentage
   * and use that to get our tooltip from */
  for (item = g_list_first (button->priv->devices); item != NULL; item = g_list_next (item))
  {
    BatteryDevice *battery_device = item->data;
    guint type = 0;
    gdouble percentage;

Gaël Bonithon's avatar
Gaël Bonithon committed
    if (!battery_device->device || !UP_IS_DEVICE (battery_device->device))
Simon Steinbeiss's avatar
Simon Steinbeiss committed
    {
      continue;
    }

    g_object_get (battery_device->device,
                  "kind", &type,
                  "percentage", &percentage,
                  NULL);

Loading
Loading full blame...