Skip to content
Snippets Groups Projects
power-manager-button.c 43.8 KiB
Newer Older
Eric Koegel's avatar
Eric Koegel committed
 * * Copyright (C) 2014 Eric Koegel <eric@xfce.org>
 *
 * 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
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <glib.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfce4ui/libxfce4ui.h>
#include <upower.h>
#include <xfconf/xfconf.h>

#include "common/xfpm-common.h"
#include "common/xfpm-config.h"
#include "common/xfpm-icons.h"
#include "common/xfpm-power-common.h"
#include "common/xfpm-brightness.h"
#include "common/xfpm-debug.h"
#include "power-manager-button.h"
Eric Koegel's avatar
Eric Koegel committed
#include "scalemenuitem.h"

#define SET_LEVEL_TIMEOUT (50)
#define PANEL_DEFAULT_ICON ("battery-full-charged")
#define PANEL_DEFAULT_ICON_SYMBOLIC ("battery-full-charged-symbolic")
#define POWER_MANAGER_BUTTON_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), POWER_MANAGER_TYPE_BUTTON, PowerManagerButtonPrivate))
struct PowerManagerButtonPrivate
#ifdef XFCE_PLUGIN
    XfcePanelPlugin *plugin;
    XfconfChannel   *channel;
    /* A list of BatteryDevices  */
    GList           *devices;

    /* The left-click popup menu, if one is being displayed */
    GtkWidget       *menu;

Eric Koegel's avatar
Eric Koegel committed
    /* The actual panel icon image */
    GtkWidget       *panel_icon_image;
Eric Koegel's avatar
Eric Koegel committed
    /* Keep track of icon name to redisplay during size changes */
    gchar           *panel_icon_name;
Eric Koegel's avatar
Eric Koegel committed
    /* Keep track of the last icon size for use during updates */
    gint             panel_icon_width;
    /* Keep track of the tooltip */
    gchar           *tooltip;

    /* Upower 0.99 has a display device that can be used for the
     * panel image and tooltip description */
    UpDevice        *display_device;

    XfpmBrightness  *brightness;

    /* display brightness slider widget */
    GtkWidget       *range;
    /* Some laptops (and mostly newer ones with intel graphics) can turn off the
     * backlight completely. If the user is not careful and sets the brightness
     * very low using the slider, he might not be able to see the screen contents
     * anymore. Brightness keys do not work on every laptop, so it's better to use
     * a safe default minimum level that the user can change via the settings
     * editor if desired.
     */
    gint32           brightness_min_level;

    /* filter range value changed events for snappier UI feedback */
    guint            set_level_timeout;
typedef struct
    GdkPixbuf   *pix;               /* 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;
typedef enum
{
    PROP_0 = 0,
    PROP_BRIGHTNESS_MIN_LEVEL,
} POWER_MANAGER_BUTTON_PROPERTIES;

enum {
    SIG_ICON_NAME_CHANGED = 0,
    SIG_TOOLTIP_CHANGED,
    SIG_N_SIGNALS,
};

static guint __signals[SIG_N_SIGNALS] = { 0, };
G_DEFINE_TYPE (PowerManagerButton, power_manager_button, GTK_TYPE_TOGGLE_BUTTON)
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_expose (GtkWidget *img, GdkEventExpose *event, gpointer userdata);
static void power_manager_button_set_icon (PowerManagerButton *button);
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 increase_brightness (PowerManagerButton *button);
static void decrease_brightness (PowerManagerButton *button);
static void battery_device_remove_pix (BatteryDevice *battery_device);
Eric Koegel's avatar
Eric Koegel committed
static BatteryDevice*
get_display_device (PowerManagerButton *button)
Eric Koegel's avatar
Eric Koegel committed
    GList *item = NULL;
    gdouble highest_percentage = 0;
    BatteryDevice *display_device = NULL;

    TRACE("entering");

    g_return_val_if_fail (POWER_MANAGER_IS_BUTTON(button), NULL);
    if (button->priv->display_device)
    {
        item = find_device_in_list (button, up_device_get_object_path (button->priv->display_device));
        if (item)
        {
            return item->data;
        }
Eric Koegel's avatar
Eric Koegel 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;
        if (!battery_device->device || !UP_IS_DEVICE(battery_device->device))
        g_object_get (battery_device->device,
                      "kind", &type,
                      "percentage", &percentage,
                      NULL);

        if (type == UP_DEVICE_KIND_BATTERY || type == UP_DEVICE_KIND_UPS)
            if (highest_percentage < percentage)
            {
                display_device = battery_device;
                highest_percentage = percentage;
            }
        }
Eric Koegel's avatar
Eric Koegel committed
    return display_device;
}

static void
power_manager_button_set_tooltip (PowerManagerButton *button)
Eric Koegel's avatar
Eric Koegel committed
{
    BatteryDevice *display_device = get_display_device (button);

    TRACE("entering");

    if (!GTK_IS_WIDGET (button))
        g_critical ("power_manager_button_set_tooltip: !GTK_IS_WIDGET (button)");
        return;
Loading
Loading full blame...