diff options
author | Ali Abdallah <ali@ali-xfce.org> | 2009-11-05 10:04:22 +0100 |
---|---|---|
committer | Ali Abdallah <ali@ali-xfce.org> | 2009-11-05 10:04:22 +0100 |
commit | 14d0c8e0da97157b3acf127086c7a79be73961c3 (patch) | |
tree | 5c67645cdcfb32c95a10cc16ed8fbdd049c342df | |
parent | 44f74bccaf9cedbf1e245d372152055f487e52ad (diff) | |
download | ixfce4-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-- | TODO | 13 | ||||
-rw-r--r-- | libdbus/xfpm-dbus-monitor.c | 34 | ||||
-rw-r--r-- | libdbus/xfpm-dbus-monitor.h | 9 | ||||
-rw-r--r-- | src/xfpm-battery.c | 61 | ||||
-rw-r--r-- | src/xfpm-battery.h | 18 | ||||
-rw-r--r-- | src/xfpm-dkp.c | 311 | ||||
-rw-r--r-- | src/xfpm-dkp.h | 2 | ||||
-rw-r--r-- | src/xfpm-manager.c | 17 | ||||
-rw-r--r-- | src/xfpm-notify.c | 110 | ||||
-rw-r--r-- | src/xfpm-xfconf.c | 2 |
10 files changed, 478 insertions, 99 deletions
@@ -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, ¬ify, + 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)); |