summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Abdallah <ali@ali-xfce.org>2009-11-05 10:04:22 +0100
committerAli Abdallah <ali@ali-xfce.org>2009-11-05 10:04:22 +0100
commit14d0c8e0da97157b3acf127086c7a79be73961c3 (patch)
tree5c67645cdcfb32c95a10cc16ed8fbdd049c342df
parent44f74bccaf9cedbf1e245d372152055f487e52ad (diff)
downloadixfce4-power-manager-14d0c8e0da97157b3acf127086c7a79be73961c3.tar.gz
Query notification server capabilities for adding actions to
notification, if server supports actions use them to show a notification warning about the low power level if not use gtk. Re-Enable suspend/hibernate/lid actions.
-rw-r--r--TODO13
-rw-r--r--libdbus/xfpm-dbus-monitor.c34
-rw-r--r--libdbus/xfpm-dbus-monitor.h9
-rw-r--r--src/xfpm-battery.c61
-rw-r--r--src/xfpm-battery.h18
-rw-r--r--src/xfpm-dkp.c311
-rw-r--r--src/xfpm-dkp.h2
-rw-r--r--src/xfpm-manager.c17
-rw-r--r--src/xfpm-notify.c110
-rw-r--r--src/xfpm-xfconf.c2
10 files changed, 478 insertions, 99 deletions
diff --git a/TODO b/TODO
index 00e9a837..dd1ba557 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,8 @@
-* : Solve the problem of possible multiple sleep requests between us and the session manager.
-
-* : Probably provide a PermissionDenied error on the inhibit interface?
-
-* : Updating the documentations.
+* Reimplement critical battery action
+* Make xrandr brightness control working.
+* Reimplement the org.freedesktop.PowerManagement interface.
+* Battery information.
+* Hard drive spinning.
+* Survive D-Bus restarts.
+* Probably provide a PermissionDenied error on the inhibit interface?
+* Update the documentations.
diff --git a/libdbus/xfpm-dbus-monitor.c b/libdbus/xfpm-dbus-monitor.c
index 16fa406b..1721901c 100644
--- a/libdbus/xfpm-dbus-monitor.c
+++ b/libdbus/xfpm-dbus-monitor.c
@@ -53,8 +53,6 @@ struct XfpmDBusMonitorPrivate
GPtrArray *names_array;
GPtrArray *services_array;
-
- gboolean hal_connected;
};
typedef struct
@@ -68,7 +66,6 @@ enum
{
UNIQUE_NAME_LOST,
SERVICE_CONNECTION_CHANGED,
- HAL_CONNECTION_CHANGED,
SYSTEM_BUS_CONNECTION_CHANGED,
LAST_SIGNAL
};
@@ -126,14 +123,6 @@ xfpm_dbus_monitor_service_connection_changed (XfpmDBusMonitor *monitor, DBusBusT
XfpmWatchData *watch;
guint i;
- /* Simplify things for HAL */
- if ( !g_strcmp0 (name, "org.freedesktop.Hal") && bus_type == DBUS_BUS_SYSTEM )
- {
- monitor->priv->hal_connected = connected;
- g_signal_emit (G_OBJECT (monitor), signals [HAL_CONNECTION_CHANGED], 0, connected);
- return;
- }
-
for ( i = 0; i < monitor->priv->services_array->len; i++)
{
watch = g_ptr_array_index (monitor->priv->services_array, i);
@@ -196,10 +185,6 @@ xfpm_dbus_monitor_query_system_bus_idle (gpointer data)
return TRUE;
}
- /*
- * This message is catched by xfpm manager then it simply
- * restarts all the power manager
- */
monitor = XFPM_DBUS_MONITOR (data);
g_signal_emit (G_OBJECT (monitor), signals [SYSTEM_BUS_CONNECTION_CHANGED], 0, TRUE);
@@ -288,15 +273,6 @@ xfpm_dbus_monitor_class_init (XfpmDBusMonitorClass *klass)
G_TYPE_NONE, 2,
G_TYPE_STRING, G_TYPE_BOOLEAN);
- signals [HAL_CONNECTION_CHANGED] =
- g_signal_new ("hal-connection-changed",
- XFPM_TYPE_DBUS_MONITOR,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (XfpmDBusMonitorClass, hal_connection_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
-
signals [SERVICE_CONNECTION_CHANGED] =
g_signal_new ("service-connection-changed",
XFPM_TYPE_DBUS_MONITOR,
@@ -345,11 +321,6 @@ xfpm_dbus_monitor_init (XfpmDBusMonitor *monitor)
xfpm_dbus_monitor_system_bus_filter,
monitor,
NULL);
-
- monitor->priv->hal_connected = xfpm_dbus_name_has_owner (dbus_g_connection_get_connection (monitor->priv->system_bus),
- "org.freedesktop.Hal");
-
- xfpm_dbus_monitor_add_service (monitor, DBUS_BUS_SESSION, "org.freedesktop.Hal");
}
static void
@@ -473,8 +444,3 @@ void xfpm_dbus_monitor_remove_service (XfpmDBusMonitor *monitor, DBusBusType bus
xfpm_dbus_monitor_free_watch_data (watch);
}
}
-
-gboolean xfpm_dbus_monitor_hal_connected (XfpmDBusMonitor *monitor)
-{
- return monitor->priv->hal_connected;
-}
diff --git a/libdbus/xfpm-dbus-monitor.h b/libdbus/xfpm-dbus-monitor.h
index 84889909..cc780028 100644
--- a/libdbus/xfpm-dbus-monitor.h
+++ b/libdbus/xfpm-dbus-monitor.h
@@ -59,12 +59,6 @@ typedef struct
gboolean on_session);
/*
- * Hal Connection
- */
- void (*hal_connection_changed) (XfpmDBusMonitor *monitor,
- gboolean connected);
-
- /*
* DBus: system bus disconnected
*/
void (*system_bus_connection_changed) (XfpmDBusMonitor *monitor,
@@ -91,9 +85,6 @@ gboolean xfpm_dbus_monitor_add_service (XfpmDBusMonitor *monitor,
void xfpm_dbus_monitor_remove_service (XfpmDBusMonitor *monitor,
DBusBusType bus_type,
const gchar *service_name);
-
-gboolean xfpm_dbus_monitor_hal_connected (XfpmDBusMonitor *monitor);
-
G_END_DECLS
#endif /* __XFPM_DBUS_MONITOR_H */
diff --git a/src/xfpm-battery.c b/src/xfpm-battery.c
index e66d14c1..29b6cdd3 100644
--- a/src/xfpm-battery.c
+++ b/src/xfpm-battery.c
@@ -55,11 +55,12 @@ struct XfpmBatteryPrivate
gchar *icon_prefix;
+ XfpmBatteryCharge charge;
XfpmDkpDeviceState state;
XfpmDkpDeviceType type;
gboolean ac_online;
gboolean present;
- gint percentage;
+ guint percentage;
gint64 time_to_full;
gint64 time_to_empty;
@@ -72,6 +73,14 @@ enum
PROP_AC_ONLINE
};
+enum
+{
+ BATTERY_CHARGE_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
G_DEFINE_TYPE (XfpmBattery, xfpm_battery, GTK_TYPE_STATUS_ICON)
static const gchar * G_GNUC_CONST
@@ -219,7 +228,6 @@ xfpm_battery_notify_idle (gpointer data)
FALSE,
XFPM_NOTIFY_NORMAL,
GTK_STATUS_ICON (battery));
-
return FALSE;
}
@@ -389,6 +397,32 @@ xfpm_battery_set_tooltip_primary (XfpmBattery *battery, GtkTooltip *tooltip)
}
static void
+xfpm_battery_check_charge (XfpmBattery *battery)
+{
+ XfpmBatteryCharge charge;
+ guint critical_level, low_level;
+
+ g_object_get (G_OBJECT (battery->priv->conf),
+ CRITICAL_POWER_LEVEL, &critical_level,
+ NULL);
+
+ low_level = critical_level + 10;
+
+ if ( battery->priv->percentage > low_level )
+ charge = XFPM_BATTERY_CHARGE_OK;
+ else if ( battery->priv->percentage <= low_level && battery->priv->percentage > critical_level )
+ charge = XFPM_BATTERY_CHARGE_LOW;
+ else if ( battery->priv->percentage <= critical_level )
+ charge = XFPM_BATTERY_CHARGE_CRITICAL;
+
+ if ( charge != battery->priv->charge )
+ {
+ battery->priv->charge = charge;
+ g_signal_emit (G_OBJECT (battery), signals [BATTERY_CHARGE_CHANGED], 0);
+ }
+}
+
+static void
xfpm_battery_refresh (XfpmBattery *battery, GHashTable *props)
{
GValue *value;
@@ -427,7 +461,9 @@ xfpm_battery_refresh (XfpmBattery *battery, GHashTable *props)
goto out;
}
- battery->priv->percentage = (gint) g_value_get_double (value);
+ battery->priv->percentage = (guint) g_value_get_double (value);
+
+ xfpm_battery_check_charge (battery);
xfpm_battery_refresh_icon (battery);
@@ -551,6 +587,15 @@ xfpm_battery_class_init (XfpmBatteryClass *klass)
status_icon_class->query_tooltip = xfpm_battery_query_tooltip;
+ signals [BATTERY_CHARGE_CHANGED] =
+ g_signal_new ("battery-charge-changed",
+ XFPM_TYPE_BATTERY,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(XfpmBatteryClass, battery_charge_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0, G_TYPE_NONE);
+
g_object_class_install_property (object_class,
PROP_AC_ONLINE,
g_param_spec_boolean("ac-online",
@@ -571,6 +616,7 @@ xfpm_battery_init (XfpmBattery *battery)
battery->priv->proxy_prop = NULL;
battery->priv->state = XFPM_DKP_DEVICE_STATE_UNKNOWN;
battery->priv->type = XFPM_DKP_DEVICE_TYPE_UNKNOWN;
+ battery->priv->charge = XFPM_BATTERY_CHARGE_UNKNOWN;
battery->priv->icon_prefix = NULL;
battery->priv->time_to_full = 0;
battery->priv->time_to_empty = 0;
@@ -661,9 +707,16 @@ void xfpm_battery_monitor_device (XfpmBattery *battery,
xfpm_battery_changed_cb (proxy, battery);
}
-XfpmDkpDeviceType xfpm_battery_get_device_type (XfpmBattery *battery)
+XfpmDkpDeviceType xfpm_battery_get_device_type (XfpmBattery *battery)
{
g_return_val_if_fail (XFPM_IS_BATTERY (battery), XFPM_DKP_DEVICE_TYPE_UNKNOWN );
return battery->priv->type;
}
+
+XfpmBatteryCharge xfpm_battery_get_charge (XfpmBattery *battery)
+{
+ g_return_val_if_fail (XFPM_IS_BATTERY (battery), XFPM_BATTERY_CHARGE_UNKNOWN);
+
+ return battery->priv->charge;
+}
diff --git a/src/xfpm-battery.h b/src/xfpm-battery.h
index 2cd43990..91945178 100644
--- a/src/xfpm-battery.h
+++ b/src/xfpm-battery.h
@@ -33,6 +33,18 @@ G_BEGIN_DECLS
#define XFPM_BATTERY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XFPM_TYPE_BATTERY, XfpmBattery))
#define XFPM_IS_BATTERY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XFPM_TYPE_BATTERY))
+/*
+ * Order matters
+ */
+typedef enum
+{
+ XFPM_BATTERY_CHARGE_UNKNOWN,
+ XFPM_BATTERY_CHARGE_CRITICAL,
+ XFPM_BATTERY_CHARGE_LOW,
+ XFPM_BATTERY_CHARGE_OK
+
+} XfpmBatteryCharge;
+
typedef struct XfpmBatteryPrivate XfpmBatteryPrivate;
typedef struct
@@ -47,6 +59,8 @@ typedef struct
{
GtkStatusIconClass parent_class;
+ void (*battery_charge_changed) (XfpmBattery *battery);
+
} XfpmBatteryClass;
GType xfpm_battery_get_type (void) G_GNUC_CONST;
@@ -57,9 +71,11 @@ void xfpm_battery_monitor_device (XfpmBattery *battery,
DBusGProxy *proxy,
DBusGProxy *proxy_prop,
XfpmDkpDeviceType device_type);
-
+//FIXME, make these as properties
XfpmDkpDeviceType xfpm_battery_get_device_type (XfpmBattery *battery);
+XfpmBatteryCharge xfpm_battery_get_charge (XfpmBattery *battery);
+
G_END_DECLS
#endif /* __XFPM_BATTERY_H */
diff --git a/src/xfpm-dkp.c b/src/xfpm-dkp.c
index 1a7a0b54..1e59d65e 100644
--- a/src/xfpm-dkp.c
+++ b/src/xfpm-dkp.c
@@ -43,14 +43,12 @@
#include "xfpm-icons.h"
#include "xfpm-common.h"
#include "xfpm-config.h"
+#include "xfpm-enum-glib.h"
+#include "xfpm-debug.h"
+#include "xfpm-enum-types.h"
static void xfpm_dkp_finalize (GObject *object);
-static void xfpm_dkp_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-
static void xfpm_dkp_get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -89,6 +87,8 @@ struct XfpmDkpPrivate
gchar *daemon_version;
gboolean can_suspend;
gboolean can_hibernate;
+
+ GtkWidget *dialog;
};
enum
@@ -109,6 +109,7 @@ enum
LID_CHANGED,
WAKING_UP,
SLEEPING,
+ ASK_SHUTDOWN,
LAST_SIGNAL
};
@@ -326,6 +327,7 @@ xfpm_dkp_sleep (XfpmDkp *dkp, const gchar *sleep, gboolean force)
return;
}
+ g_signal_emit (G_OBJECT (dkp), signals [SLEEPING], 0);
xfpm_send_message_to_network_manager ("sleep");
g_object_get (G_OBJECT (dkp->priv->conf),
@@ -366,18 +368,34 @@ xfpm_dkp_sleep (XfpmDkp *dkp, const gchar *sleep, gboolean force)
}
static void
-xfpm_dkp_hibernate_cb (GtkStatusIcon *icon, XfpmDkp *dkp)
+xfpm_dkp_hibernate_cb (XfpmDkp *dkp)
{
xfpm_dkp_sleep (dkp, "Hibernate", FALSE);
}
static void
-xfpm_dkp_suspend_cb (GtkStatusIcon *icon, XfpmDkp *dkp)
+xfpm_dkp_suspend_cb (XfpmDkp *dkp)
{
xfpm_dkp_sleep (dkp, "Suspend", FALSE);
}
static void
+xfpm_dkp_hibernate_clicked (XfpmDkp *dkp)
+{
+ gtk_widget_destroy (dkp->priv->dialog );
+ dkp->priv->dialog = NULL;
+ xfpm_dkp_sleep (dkp, "Hibernate", TRUE);
+}
+
+static void
+xfpm_dkp_suspend_clicked (XfpmDkp *dkp)
+{
+ gtk_widget_destroy (dkp->priv->dialog );
+ dkp->priv->dialog = NULL;
+ xfpm_dkp_sleep (dkp, "Suspend", TRUE);
+}
+
+static void
xfpm_dkp_battery_info_cb (GtkStatusIcon *icon)
{
@@ -420,8 +438,8 @@ xfpm_dkp_show_tray_menu (XfpmDkp *dkp,
if ( dkp->priv->can_hibernate && dkp->priv->auth_hibernate)
{
gtk_widget_set_sensitive (mi, TRUE);
- g_signal_connect (G_OBJECT (mi), "activate",
- G_CALLBACK (xfpm_dkp_hibernate_cb), dkp);
+ g_signal_connect_swapped (G_OBJECT (mi), "activate",
+ G_CALLBACK (xfpm_dkp_hibernate_cb), dkp);
}
gtk_widget_show (mi);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
@@ -436,8 +454,8 @@ xfpm_dkp_show_tray_menu (XfpmDkp *dkp,
if ( dkp->priv->can_suspend && dkp->priv->auth_hibernate)
{
gtk_widget_set_sensitive (mi, TRUE);
- g_signal_connect (mi, "activate",
- G_CALLBACK (xfpm_dkp_suspend_cb), dkp);
+ g_signal_connect_swapped (mi, "activate",
+ G_CALLBACK (xfpm_dkp_suspend_cb), dkp);
}
gtk_widget_show (mi);
@@ -530,6 +548,242 @@ xfpm_dkp_show_tray_menu_battery (GtkStatusIcon *icon, guint button,
xfpm_dkp_show_tray_menu (dkp, icon, button, activate_time, TRUE);
}
+static XfpmBatteryCharge
+xfpm_dkp_get_current_charge_state (XfpmDkp *dkp)
+{
+ GList *list;
+ XfpmBatteryCharge charge = XFPM_BATTERY_CHARGE_UNKNOWN;
+ guint len, i;
+
+ list = g_hash_table_get_values (dkp->priv->hash);
+ len = g_list_length (list);
+
+ for ( i = 0; i < len; i++)
+ {
+ charge = MAX (charge, xfpm_battery_get_charge (XFPM_BATTERY (g_list_nth_data (list, i))));
+ }
+
+ return charge;
+}
+
+static void
+xfpm_dkp_notify_action_callback (NotifyNotification *n, gchar *action, XfpmDkp *dkp)
+{
+ if ( !g_strcmp0 (action, "Shutdown") )
+ ;
+ else
+ xfpm_dkp_sleep (dkp, action, TRUE);
+}
+
+
+static void
+xfpm_dkp_add_actions_to_notification (XfpmDkp *dkp, NotifyNotification *n)
+{
+ if ( dkp->priv->can_hibernate && dkp->priv->auth_hibernate )
+ {
+ xfpm_notify_add_action_to_notification(
+ dkp->priv->notify,
+ n,
+ "Hibernate",
+ _("Hibernate the system"),
+ (NotifyActionCallback)xfpm_dkp_notify_action_callback,
+ dkp);
+ }
+
+ if ( dkp->priv->can_suspend && dkp->priv->auth_suspend )
+ {
+ xfpm_notify_add_action_to_notification(
+ dkp->priv->notify,
+ n,
+ "Suspend",
+ _("Suspend the system"),
+ (NotifyActionCallback)xfpm_dkp_notify_action_callback,
+ dkp);
+ }
+ //FIXME, Shutdown
+}
+
+static void
+xfpm_dkp_show_critical_action_notification (XfpmDkp *dkp, XfpmBattery *battery)
+{
+ const gchar *message;
+ NotifyNotification *n;
+
+ message = _("System is running on low power. "\
+ "Save your work to avoid losing data");
+
+ n =
+ xfpm_notify_new_notification (dkp->priv->notify,
+ _("Xfce power manager"),
+ message,
+ gtk_status_icon_get_icon_name (GTK_STATUS_ICON (battery)),
+ 20000,
+ XFPM_NOTIFY_CRITICAL,
+ GTK_STATUS_ICON (battery));
+
+ xfpm_dkp_add_actions_to_notification (dkp, n);
+ xfpm_notify_critical (dkp->priv->notify, n);
+
+}
+
+static void
+xfpm_dkp_close_critical_dialog (XfpmDkp *dkp)
+{
+ gtk_widget_destroy (dkp->priv->dialog);
+ dkp->priv->dialog = NULL;
+}
+
+static void
+xfpm_dkp_show_critical_action_gtk (XfpmDkp *dkp)
+{
+ GtkWidget *dialog;
+ GtkWidget *content_area;
+ GtkWidget *img;
+ GtkWidget *cancel;
+ const gchar *message;
+
+ message = _("System is running on low power. "\
+ "Save your work to avoid losing data");
+
+ dialog = gtk_dialog_new_with_buttons (_("Xfce Power Manager"), NULL, GTK_DIALOG_MODAL,
+ NULL);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog),
+ GTK_RESPONSE_CANCEL);
+
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+ gtk_box_pack_start_defaults (GTK_BOX (content_area), gtk_label_new (message));
+
+ if ( dkp->priv->can_hibernate && dkp->priv->auth_hibernate )
+ {
+ GtkWidget *hibernate;
+ hibernate = gtk_button_new_with_label (_("Hibernate"));
+ img = gtk_image_new_from_icon_name (XFPM_HIBERNATE_ICON, GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (hibernate), img);
+ gtk_dialog_add_action_widget (GTK_DIALOG (dialog), hibernate, GTK_RESPONSE_NONE);
+
+ g_signal_connect_swapped (hibernate, "clicked",
+ G_CALLBACK (xfpm_dkp_hibernate_clicked), dkp);
+ }
+
+ if ( dkp->priv->can_suspend && dkp->priv->auth_suspend )
+ {
+ GtkWidget *suspend;
+
+ suspend = gtk_button_new_with_label (_("Suspend"));
+ img = gtk_image_new_from_icon_name (XFPM_SUSPEND_ICON, GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (suspend), img);
+ gtk_dialog_add_action_widget (GTK_DIALOG (dialog), suspend, GTK_RESPONSE_NONE);
+
+ g_signal_connect_swapped (suspend, "clicked",
+ G_CALLBACK (xfpm_dkp_suspend_clicked), dkp);
+ }
+
+ cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+ gtk_dialog_add_action_widget (GTK_DIALOG (dialog), cancel, GTK_RESPONSE_NONE);
+
+ g_signal_connect_swapped (cancel, "clicked",
+ G_CALLBACK (xfpm_dkp_close_critical_dialog), dkp);
+
+ g_signal_connect_swapped (dialog, "destroy",
+ G_CALLBACK (xfpm_dkp_close_critical_dialog), dkp);
+
+ dkp->priv->dialog = dialog;
+ gtk_widget_show_all (dialog);
+}
+
+static void
+xfpm_dkp_show_critical_action (XfpmDkp *dkp, XfpmBattery *battery)
+{
+ gboolean supports_actions;
+
+ g_object_get (G_OBJECT (dkp->priv->notify),
+ "actions", &supports_actions,
+ NULL);
+
+ if ( supports_actions )
+ xfpm_dkp_show_critical_action_notification (dkp, battery);
+ else
+ xfpm_dkp_show_critical_action_gtk (dkp);
+}
+
+static void
+xfpm_dkp_process_critical_action (XfpmDkp *dkp, XfpmShutdownRequest req)
+{
+ if ( req == XFPM_ASK )
+ g_signal_emit (G_OBJECT (dkp), signals [ASK_SHUTDOWN], 0);
+ else if ( req == XFPM_DO_SUSPEND )
+ xfpm_dkp_sleep (dkp, "Suspend", TRUE);
+ else if ( req == XFPM_DO_HIBERNATE )
+ xfpm_dkp_sleep (dkp, "Hibernate", TRUE);
+ //FIXME, Shutdown also.
+
+}
+
+static void
+xfpm_dkp_system_on_low_power (XfpmDkp *dkp, XfpmBattery *battery)
+{
+ XfpmShutdownRequest critical_action;
+
+ g_object_get (G_OBJECT (dkp->priv->conf),
+ CRITICAL_BATT_ACTION_CFG, &critical_action,
+ NULL);
+
+ TRACE ("System is running on low power");
+ XFPM_DEBUG_ENUM ("Critical battery action", critical_action, XFPM_TYPE_SHUTDOWN_REQUEST);
+
+ if ( critical_action == XFPM_DO_NOTHING )
+ {
+ xfpm_dkp_show_critical_action (dkp, battery);
+ }
+ else
+ {
+ xfpm_dkp_process_critical_action (dkp, critical_action);
+ }
+}
+
+static void
+xfpm_dkp_battery_charge_changed_cb (XfpmBattery *battery, XfpmDkp *dkp)
+{
+ XfpmBatteryCharge battery_charge;
+ XfpmBatteryCharge current_charge;
+
+ battery_charge = xfpm_battery_get_charge (battery);
+ current_charge = xfpm_dkp_get_current_charge_state (dkp);
+
+ if ( current_charge == XFPM_BATTERY_CHARGE_CRITICAL )
+ {
+ xfpm_dkp_system_on_low_power (dkp, battery);
+ return;
+ }
+
+ if ( battery_charge == XFPM_BATTERY_CHARGE_LOW )
+ {
+ gboolean notify;
+
+ g_object_get (G_OBJECT (dkp->priv->conf),
+ GENERAL_NOTIFICATION_CFG, &notify,
+ NULL);
+ if ( notify )
+ xfpm_notify_show_notification (dkp->priv->notify,
+ _("Xfce power manager"),
+ _("Battery charge level is low"),
+ gtk_status_icon_get_icon_name (GTK_STATUS_ICON (battery)),
+ 10000,
+ FALSE,
+ XFPM_NOTIFY_NORMAL,
+ GTK_STATUS_ICON (battery));
+ }
+
+ /*Current charge is okay now, then close the dialog*/
+ if ( dkp->priv->dialog )
+ {
+ gtk_widget_destroy (dkp->priv->dialog);
+ dkp->priv->dialog = NULL;
+ }
+}
+
static void
xfpm_dkp_add_device (XfpmDkp *dkp, const gchar *object_path)
{
@@ -554,7 +808,7 @@ xfpm_dkp_add_device (XfpmDkp *dkp, const gchar *object_path)
if ( device_type == XFPM_DKP_DEVICE_TYPE_LINE_POWER )
{
-
+ //FIXME: Handel adaptor.
}
else if ( device_type == XFPM_DKP_DEVICE_TYPE_BATTERY ||
device_type == XFPM_DKP_DEVICE_TYPE_UPS ||
@@ -576,6 +830,8 @@ xfpm_dkp_add_device (XfpmDkp *dkp, const gchar *object_path)
g_signal_connect (battery, "popup-menu",
G_CALLBACK (xfpm_dkp_show_tray_menu_battery), dkp);
+ g_signal_connect (battery, "battery-charge-changed",
+ G_CALLBACK (xfpm_dkp_battery_charge_changed_cb), dkp);
}
else
{
@@ -688,7 +944,6 @@ xfpm_dkp_class_init (XfpmDkpClass *klass)
object_class->finalize = xfpm_dkp_finalize;
object_class->get_property = xfpm_dkp_get_property;
- object_class->set_property = xfpm_dkp_set_property;
signals [ON_BATTERY_CHANGED] =
g_signal_new ("on-battery-changed",
@@ -735,6 +990,15 @@ xfpm_dkp_class_init (XfpmDkpClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0, G_TYPE_NONE);
+ signals [ASK_SHUTDOWN] =
+ g_signal_new ("ask-shutdown",
+ XFPM_TYPE_DKP,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(XfpmDkpClass, ask_shutdown),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0, G_TYPE_NONE);
+
g_object_class_install_property (object_class,
PROP_ON_BATTERY,
g_param_spec_boolean ("on-battery",
@@ -798,6 +1062,7 @@ xfpm_dkp_init (XfpmDkp *dkp)
dkp->priv->can_hibernate = FALSE;
dkp->priv->auth_hibernate = TRUE;
dkp->priv->auth_suspend = TRUE;
+ dkp->priv->dialog = NULL;
dkp->priv->inhibit = xfpm_inhibit_new ();
dkp->priv->notify = xfpm_notify_new ();
@@ -845,7 +1110,7 @@ xfpm_dkp_init (XfpmDkp *dkp)
#ifdef HAVE_POLKIT
xfpm_dkp_check_polkit_auth (dkp);
#endif
-
+
dbus_g_proxy_add_signal (dkp->priv->proxy, "Changed", G_TYPE_INVALID);
dbus_g_proxy_add_signal (dkp->priv->proxy, "DeviceAdded", G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_add_signal (dkp->priv->proxy, "DeviceRemoved", G_TYPE_STRING, G_TYPE_INVALID);
@@ -864,29 +1129,13 @@ xfpm_dkp_init (XfpmDkp *dkp)
out:
xfpm_dkp_dbus_init (dkp);
-
+
/*
* Emit org.freedesktop.PowerManagement session signals on startup
*/
g_signal_emit (G_OBJECT (dkp), signals [ON_BATTERY_CHANGED], 0, dkp->priv->on_battery);
}
-static void xfpm_dkp_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- XfpmDkp *dkp;
- dkp = XFPM_DKP (object);
-
- switch (prop_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
static void xfpm_dkp_get_property (GObject *object,
guint prop_id,
GValue *value,
diff --git a/src/xfpm-dkp.h b/src/xfpm-dkp.h
index f99a1a92..e928831f 100644
--- a/src/xfpm-dkp.h
+++ b/src/xfpm-dkp.h
@@ -87,6 +87,8 @@ typedef struct
void (*sleeping) (XfpmDkp *dkp);
+ void (*ask_shutdown) (XfpmDkp *dkp);
+
} XfpmDkpClass;
GType xfpm_dkp_get_type (void) G_GNUC_CONST;
diff --git a/src/xfpm-manager.c b/src/xfpm-manager.c
index d1c07203..822b8b4a 100644
--- a/src/xfpm-manager.c
+++ b/src/xfpm-manager.c
@@ -170,6 +170,13 @@ xfpm_manager_reserve_names (XfpmManager *manager)
}
static void
+xfpm_manager_ask_shutdown (XfpmManager *manager)
+{
+ if ( manager->priv->session_managed )
+ xfce_sm_client_request_shutdown (manager->priv->client, XFCE_SM_CLIENT_SHUTDOWN_HINT_ASK);
+}
+
+static void
xfpm_manager_sleep_request (XfpmManager *manager, XfpmShutdownRequest req, gboolean force)
{
switch (req)
@@ -186,7 +193,7 @@ xfpm_manager_sleep_request (XfpmManager *manager, XfpmShutdownRequest req, gbool
/*FIXME ConsoleKit*/
break;
case XFPM_ASK:
- xfce_sm_client_request_shutdown (manager->priv->client, XFCE_SM_CLIENT_SHUTDOWN_HINT_ASK);
+ xfpm_manager_ask_shutdown (manager);
break;
default:
g_warn_if_reached ();
@@ -235,8 +242,8 @@ xfpm_manager_button_pressed_cb (XfpmButton *bt, XfpmButtonKey type, XfpmManager
XFPM_DEBUG_ENUM ("Shutdown request : ", req, XFPM_TYPE_SHUTDOWN_REQUEST);
- if ( req == XFPM_ASK && manager->priv->session_managed )
- xfce_sm_client_request_shutdown (manager->priv->client, XFCE_SM_CLIENT_SHUTDOWN_HINT_ASK);
+ if ( req == XFPM_ASK )
+ xfpm_manager_ask_shutdown (manager);
else
{
if ( g_timer_elapsed (manager->priv->timer, NULL) > SLEEP_KEY_TIMEOUT )
@@ -245,7 +252,6 @@ xfpm_manager_button_pressed_cb (XfpmButton *bt, XfpmButtonKey type, XfpmManager
xfpm_manager_sleep_request (manager, req, FALSE);
}
}
-
}
static void
@@ -376,6 +382,9 @@ void xfpm_manager_start (XfpmManager *manager)
g_signal_connect_swapped (manager->priv->dkp, "sleeping",
G_CALLBACK (xfpm_manager_reset_sleep_timer), manager);
+
+ g_signal_connect_swapped (manager->priv->dkp, "ask-shutdown",
+ G_CALLBACK (xfpm_manager_ask_shutdown), manager);
out:
;
}
diff --git a/src/xfpm-notify.c b/src/xfpm-notify.c
index 89a78bbd..38d5bef4 100644
--- a/src/xfpm-notify.c
+++ b/src/xfpm-notify.c
@@ -44,6 +44,7 @@
#include "xfpm-common.h"
#include "xfpm-notify.h"
+#include "xfpm-dbus-monitor.h"
static void xfpm_notify_finalize (GObject *object);
@@ -59,45 +60,132 @@ static NotifyNotification * xfpm_notify_new_notification_internal (const gchar *
struct XfpmNotifyPrivate
{
+ XfpmDBusMonitor *monitor;
+
NotifyNotification *notification;
NotifyNotification *critical;
+
+ gboolean supports_actions;
+ gboolean supports_sync; /*For x-canonical-private-synchronous */
};
-static gpointer xfpm_notify_object = NULL;
+enum
+{
+ PROP_0,
+ PROP_ACTIONS,
+ PROP_SYNC
+};
G_DEFINE_TYPE(XfpmNotify, xfpm_notify, G_TYPE_OBJECT)
static void
-xfpm_notify_class_init(XfpmNotifyClass *klass)
+xfpm_notify_get_server_caps (XfpmNotify *notify)
{
- GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ GList *caps = NULL;
+ notify->priv->supports_actions = FALSE;
+ notify->priv->supports_sync = FALSE;
+
+ caps = notify_get_server_caps ();
+
+ if (caps != NULL)
+ {
+ if (g_list_find_custom (caps, "x-canonical-private-synchronous", (GCompareFunc) g_strcmp0) != NULL)
+ notify->priv->supports_sync = TRUE;
+
+ if (g_list_find_custom (caps, "actions", (GCompareFunc) g_strcmp0) != NULL)
+ notify->priv->supports_actions = TRUE;
- object_class->finalize = xfpm_notify_finalize;
+ g_list_foreach(caps, (GFunc)g_free, NULL);
+ g_list_free(caps);
+ }
+}
+static void
+xfpm_notify_check_server (XfpmDBusMonitor *monitor,
+ gchar *service_name,
+ gboolean connected,
+ gboolean on_session,
+ XfpmNotify *notify)
+{
+ if ( !g_strcmp0 (service_name, "org.freedesktop.Notifications") && on_session && connected )
+ xfpm_notify_get_server_caps (notify);
+}
- g_type_class_add_private(klass,sizeof(XfpmNotifyPrivate));
+static void xfpm_notify_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ XfpmNotify *notify;
+
+ notify = XFPM_NOTIFY (object);
+
+ switch (prop_id)
+ {
+ case PROP_ACTIONS:
+ g_value_set_boolean (value, notify->priv->supports_actions);
+ break;
+ case PROP_SYNC:
+ g_value_set_boolean (value, notify->priv->supports_sync);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+xfpm_notify_class_init (XfpmNotifyClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = xfpm_notify_finalize;
+ object_class->get_property = xfpm_notify_get_property;
+
+ g_object_class_install_property (object_class,
+ PROP_ACTIONS,
+ g_param_spec_boolean ("actions",
+ NULL, NULL,
+ FALSE,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_SYNC,
+ g_param_spec_boolean ("sync",
+ NULL, NULL,
+ FALSE,
+ G_PARAM_READABLE));
+
+ g_type_class_add_private (klass, sizeof (XfpmNotifyPrivate));
}
static void
-xfpm_notify_init(XfpmNotify *notify)
+xfpm_notify_init (XfpmNotify *notify)
{
- notify->priv = XFPM_NOTIFY_GET_PRIVATE(notify);
+ notify->priv = XFPM_NOTIFY_GET_PRIVATE (notify);
notify->priv->notification = NULL;
notify->priv->critical = NULL;
+
+ notify->priv->monitor = xfpm_dbus_monitor_new ();
+ xfpm_dbus_monitor_add_service (notify->priv->monitor, DBUS_BUS_SESSION, "org.freedesktop.Notifications");
+ g_signal_connect (notify->priv->monitor, "service-connection-changed",
+ G_CALLBACK (xfpm_notify_check_server), notify);
+
+ xfpm_notify_get_server_caps (notify);
}
static void
-xfpm_notify_finalize(GObject *object)
+xfpm_notify_finalize (GObject *object)
{
XfpmNotify *notify;
- notify = XFPM_NOTIFY(object);
+ notify = XFPM_NOTIFY (object);
xfpm_notify_close_normal (notify);
xfpm_notify_close_critical (notify);
- G_OBJECT_CLASS(xfpm_notify_parent_class)->finalize(object);
+ G_OBJECT_CLASS (xfpm_notify_parent_class)->finalize(object);
}
static void
@@ -172,6 +260,8 @@ xfpm_notify_close_notification (XfpmNotify *notify )
XfpmNotify *
xfpm_notify_new (void)
{
+ static gpointer xfpm_notify_object = NULL;
+
if ( xfpm_notify_object != NULL )
{
g_object_ref (xfpm_notify_object);
diff --git a/src/xfpm-xfconf.c b/src/xfpm-xfconf.c
index 93562693..359d0c60 100644
--- a/src/xfpm-xfconf.c
+++ b/src/xfpm-xfconf.c
@@ -234,7 +234,7 @@ xfpm_xfconf_class_init (XfpmXfconfClass *klass)
PROP_CRITICAL_LEVEL,
g_param_spec_uint (CRITICAL_POWER_LEVEL,
NULL, NULL,
- 5,
+ 1,
20,
10,
G_PARAM_READWRITE));