Newer
Older
*
* 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 "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"
#define SET_LEVEL_TIMEOUT (50)
#define SAFE_SLIDER_MIN_LEVEL (5)
#define PANEL_DEFAULT_ICON ("battery-full-charged")
#define POWER_MANAGER_BUTTON_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), POWER_MANAGER_TYPE_BUTTON, PowerManagerButtonPrivate))
/* A list of BatteryDevices */
GList *devices;
/* The left-click popup menu, if one is being displayed */
GtkWidget *menu;
/* Keep track of icon name to redisplay during size changes */
/* Keep track of the last icon size for use during updates */
/* 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;
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) */
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);
get_display_device (PowerManagerButton *button)
GList *item = NULL;
gdouble highest_percentage = 0;
BatteryDevice *display_device = NULL;
g_return_val_if_fail (POWER_MANAGER_IS_BUTTON(button), NULL);
item = find_device_in_list (button, up_device_get_object_path (button->priv->display_device));
if (item)
{
return item->data;
}
}
/* 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;
}
}
return display_device;
}
static void
power_manager_button_set_tooltip (PowerManagerButton *button)
{
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;
if (button->priv->tooltip != NULL)
{
g_free (button->priv->tooltip);
button->priv->tooltip = NULL;
}
/* if we have something, display it */
if( display_device->details )
{
button->priv->tooltip = g_strdup(display_device->details);
gtk_widget_set_tooltip_markup (GTK_WIDGET (button), display_device->details);
/* Tooltip changed! */
g_signal_emit (button, __signals[SIG_TOOLTIP_CHANGED], 0);
/* Odds are this is a desktop without any batteries attached */
button->priv->tooltip = g_strdup (_("Display battery levels for attached devices"));
gtk_widget_set_tooltip_text (GTK_WIDGET (button), button->priv->tooltip);
/* Tooltip changed! */
g_signal_emit (button, __signals[SIG_TOOLTIP_CHANGED], 0);
find_device_in_list (PowerManagerButton *button, const gchar *object_path)
g_return_val_if_fail ( POWER_MANAGER_IS_BUTTON(button), NULL );
for (item = g_list_first (button->priv->devices); item != NULL; item = g_list_next (item))
{
BatteryDevice *battery_device = item->data;
if (battery_device == NULL)
{
DBG("!battery_device");
continue;
}
if (g_strcmp0 (battery_device->object_path, object_path) == 0)
return item;
power_manager_button_device_icon_expose (GtkWidget *img, GdkEventExpose *event, gpointer userdata)
guint type = 0, state = 0;
gdouble percentage;
gint height, width;
gdouble min_height = 2;
PangoRectangle ink_extent, log_extent;
/* sanity checks */
if (!img || !GTK_IS_WIDGET (img))
if (UP_IS_DEVICE (userdata))
{
device = UP_DEVICE(userdata);
g_object_get (device,
"kind", &type,
"state", &state,
"percentage", &percentage,
NULL);
/* Don't draw the progressbar for Battery */
if (type == UP_DEVICE_KIND_BATTERY)
return FALSE;
}
else
{
/* If the UpDevice hasn't fully updated yet it then we'll want
* a question mark for sure. */
state = UP_DEVICE_STATE_UNKNOWN;
}
gtk_widget_get_allocation (img, &allocation);
cr = gdk_cairo_create (gtk_widget_get_window (img));
width = allocation.width;
height = allocation.height;
if (state != UP_DEVICE_STATE_UNKNOWN)
{
/* Draw the trough of the progressbar */
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_set_line_width (cr, 1.0);
cairo_rectangle (cr, width - 3.5, allocation.y + 1.5, 5, height - 2);
cairo_set_source_rgb (cr, 0.87, 0.87, 0.87);
cairo_fill_preserve (cr);
cairo_set_source_rgb (cr, 0.53, 0.54, 0.52);
cairo_stroke (cr);
/* Draw the fill of the progressbar
Use yellow for 20% and below, green for 100%, red for 5% and below and blue for the rest */
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
if ((height * (percentage / 100)) > min_height)
min_height = (height - 3) * (percentage / 100);
cairo_rectangle (cr, width - 3, allocation.y + height - min_height - 1, 4, min_height);
if (percentage > 5 && percentage < 20)
cairo_set_source_rgb (cr, 0.93, 0.83, 0.0);
else if (percentage > 20 && percentage < 100)
cairo_set_source_rgb (cr, 0.2, 0.4, 0.64);
else if (percentage == 100)
cairo_set_source_rgb (cr, 0.45, 0.82, 0.08);
else
cairo_set_source_rgb (cr, 0.94, 0.16, 0.16);
cairo_fill (cr);
cairo_rectangle (cr, width - 2.5, allocation.y + 2.5, 3, height - 4);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.75);
cairo_stroke (cr);
}
{
/* Draw a bubble with a question mark for devices with unknown state */
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_set_line_width (cr, 1.0);
cairo_arc(cr, width - 4.5, allocation.y + 6.5, 6, 0, 2*3.14159);
cairo_set_source_rgb (cr, 0.2, 0.54, 0.9);
cairo_fill_preserve (cr);
cairo_set_source_rgb (cr, 0.1, 0.37, 0.6);
cairo_stroke (cr);
layout = gtk_widget_create_pango_layout (GTK_WIDGET (img), "?");
pango_layout_set_font_description (layout, pango_font_description_from_string ("Sans Bold 9"));
pango_layout_get_pixel_extents (layout, &ink_extent, &log_extent);
cairo_move_to (cr, (width - 5.5) - (log_extent.width / 2), (allocation.y + 5.5) - (log_extent.height / 2));
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
pango_cairo_show_layout (cr, layout);
}
if (layout)
g_object_unref (layout);
power_manager_button_update_device_icon_and_details (PowerManagerButton *button, UpDevice *device)
GList *item;
BatteryDevice *battery_device;
BatteryDevice *display_device;
const gchar *object_path = up_device_get_object_path(device);
gchar *details;
gchar *icon_name;
GdkPixbuf *pix = NULL;
XFPM_DEBUG("entering for %s", object_path);
if (!POWER_MANAGER_IS_BUTTON (button))
item = find_device_in_list (button, object_path);
icon_name = get_device_icon_name (button->priv->upower, device);
details = get_device_description (button->priv->upower, device);
/* If UPower doesn't give us an icon, just use the default */
if (icon_name == NULL)
icon_name = g_strdup (PANEL_DEFAULT_ICON);
pix = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
icon_name,
32,
GTK_ICON_LOOKUP_USE_BUILTIN,
NULL);
g_free (battery_device->details);
/* If we had an image before, remove it and the callback */
battery_device_remove_pix(battery_device);
/* Get the display device, which may now be this one */
display_device = get_display_device (button);
if (battery_device == display_device)
DBG("this is the display device, updating");
/* it is! update the panel button */
g_free (button->priv->panel_icon_name);
#ifdef XFCE_PLUGIN
g_object_get (device,
"icon-name", &icon_name,
NULL);
if (icon_name == NULL || g_strcmp0(icon_name, "") == 0)
icon_name = g_strdup (PANEL_DEFAULT_ICON);
#endif
button->priv->panel_icon_name = g_strdup (icon_name);
power_manager_button_set_icon (button);
/* update tooltip */
power_manager_button_set_tooltip (button);
g_free (icon_name);
/* If the menu is being displayed, update it */
if (button->priv->menu && battery_device->menu_item)
{
gtk_menu_item_set_label (GTK_MENU_ITEM (battery_device->menu_item), details);
/* update the image, keep track of the signal ids and the img
* so we can disconnect it later */
battery_device->img = gtk_image_new_from_pixbuf (battery_device->pix);
g_object_ref (battery_device->img);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(battery_device->menu_item), battery_device->img);
G_GNUC_END_IGNORE_DEPRECATIONS
battery_device->expose_signal_id = g_signal_connect_after (G_OBJECT (battery_device->img),
G_CALLBACK (power_manager_button_device_icon_expose),
device);
device_changed_cb (UpDevice *device, GParamSpec *pspec, PowerManagerButton *button)
power_manager_button_update_device_icon_and_details (button, device);
power_manager_button_add_device (UpDevice *device, PowerManagerButton *button)
const gchar *object_path = up_device_get_object_path(device);
XFPM_DEBUG("entering for %s", object_path);
g_return_if_fail (POWER_MANAGER_IS_BUTTON (button ));
/* don't add the same device twice */
if (find_device_in_list (button, object_path))
return;
battery_device = g_new0 (BatteryDevice, 1);
/* hack, this depends on XFPM_DEVICE_TYPE_* being in sync with UP_DEVICE_KIND_* */
g_object_get (device,
"kind", &type,
NULL);
signal_id = g_signal_connect (device, "notify", G_CALLBACK (device_changed_cb), button);
/* populate the struct */
battery_device->object_path = g_strdup (object_path);
battery_device->changed_signal_id = signal_id;
battery_device->device = g_object_ref(device);
button->priv->devices = g_list_append (button->priv->devices, battery_device);
/* Add the icon and description for the device */
power_manager_button_update_device_icon_and_details (button, device);
/* If the menu is being shown, add this new device to it */
if (button->priv->menu)
{
power_manager_button_menu_add_device (button, battery_device, FALSE);
/* This function unrefs the pix and img from the battery device and
* disconnects the expose-event callback on the img.
*/
static void
battery_device_remove_pix (BatteryDevice *battery_device)
{
TRACE("entering");
if (battery_device == NULL)
return;
if (G_IS_OBJECT (battery_device->pix))
if (GTK_IS_WIDGET (battery_device->img))
{
if (battery_device->expose_signal_id != 0)
{
g_signal_handler_disconnect (battery_device->img, battery_device->expose_signal_id);
battery_device->expose_signal_id = 0;
}
g_object_unref (battery_device->img);
battery_device->img = NULL;
}
battery_device->pix = NULL;
}
}
remove_battery_device (PowerManagerButton *button, BatteryDevice *battery_device)
g_return_if_fail (POWER_MANAGER_IS_BUTTON (button));
g_return_if_fail (battery_device != NULL);
/* If it is being shown in the menu, remove it */
if(battery_device->menu_item && button->priv->menu)
gtk_container_remove (GTK_CONTAINER (button->priv->menu), battery_device->menu_item);
g_free (battery_device->details);
g_free (battery_device->object_path);
if (battery_device->device != NULL && UP_IS_DEVICE(battery_device->device))
/* disconnect the signal handler if we were using it */
if (battery_device->changed_signal_id != 0)
g_signal_handler_disconnect (battery_device->device, battery_device->changed_signal_id);
battery_device->changed_signal_id = 0;
g_object_unref (battery_device->device);
battery_device->device = NULL;
}
static void
power_manager_button_remove_device (PowerManagerButton *button, const gchar *object_path)
{
GList *item;
BatteryDevice *battery_device;
TRACE("entering for %s", object_path);
item = find_device_in_list (button, object_path);
if (item == NULL)
return;
battery_device = item->data;
/* Remove its resources */
remove_battery_device (button, battery_device);
/* remove it item and free the battery device */
button->priv->devices = g_list_delete_link (button->priv->devices, item);
device_added_cb (UpClient *upower, UpDevice *device, PowerManagerButton *button)
power_manager_button_add_device (device, button);
device_removed_cb (UpClient *upower, const gchar *object_path, PowerManagerButton *button)
power_manager_button_remove_device (button, object_path);
power_manager_button_add_all_devices (PowerManagerButton *button)
{
GPtrArray *array = NULL;
guint i;
button->priv->display_device = up_client_get_display_device (button->priv->upower);
power_manager_button_add_device (button->priv->display_device, button);
array = up_client_get_devices (button->priv->upower);
for (i = 0; i < array->len; i++)
{
UpDevice *device = g_ptr_array_index (array, i);
power_manager_button_add_device (device, button);
}
g_ptr_array_free (array, TRUE);
static void
power_manager_button_remove_all_devices (PowerManagerButton *button)
{
GList *item = NULL;
TRACE("entering");
g_return_if_fail (POWER_MANAGER_IS_BUTTON (button));
for (item = g_list_first (button->priv->devices); item != NULL; item = g_list_next (item))
{
BatteryDevice *battery_device = item->data;
if (battery_device == NULL)
{
DBG("!battery_device");
continue;
}
/* Remove its resources */
remove_battery_device (button, battery_device);
}
}
static void
brightness_up (PowerManagerButton *button)
{
gint32 level;
gint32 max_level;
xfpm_brightness_get_level (button->priv->brightness, &level);
max_level = xfpm_brightness_get_max_level (button->priv->brightness);
if ( level < max_level )
{
increase_brightness (button);
}
}
static void
brightness_down (PowerManagerButton *button)
{
gint32 level;
xfpm_brightness_get_level (button->priv->brightness, &level);
if ( level > button->priv->brightness_min_level )
{
decrease_brightness (button);
}
}
static gboolean
power_manager_button_scroll_event (GtkWidget *widget, GdkEventScroll *ev)
{
gboolean hw_found;
button = POWER_MANAGER_BUTTON (widget);
hw_found = xfpm_brightness_has_hw (button->priv->brightness);
return FALSE;
if (ev->direction == GDK_SCROLL_UP)
{
brightness_up (button);
return TRUE;
}
else if (ev->direction == GDK_SCROLL_DOWN)
{
brightness_down (button);
return TRUE;
}
return FALSE;
}
static void
set_brightness_min_level (PowerManagerButton *button, gint32 new_brightness_level)
{
gint32 max_level = xfpm_brightness_get_max_level (button->priv->brightness);
/* sanity check */
if (new_brightness_level > max_level)
new_brightness_level = -1;
/* -1 = auto, we set the step value to a hopefully sane default */
if (new_brightness_level == -1)
{
button->priv->brightness_min_level = (max_level > 100) ? SAFE_SLIDER_MIN_LEVEL : 0;
}
else
{
button->priv->brightness_min_level = new_brightness_level;
}
DBG("button->priv->brightness_min_level : %d", button->priv->brightness_min_level);
/* update the range if it's being shown */
if (button->priv->range)
{
gtk_range_set_range (GTK_RANGE (button->priv->range), button->priv->brightness_min_level, max_level);
}
}
static void
power_manager_button_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
PowerManagerButton *button;
button = POWER_MANAGER_BUTTON (object);
{
case PROP_BRIGHTNESS_MIN_LEVEL:
set_brightness_min_level (button, g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
power_manager_button_get_property(GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
PowerManagerButton *button;
button = POWER_MANAGER_BUTTON (object);
switch(property_id)
{
case PROP_BRIGHTNESS_MIN_LEVEL:
g_value_set_int (value, button->priv->brightness_min_level);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
power_manager_button_class_init (PowerManagerButtonClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->finalize = power_manager_button_finalize;
object_class->set_property = power_manager_button_set_property;
object_class->get_property = power_manager_button_get_property;
widget_class->button_press_event = power_manager_button_press_event;
widget_class->scroll_event = power_manager_button_scroll_event;
g_type_class_add_private (klass, sizeof (PowerManagerButtonPrivate));
__signals[SIG_TOOLTIP_CHANGED] = g_signal_new ("tooltip-changed",
POWER_MANAGER_TYPE_BUTTON,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(PowerManagerButtonClass,
tooltip_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
__signals[SIG_ICON_NAME_CHANGED] = g_signal_new ("icon-name-changed",
POWER_MANAGER_TYPE_BUTTON,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(PowerManagerButtonClass,
icon_name_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
#define XFPM_PARAM_FLAGS (G_PARAM_READWRITE \
| G_PARAM_CONSTRUCT \
| G_PARAM_STATIC_NAME \
| G_PARAM_STATIC_NICK \
| G_PARAM_STATIC_BLURB)
/* We allow and default to -1 only so that we can automagically set a
* sane value if the user hasn't selected one already */
g_object_class_install_property(object_class, PROP_BRIGHTNESS_MIN_LEVEL,
g_param_spec_int(BRIGHTNESS_SLIDER_MIN_LEVEL,
BRIGHTNESS_SLIDER_MIN_LEVEL,
BRIGHTNESS_SLIDER_MIN_LEVEL,
-1, G_MAXINT32, -1,
XFPM_PARAM_FLAGS));
#undef XFPM_PARAM_FLAGS
power_manager_button_init (PowerManagerButton *button)
GtkCssProvider *css_provider;
button->priv = POWER_MANAGER_BUTTON_GET_PRIVATE (button);
gtk_widget_set_can_default (GTK_WIDGET (button), FALSE);
gtk_widget_set_can_focus (GTK_WIDGET (button), FALSE);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
gtk_widget_set_name (GTK_WIDGET (button), "xfce4-power-manager-plugin");
button->priv->brightness = xfpm_brightness_new ();
xfpm_brightness_setup (button->priv->brightness);
button->priv->set_level_timeout = 0;
button->priv->upower = up_client_new ();
if ( !xfconf_init (&error) )
{
g_critical ("xfconf_init failed: %s\n", error->message);
g_error_free (error);
}
else
{
button->priv->channel = xfconf_channel_get ("xfce4-power-manager");
button->priv->panel_icon_name = g_strdup (PANEL_DEFAULT_ICON);
button->priv->panel_icon_width = 24;
/* Sane default Gtk style */
css_provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (css_provider,
"#xfce4-power-manager-plugin {"
"-GtkWidget-focus-padding: 0;"
"-GtkWidget-focus-line-width: 0;"
"-GtkButton-default-border: 0;"
"-GtkButton-inner-border: 0;"
"padding: 1px;"
"border-width: 1px;}",
-1, NULL);
gtk_style_context_add_provider (GTK_STYLE_CONTEXT (gtk_widget_get_style_context (GTK_WIDGET (button))),
GTK_STYLE_PROVIDER (css_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
/* Intercept scroll events */
gtk_widget_add_events (GTK_WIDGET (button), GDK_SCROLL_MASK);
g_signal_connect (button->priv->upower, "device-added", G_CALLBACK (device_added_cb), button);
g_signal_connect (button->priv->upower, "device-removed", G_CALLBACK (device_removed_cb), button);
}
static void
power_manager_button_finalize (GObject *object)
button = POWER_MANAGER_BUTTON (object);
g_free(button->priv->panel_icon_name);
if (button->priv->set_level_timeout)
{
g_source_remove(button->priv->set_level_timeout);
button->priv->set_level_timeout = 0;
}
g_signal_handlers_disconnect_by_data (button->priv->upower, button);
power_manager_button_remove_all_devices (button);
g_object_unref (button->priv->plugin);
G_OBJECT_CLASS (power_manager_button_parent_class)->finalize (object);
power_manager_button_new (XfcePanelPlugin *plugin)
#ifdef XFPM_SYSTRAY
power_manager_button_new (void)
#endif
PowerManagerButton *button = NULL;
button = g_object_new (POWER_MANAGER_TYPE_BUTTON, NULL, NULL);
#ifdef XFCE_PLUGIN
button->priv->plugin = XFCE_PANEL_PLUGIN (g_object_ref (plugin));
#endif
xfconf_g_property_bind (button->priv->channel,
PROPERTIES_PREFIX BRIGHTNESS_SLIDER_MIN_LEVEL, G_TYPE_INT,
G_OBJECT (button), BRIGHTNESS_SLIDER_MIN_LEVEL);
return GTK_WIDGET (button);
}
power_manager_button_set_icon (PowerManagerButton *button)
gtk_image_set_from_icon_name (GTK_IMAGE (button->priv->panel_icon_image), button->priv->panel_icon_name, GTK_ICON_SIZE_BUTTON);
gtk_image_set_pixel_size (GTK_IMAGE (button->priv->panel_icon_image), button->priv->panel_icon_width);
/* Notify others the icon name changed */
g_signal_emit (button, __signals[SIG_ICON_NAME_CHANGED], 0);
const gchar *
power_manager_button_get_icon_name (PowerManagerButton *button)
{
return button->priv->panel_icon_name;
}
const gchar *
power_manager_button_get_tooltip (PowerManagerButton *button)
{
return button->priv->tooltip;
}
power_manager_button_press_event (GtkWidget *widget, GdkEventButton *event)
PowerManagerButton *button = POWER_MANAGER_BUTTON (widget);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
power_manager_button_show_menu (button);
power_manager_button_size_changed_cb (XfcePanelPlugin *plugin, gint size, PowerManagerButton *button)
gint xthickness;
gint ythickness;
g_return_if_fail (POWER_MANAGER_IS_BUTTON (button));
g_return_if_fail (XFCE_IS_PANEL_PLUGIN (plugin));
g_return_if_fail (size > 0);
size /= xfce_panel_plugin_get_nrows (plugin);
/* Calculate the size of the widget because the theme can override it */
context = gtk_widget_get_style_context (GTK_WIDGET (button));
gtk_style_context_get_padding (context, gtk_widget_get_state_flags (GTK_WIDGET (button)), &padding);
gtk_style_context_get_border (context, gtk_widget_get_state_flags (GTK_WIDGET (button)), &border);
xthickness = padding.left+padding.right+border.left+border.right;
ythickness = padding.top+padding.bottom+border.top+border.bottom;
/* Calculate the size of the space left for the icon */
width = size - 2* MAX (xthickness, ythickness);
/* Since symbolic icons are usually only provided in 16px we
* try to be clever and use size steps */
if (width <= 21)
button->priv->panel_icon_width = 16;
else if (width >=22 && width <= 29)
button->priv->panel_icon_width = 24;
else if (width >= 30 && width <= 40)
button->priv->panel_icon_width = 32;
else
button->priv->panel_icon_width = width;
gtk_widget_set_size_request (GTK_WIDGET(plugin), size, size);
power_manager_button_set_icon (button);
power_manager_button_style_update_cb (XfcePanelPlugin *plugin, PowerManagerButton *button)
gtk_widget_reset_style (GTK_WIDGET (plugin));
power_manager_button_size_changed_cb (plugin, xfce_panel_plugin_get_size (plugin), button);
power_manager_button_free_data_cb (XfcePanelPlugin *plugin, PowerManagerButton *button)
{
gtk_widget_destroy (GTK_WIDGET (button));
}
static void
help_cb (GtkMenuItem *menuitem, gpointer user_data)
{
xfce_dialog_show_help_with_version (NULL, "xfce4-power-manager", "start", NULL, XFPM_VERSION_SHORT);
power_manager_button_show (PowerManagerButton *button)