From f50ecae4010b68777623d1fe49863dbdf3358c93 Mon Sep 17 00:00:00 2001
From: Ali Abdallah <ali.slackware@gmail.com>
Date: Sat, 11 Apr 2009 21:06:30 +0000
Subject: [PATCH] Implement option to put the system in sleep mode when it is
 inactive for a long time

(Old svn revision: 7168)
---
 ChangeLog                    |   3 +
 TODO                         |   2 -
 settings/xfpm-settings.c     | 153 +++++++++++++++++++++++++++++++--
 settings/xfpm-settings.glade | 158 ++++++++++++++++++++++++++---------
 src/xfpm-brightness-hal.c    |  17 ++--
 src/xfpm-config.h            |   4 +
 src/xfpm-engine.c            |  66 +++++++++++++++
 src/xfpm-idle.h              |   9 ++
 src/xfpm-xfconf.c            |  92 +++++++++++++++++++-
 src/xfpm-xfconf.h            |   2 +
 10 files changed, 445 insertions(+), 61 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 14263744..5e77bfdf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,7 @@
 
+2009-04-11 23:06 Ali aliov@xfce.org 
+	 * : Implement option to put the system in sleep mode when it is inactive for a long time
+
 2009-04-11 16:48 Ali aliov@xfce.org 
 	 * : Patch for the xfpm-button-hal from Mike Massonnet
 
diff --git a/TODO b/TODO
index 600ea53d..5f3bdaeb 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,3 @@
-* : Option to sleep when system is idle for a long time (does anybody needs this?).
-
 * : OnLowBattery DBus signals (currently there is only OnBattery DBus signal).
 
 * : Support Suspend Hybrid! ( DeviceKit power will not support this! ).
diff --git a/settings/xfpm-settings.c b/settings/xfpm-settings.c
index 23908cf3..bd80ab00 100644
--- a/settings/xfpm-settings.c
+++ b/settings/xfpm-settings.c
@@ -103,6 +103,28 @@ set_show_tray_icon_cb (GtkWidget *w, XfconfChannel *channel)
     }
 }
 
+static void
+inactivity_on_ac_value_changed_cb (GtkWidget *widget, XfconfChannel *channel)
+{
+    gint value    = (gint)gtk_range_get_value (GTK_RANGE (widget));
+    
+    if (!xfconf_channel_set_uint (channel, ON_AC_INACTIVITY_TIMEOUT, value))
+    {
+	g_critical ("Cannot set value for property %s\n", ON_AC_INACTIVITY_TIMEOUT);
+    }
+}
+
+static void
+inactivity_on_battery_value_changed_cb (GtkWidget *widget, XfconfChannel *channel)
+{
+    gint value    = (gint)gtk_range_get_value (GTK_RANGE (widget));
+    
+    if (!xfconf_channel_set_uint (channel, ON_BATTERY_INACTIVITY_TIMEOUT, value))
+    {
+	g_critical ("Cannot set value for property %s\n", ON_BATTERY_INACTIVITY_TIMEOUT);
+    }
+}
+
 static void
 set_sleep_changed_cb (GtkWidget *w, XfconfChannel *channel)
 {
@@ -197,6 +219,24 @@ notify_toggled_cb (GtkWidget *w, XfconfChannel *channel)
     }
 }
 
+static void
+set_hibernate_inactivity (GtkWidget *w, XfconfChannel *channel)
+{
+    if (!xfconf_channel_set_string (channel, INACTIVITY_SLEEP_MODE, "hibernate") )
+    {
+	g_critical ("Cannot set value hibernate for property %s", INACTIVITY_SLEEP_MODE);
+    }
+}
+
+static void
+set_suspend_inactivity (GtkWidget *w, XfconfChannel *channel)
+{
+    if (!xfconf_channel_set_string (channel, INACTIVITY_SLEEP_MODE, "suspend") )
+    {
+	g_critical ("Cannot set value suspend for property %s", INACTIVITY_SLEEP_MODE);
+    }
+}
+
 #ifdef HAVE_DPMS
 static void
 set_dpms_sleep_mode (GtkWidget *w, XfconfChannel *channel)
@@ -326,7 +366,7 @@ off_on_ac_value_changed_cb (GtkWidget *w, XfconfChannel *channel)
 static gchar *
 format_dpms_value_cb (GtkScale *scale, gdouble value)
 {
-    if ( (int)value == 0 )
+    if ( (gint)value == 0 )
     	return g_strdup (_("Never"));
     
     if ( (int)value == 1 )
@@ -336,13 +376,42 @@ format_dpms_value_cb (GtkScale *scale, gdouble value)
 }
 #endif /* HAVE_DPMS */
 
+static gchar *
+format_inactivity_value_cb (GtkScale *scale, gdouble value)
+{
+    gint h, min;
+    
+    if ( (gint)value <= 30 )
+	return g_strdup (_("Never"));
+    else if ( (gint)value < 60 )
+	return g_strdup_printf ("%d %s", (gint)value, _("Minutes"));
+    else if ( (gint)value == 60)
+	return g_strdup (_("One hour"));
+    else if ( (gint)value > 60 )
+    {
+	h = (gint)value/60;
+	min = (gint)value%60;
+	
+	if ( h <= 1 )
+	    if ( min == 0 )      return g_strdup_printf ("%s", _("One hour"));
+	    else if ( min == 1 ) return g_strdup_printf ("%s %s", _("One hour"),  _("one minute"));
+	    else                 return g_strdup_printf ("%s %d %s", _("One hour"), min, _("minutes"));
+	else 
+	    if ( min == 0 )      return g_strdup_printf ("%d %s", h, _("hours"));
+	    else if ( min == 1 ) return g_strdup_printf ("%d %s %s", h, _("hours"), _("one minute"));
+	    else            return g_strdup_printf ("%d %s %d %s", h, _("hours"), min, _("minutes"));
+    }
+	
+    return g_strdup_printf ("%d %s", (int)value, _("Minutes"));
+}
+
 /*
  * Format value of GtkRange used with Brightness
  */
 static gchar *
 format_brightness_value_cb (GtkScale *scale, gdouble value)
 {
-    if ( (int)value == 9 )
+    if ( (gint)value <= 9 )
     	return g_strdup (_("Never"));
         
     return g_strdup_printf ("%d %s", (int)value, _("Seconds"));
@@ -460,6 +529,22 @@ xfpm_settings_on_battery (XfconfChannel *channel, gboolean user_privilege, gbool
     GtkListStore *list_store;
     GtkTreeIter iter;
     GtkWidget *battery_critical = glade_xml_get_widget (xml, "battery-critical-combox");
+    GtkWidget *inact;
+    
+    inact = glade_xml_get_widget (xml, "inactivity-on-battery");
+    
+    if ( !can_suspend && !can_hibernate )
+    {
+	gtk_widget_set_sensitive (inact, FALSE);
+	gtk_widget_set_tooltip_text (inact, _("Hibernate and suspend operations not permitted"));
+    }
+    
+    val = xfconf_channel_get_uint (channel, ON_BATTERY_INACTIVITY_TIMEOUT, 30);
+    gtk_range_set_value (GTK_RANGE (inact), val);
+    g_signal_connect (inact, "value-changed",
+		      G_CALLBACK (inactivity_on_battery_value_changed_cb), channel);
+    g_signal_connect (inact, "format-value",
+		      G_CALLBACK (format_inactivity_value_cb), NULL);
     
     if (!user_privilege )
     {
@@ -642,8 +727,25 @@ static void
 xfpm_settings_on_ac (XfconfChannel *channel, gboolean user_privilege, gboolean can_suspend, 
 		     gboolean can_hibernate, gboolean has_lcd_brightness, gboolean has_lid)
 {
+    GtkWidget *inact;
     guint val;
     gboolean valid;
+    
+    inact = glade_xml_get_widget (xml, "inactivity-on-ac");
+    
+    if ( !can_suspend && !can_hibernate )
+    {
+	gtk_widget_set_sensitive (inact, FALSE);
+	gtk_widget_set_tooltip_text (inact, _("Hibernate and suspend operations not permitted"));
+    }
+    
+    val = xfconf_channel_get_uint (channel, ON_AC_INACTIVITY_TIMEOUT, 30);
+    gtk_range_set_value (GTK_RANGE (inact), val);
+    g_signal_connect (inact, "value-changed",
+		      G_CALLBACK (inactivity_on_ac_value_changed_cb), channel);
+    g_signal_connect (inact, "format-value",
+		      G_CALLBACK (format_inactivity_value_cb), NULL);
+   
 #ifdef HAVE_DPMS
     /*
      * DPMS settings when running on AC power 
@@ -654,7 +756,7 @@ xfpm_settings_on_ac (XfconfChannel *channel, gboolean user_privilege, gboolean c
     on_ac_dpms_sleep = glade_xml_get_widget (xml, "sleep-dpms-on-ac");
   
     val = xfconf_channel_get_uint (channel, ON_AC_DPMS_SLEEP, 10);
-    gtk_range_set_value (GTK_RANGE(on_ac_dpms_sleep), val);
+    gtk_range_set_value (GTK_RANGE (on_ac_dpms_sleep), val);
     
     g_signal_connect (on_ac_dpms_sleep, "value-changed",
 		      G_CALLBACK(sleep_on_ac_value_changed_cb), channel);
@@ -997,18 +1099,57 @@ xfpm_settings_general (XfconfChannel *channel, gboolean user_privilege,
 }
 
 static void
-xfpm_settings_advanced (XfconfChannel *channel, gboolean system_latop, gboolean user_privilege )
+xfpm_settings_advanced (XfconfChannel *channel, gboolean system_latop, gboolean user_privilege,
+			gboolean can_suspend, gboolean can_hibernate)
 {
     guint val;
+    gchar *str;
+    
+    GtkWidget *inact_suspend = glade_xml_get_widget (xml, "inactivity-suspend");
+    GtkWidget *inact_hibernate = glade_xml_get_widget (xml, "inactivity-hibernate");
+    
+    if ( !can_suspend )
+    {
+	gtk_widget_set_sensitive (inact_suspend, FALSE);
+	gtk_widget_set_tooltip_text (inact_suspend, _("Suspend operation not permitted"));
+    }
+    
+    if ( !can_hibernate )
+    {
+	gtk_widget_set_sensitive (inact_hibernate, FALSE);
+	gtk_widget_set_tooltip_text (inact_hibernate, _("Hibernate operation not permitted"));
+    }
+   
+    g_signal_connect (inact_suspend, "toggled",
+		      G_CALLBACK (set_suspend_inactivity), channel);
+		      
+    g_signal_connect (inact_hibernate, "toggled",
+		      G_CALLBACK (set_hibernate_inactivity), channel);
+		      
+    str = xfconf_channel_get_string (channel, INACTIVITY_SLEEP_MODE, "suspend");
+    if ( xfpm_strequal (str, "suspend") )
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (inact_suspend), TRUE);
+    else if ( xfpm_strequal (str, "hibernate"))
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (inact_hibernate), TRUE);
+    else 
+    {
+	g_warning ("Invalid value %s for property %s ", str, INACTIVITY_SLEEP_MODE);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (inact_suspend), TRUE);
+    }
+   
+    g_free (str);
+    
 #ifdef HAVE_DPMS
     sleep_dpms_mode = glade_xml_get_widget (xml, "sleep-dpms-mode");
     suspend_dpms_mode = glade_xml_get_widget (xml, "suspend-dpms-mode");
+    
     g_signal_connect (sleep_dpms_mode, "toggled",
 		      G_CALLBACK(set_dpms_sleep_mode), channel);
     g_signal_connect (suspend_dpms_mode, "toggled",
 		      G_CALLBACK(set_dpms_suspend_mode), channel);
 		      
-    gchar *str = xfconf_channel_get_string (channel, DPMS_SLEEP_MODE, "sleep");
+    str = xfconf_channel_get_string (channel, DPMS_SLEEP_MODE, "sleep");
+    
     if ( xfpm_strequal (str, "sleep" ) )
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(sleep_dpms_mode), TRUE);
     else if ( xfpm_strequal (str, "suspend") )
@@ -1254,7 +1395,7 @@ xfpm_settings_dialog_new (XfconfChannel *channel, gboolean system_laptop,
     xfpm_settings_tree_view (channel, system_laptop);
     
     xfpm_settings_general   (channel, user_privilege, can_suspend, can_hibernate);
-    xfpm_settings_advanced  (channel, system_laptop, user_privilege);
+    xfpm_settings_advanced  (channel, system_laptop, user_privilege, can_suspend, can_hibernate);
     
     if ( id != 0 )
     {
diff --git a/settings/xfpm-settings.glade b/settings/xfpm-settings.glade
index 2f2235a1..326f4219 100644
--- a/settings/xfpm-settings.glade
+++ b/settings/xfpm-settings.glade
@@ -295,6 +295,7 @@
                                 <child>
                                   <widget class="GtkVBox" id="vbox19">
                                     <property name="visible">True</property>
+                                    <property name="spacing">10</property>
                                     <child>
                                       <widget class="GtkHBox" id="hbox17">
                                         <property name="visible">True</property>
@@ -326,7 +327,34 @@
                                       </packing>
                                     </child>
                                     <child>
-                                      <placeholder/>
+                                      <widget class="GtkVBox" id="vbox1">
+                                        <property name="visible">True</property>
+                                        <property name="orientation">vertical</property>
+                                        <child>
+                                          <widget class="GtkLabel" id="label5">
+                                            <property name="visible">True</property>
+                                            <property name="label" translatable="yes">Put the computer to sleep when inactive for:</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="position">0</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <widget class="GtkHScale" id="inactivity-on-ac">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="adjustment">30 30 360 1 10 10</property>
+                                            <property name="digits">0</property>
+                                            <property name="value_pos">bottom</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="position">1</property>
+                                          </packing>
+                                        </child>
+                                      </widget>
+                                      <packing>
+                                        <property name="position">1</property>
+                                      </packing>
                                     </child>
                                   </widget>
                                 </child>
@@ -378,7 +406,7 @@
                                           <widget class="GtkHScale" id="sleep-dpms-on-ac">
                                             <property name="visible">True</property>
                                             <property name="can_focus">True</property>
-                                            <property name="adjustment">10 0 60 1 0 0</property>
+                                            <property name="adjustment">17 0 60 1 0 0</property>
                                             <property name="show_fill_level">True</property>
                                             <property name="digits">0</property>
                                             <property name="value_pos">bottom</property>
@@ -476,12 +504,6 @@
                                         <property name="position">1</property>
                                       </packing>
                                     </child>
-                                    <child>
-                                      <placeholder/>
-                                    </child>
-                                    <child>
-                                      <placeholder/>
-                                    </child>
                                   </widget>
                                 </child>
                               </widget>
@@ -639,6 +661,36 @@
                                             <property name="position">1</property>
                                           </packing>
                                         </child>
+                                        <child>
+                                          <widget class="GtkVBox" id="vbox4">
+                                            <property name="visible">True</property>
+                                            <property name="orientation">vertical</property>
+                                            <child>
+                                              <widget class="GtkLabel" id="label6">
+                                                <property name="visible">True</property>
+                                                <property name="label" translatable="yes">Put the computer to sleep when inactive for:</property>
+                                              </widget>
+                                              <packing>
+                                                <property name="position">0</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <widget class="GtkHScale" id="inactivity-on-battery">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">True</property>
+                                                <property name="adjustment">30 30 360 1 10 10</property>
+                                                <property name="digits">0</property>
+                                                <property name="value_pos">bottom</property>
+                                              </widget>
+                                              <packing>
+                                                <property name="position">1</property>
+                                              </packing>
+                                            </child>
+                                          </widget>
+                                          <packing>
+                                            <property name="position">2</property>
+                                          </packing>
+                                        </child>
                                       </widget>
                                     </child>
                                   </widget>
@@ -787,36 +839,6 @@
                                             <property name="position">1</property>
                                           </packing>
                                         </child>
-                                        <child>
-                                          <widget class="GtkHBox" id="hbox22">
-                                            <property name="visible">True</property>
-                                            <child>
-                                              <placeholder/>
-                                            </child>
-                                            <child>
-                                              <placeholder/>
-                                            </child>
-                                          </widget>
-                                          <packing>
-                                            <property name="expand">False</property>
-                                            <property name="position">2</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <widget class="GtkHBox" id="hbox23">
-                                            <property name="visible">True</property>
-                                            <child>
-                                              <placeholder/>
-                                            </child>
-                                            <child>
-                                              <placeholder/>
-                                            </child>
-                                          </widget>
-                                          <packing>
-                                            <property name="expand">False</property>
-                                            <property name="position">3</property>
-                                          </packing>
-                                        </child>
                                       </widget>
                                     </child>
                                   </widget>
@@ -926,6 +948,62 @@
                                     <property name="position">0</property>
                                   </packing>
                                 </child>
+                                <child>
+                                  <widget class="GtkHBox" id="hbox7">
+                                    <property name="visible">True</property>
+                                    <property name="spacing">10</property>
+                                    <child>
+                                      <widget class="GtkLabel" id="label7">
+                                        <property name="visible">True</property>
+                                        <property name="label" translatable="yes">Set computer inactivity sleep mode:</property>
+                                      </widget>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="position">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkVBox" id="vbox5">
+                                        <property name="visible">True</property>
+                                        <property name="orientation">vertical</property>
+                                        <child>
+                                          <widget class="GtkRadioButton" id="inactivity-suspend">
+                                            <property name="label" translatable="yes">Suspend</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">False</property>
+                                            <property name="active">True</property>
+                                            <property name="draw_indicator">True</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="position">0</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <widget class="GtkRadioButton" id="inactivity-hibernate">
+                                            <property name="label" translatable="yes">Hibernate</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">False</property>
+                                            <property name="active">True</property>
+                                            <property name="draw_indicator">True</property>
+                                            <property name="group">inactivity-suspend</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="position">1</property>
+                                          </packing>
+                                        </child>
+                                      </widget>
+                                      <packing>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                  </widget>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
                                 <child>
                                   <widget class="GtkHBox" id="hbox2">
                                     <property name="visible">True</property>
@@ -955,7 +1033,7 @@
                                   </widget>
                                   <packing>
                                     <property name="expand">False</property>
-                                    <property name="position">1</property>
+                                    <property name="position">2</property>
                                   </packing>
                                 </child>
                                 <child>
@@ -968,7 +1046,7 @@
                                   </widget>
                                   <packing>
                                     <property name="expand">False</property>
-                                    <property name="position">2</property>
+                                    <property name="position">3</property>
                                   </packing>
                                 </child>
                               </widget>
diff --git a/src/xfpm-brightness-hal.c b/src/xfpm-brightness-hal.c
index 62fb3b6e..febbe72d 100644
--- a/src/xfpm-brightness-hal.c
+++ b/src/xfpm-brightness-hal.c
@@ -75,13 +75,6 @@ struct XfpmBrightnessHalPrivate
     
 };
 
-enum
-{
-    TIMEOUT_INPUT = 0,
-    TIMEOUT_ON_AC_ID,
-    TIMEOUT_ON_BATTERY_ID
-};
-
 enum
 {
     BRIGHTNESS_UP,
@@ -316,7 +309,7 @@ xfpm_brightness_hal_alarm_timeout_cb (XfpmIdle *idle, guint id, XfpmBrightnessHa
     if ( brg->priv->inhibited )
 	return;
     
-    id == TIMEOUT_ON_AC_ID ? xfpm_brightness_timeout_on_ac (brg) :
+    id == TIMEOUT_BRIGHTNESS_ON_AC ? xfpm_brightness_timeout_on_ac (brg) :
 			     xfpm_brightness_timeout_on_battery (brg);
 }
 
@@ -349,20 +342,20 @@ xfpm_brightness_hal_set_timeouts (XfpmBrightnessHal *brg )
     
     if ( on_ac == ALARM_DISABLED )
     {
-	xfpm_idle_free_alarm (brg->priv->idle, TIMEOUT_ON_AC_ID );
+	xfpm_idle_free_alarm (brg->priv->idle, TIMEOUT_BRIGHTNESS_ON_AC );
     }
     else
     {
-	xfpm_idle_set_alarm (brg->priv->idle, TIMEOUT_ON_AC_ID, on_ac * 1000);
+	xfpm_idle_set_alarm (brg->priv->idle, TIMEOUT_BRIGHTNESS_ON_AC, on_ac * 1000);
     }
     
     if ( on_battery == ALARM_DISABLED )
     {
-	xfpm_idle_free_alarm (brg->priv->idle, TIMEOUT_ON_BATTERY_ID );
+	xfpm_idle_free_alarm (brg->priv->idle, TIMEOUT_BRIGHTNESS_ON_BATTERY );
     }
     else
     {
-	xfpm_idle_set_alarm (brg->priv->idle, TIMEOUT_ON_BATTERY_ID, on_battery * 1000);
+	xfpm_idle_set_alarm (brg->priv->idle, TIMEOUT_BRIGHTNESS_ON_BATTERY, on_battery * 1000);
     }
     
     xfpm_idle_alarm_reset_all (brg->priv->idle);
diff --git a/src/xfpm-config.h b/src/xfpm-config.h
index 86e01335..ded6ef7a 100644
--- a/src/xfpm-config.h
+++ b/src/xfpm-config.h
@@ -47,6 +47,10 @@ G_BEGIN_DECLS
 #define         HIBERNATE_SWITCH_CFG        "/xfce4-power-manager/hibernate-switch-action"
 #define 	SLEEP_SWITCH_CFG            "/xfce4-power-manager/sleep-switch-action"
 
+#define         ON_AC_INACTIVITY_TIMEOUT    "/xfce4-power-manager/inactivity-on-ac"
+#define         ON_BATTERY_INACTIVITY_TIMEOUT "/xfce4-power-manager/inactivity-on-battery"
+#define         INACTIVITY_SLEEP_MODE       "/xfce4-power-manager/inactivity-sleep-mode"
+
 #define 	GENERAL_NOTIFICATION_CFG    "/xfce4-power-manager/general-notification"
 
 #ifdef HAVE_LIBNOTIFY
diff --git a/src/xfpm-engine.c b/src/xfpm-engine.c
index bb7052f1..6dcecc3e 100644
--- a/src/xfpm-engine.c
+++ b/src/xfpm-engine.c
@@ -49,6 +49,7 @@
 #include "xfpm-inhibit.h"
 #include "xfpm-backlight.h"
 #include "xfpm-shutdown.h"
+#include "xfpm-idle.h"
 #include "xfpm-errors.h"
 #include "xfpm-config.h"
 
@@ -75,6 +76,7 @@ struct XfpmEnginePrivate
     XfpmInhibit 	*inhibit;
     XfpmShutdown        *shutdown;
     XfpmButton          *button;
+    XfpmIdle            *idle;
 #ifdef HAVE_DPMS
     XfpmDpms *dpms;
 #endif
@@ -317,6 +319,58 @@ xfpm_engine_inhibit_changed_cb (XfpmInhibit * inhibit, gboolean inhibited,
     engine->priv->inhibited = inhibited;
 }
 
+static void
+xfpm_engine_set_inactivity_timeouts (XfpmEngine *engine)
+{
+    guint on_ac, on_battery;
+    
+    on_ac = xfpm_xfconf_get_property_int (engine->priv->conf, ON_AC_INACTIVITY_TIMEOUT );
+    on_battery = xfpm_xfconf_get_property_int (engine->priv->conf, ON_BATTERY_INACTIVITY_TIMEOUT );
+    
+    TRACE ("timeouts on_ac=%d on_battery=%d", on_ac, on_battery);
+    
+    if ( on_ac == 30 )
+    {
+	xfpm_idle_free_alarm (engine->priv->idle, TIMEOUT_INACTIVITY_ON_AC );
+    }
+    else
+    {
+	xfpm_idle_set_alarm (engine->priv->idle, TIMEOUT_INACTIVITY_ON_AC, on_ac * 1000 * 60);
+    }
+    
+    if ( on_battery == 30 )
+    {
+	xfpm_idle_free_alarm (engine->priv->idle, TIMEOUT_INACTIVITY_ON_BATTERY );
+    }
+    else
+    {
+	xfpm_idle_set_alarm (engine->priv->idle, TIMEOUT_INACTIVITY_ON_BATTERY, on_battery * 1000 * 60);
+    }
+}
+
+static void
+xfpm_engine_alarm_timeout_cb (XfpmIdle *idle, guint id, XfpmEngine *engine)
+{
+    TRACE ("Alarm inactivity timeout id %d", id);
+    gboolean sleep_mode;
+    
+    sleep_mode = xfpm_xfconf_get_property_bool (engine->priv->conf, INACTIVITY_SLEEP_MODE);
+
+    if ( id == TIMEOUT_INACTIVITY_ON_AC && engine->priv->on_battery == FALSE )
+	xfpm_engine_shutdown_request (engine, sleep_mode == TRUE ? XFPM_DO_SUSPEND : XFPM_DO_HIBERNATE, FALSE);
+    else if ( id ==  TIMEOUT_INACTIVITY_ON_BATTERY && engine->priv->is_laptop && engine->priv->on_battery  )
+	xfpm_engine_shutdown_request (engine, sleep_mode == TRUE ? XFPM_DO_SUSPEND : XFPM_DO_HIBERNATE, FALSE);
+    
+}
+
+static void
+xfpm_engine_inactivity_timeout_changed_cb (XfpmXfconf *conf, XfpmEngine *engine)
+{
+    TRACE ("Timeouts alarm changed");
+    
+    xfpm_engine_set_inactivity_timeouts (engine);
+}
+
 static void
 xfpm_engine_class_init (XfpmEngineClass * klass)
 {
@@ -375,6 +429,16 @@ xfpm_engine_init (XfpmEngine * engine)
 		      G_CALLBACK (xfpm_engine_adapter_changed_cb), engine);
 
     xfpm_engine_load_all (engine);
+    
+    engine->priv->idle    = xfpm_idle_new ();
+
+    g_signal_connect (engine->priv->idle, "alarm-timeout",
+		      G_CALLBACK (xfpm_engine_alarm_timeout_cb), engine);
+		      
+    g_signal_connect (engine->priv->conf, "inactivity-timeout-changed",
+		      G_CALLBACK (xfpm_engine_inactivity_timeout_changed_cb), engine);
+		    
+    xfpm_engine_set_inactivity_timeouts (engine);
 }
 
 static void
@@ -389,6 +453,8 @@ xfpm_engine_finalize (GObject * object)
     g_object_unref (engine->priv->supply);
     
     g_object_unref (engine->priv->button);
+    
+    g_object_unref (engine->priv->idle);
 
 #ifdef HAVE_DPMS
     if (engine->priv->dpms)
diff --git a/src/xfpm-idle.h b/src/xfpm-idle.h
index 46db1315..e7a3dd5b 100644
--- a/src/xfpm-idle.h
+++ b/src/xfpm-idle.h
@@ -29,6 +29,15 @@ G_BEGIN_DECLS
 #define XFPM_IDLE(o)          (G_TYPE_CHECK_INSTANCE_CAST((o), XFPM_TYPE_IDLE, XfpmIdle))
 #define XFPM_IS_IDLE(o)       (G_TYPE_CHECK_INSTANCE_TYPE((o), XFPM_TYPE_IDLE))
 
+enum
+{
+    TIMEOUT_INPUT = 0,
+    TIMEOUT_BRIGHTNESS_ON_AC,
+    TIMEOUT_BRIGHTNESS_ON_BATTERY,
+    TIMEOUT_INACTIVITY_ON_AC,
+    TIMEOUT_INACTIVITY_ON_BATTERY
+};
+
 typedef struct XfpmIdlePrivate XfpmIdlePrivate;
 
 typedef struct
diff --git a/src/xfpm-xfconf.c b/src/xfpm-xfconf.c
index 554eab29..619addb5 100644
--- a/src/xfpm-xfconf.c
+++ b/src/xfpm-xfconf.c
@@ -77,6 +77,10 @@ struct XfpmXfconfPrivate
     XfpmShowIcon     	 show_icon;
     guint                critical_level;
     gboolean             general_notification;
+    
+    guint              	 inactivity_on_ac;
+    guint                inactivity_on_battery;
+    gboolean             sleep_inactivity; /* TRUE = suspend FALSE = hibernate*/
 };
 
 enum
@@ -85,6 +89,7 @@ enum
     POWER_SAVE_SETTINGS_CHANGED,
     BRIGHTNESS_SETTINGS_CHANGED,
     TRAY_ICON_SETTINGS_CHANGED,
+    INACTIVITY_TIMEOUT_CHANGED,
     LAST_SIGNAL
 };
 
@@ -273,6 +278,46 @@ xfpm_xfconf_property_changed_cb (XfconfChannel *channel, gchar *property,
 	else 
 	    conf->priv->critical_level = val;
     }
+    else if ( xfpm_strequal (property, ON_AC_INACTIVITY_TIMEOUT ) )
+    {
+	val = g_value_get_uint (value);
+	conf->priv->inactivity_on_ac = val;
+	if ( G_UNLIKELY (conf->priv->inactivity_on_ac < 30 ) )
+	{
+	    g_print ("Invalid value for property %s", ON_AC_INACTIVITY_TIMEOUT);
+	    conf->priv->inactivity_on_ac = 30;
+	}
+	g_signal_emit (G_OBJECT (conf), signals [INACTIVITY_TIMEOUT_CHANGED], 0);
+    }
+    else if ( xfpm_strequal (property, ON_BATTERY_INACTIVITY_TIMEOUT ) )
+    {
+	val = g_value_get_uint (value);
+	conf->priv->inactivity_on_battery = val;
+	if ( G_UNLIKELY (conf->priv->inactivity_on_battery < 30 ) )
+	{
+	    g_print ("Invalid value for property %s", ON_BATTERY_INACTIVITY_TIMEOUT);
+	    conf->priv->inactivity_on_battery = 30;
+	}
+	g_signal_emit (G_OBJECT (conf), signals [INACTIVITY_TIMEOUT_CHANGED], 0);
+    }
+    else if ( xfpm_strequal (property, INACTIVITY_SLEEP_MODE ) )
+    {
+	str = g_value_get_string (value);
+	
+	if ( xfpm_strequal (str, "Suspend"))
+	{
+	    conf->priv->sleep_inactivity = TRUE;
+	}
+	else if ( xfpm_strequal (str, "Hibernate") )
+	{
+	    conf->priv->sleep_inactivity = FALSE;
+	}
+	else
+	{
+	    g_critical("Invalid value %s for property %s\n", str, INACTIVITY_SLEEP_MODE);
+	    conf->priv->sleep_inactivity = TRUE;
+	}
+    }
 }
 
 static void
@@ -425,6 +470,36 @@ xfpm_xfconf_load_configuration (XfpmXfconf *conf)
 	g_warning ("Value %d for property %s is out of range \n", conf->priv->critical_level, CRITICAL_POWER_LEVEL);
 	conf->priv->critical_level = 10;
     }
+    
+    conf->priv->inactivity_on_ac =
+	xfconf_channel_get_uint (conf->priv->channel, ON_AC_INACTIVITY_TIMEOUT, 30);
+    if ( G_UNLIKELY (conf->priv->inactivity_on_ac < 30 ) )
+    {
+	conf->priv->inactivity_on_ac = 30;
+    }
+    
+    conf->priv->inactivity_on_battery =
+	xfconf_channel_get_uint (conf->priv->channel, ON_BATTERY_INACTIVITY_TIMEOUT, 30);
+    if ( G_UNLIKELY (conf->priv->inactivity_on_battery < 30) )
+    {
+	conf->priv->inactivity_on_battery = 30;
+    }
+    
+    str = xfconf_channel_get_string (conf->priv->channel, INACTIVITY_SLEEP_MODE, "Suspend");
+
+    if ( xfpm_strequal (str, "Suspend"))
+    {
+	conf->priv->sleep_inactivity = TRUE;
+    }
+    else if ( xfpm_strequal (str, "Hibernate") )
+    {
+	conf->priv->sleep_inactivity = FALSE;
+    }
+    else
+    {
+	g_critical("Invalid value %s for property %s\n", str, INACTIVITY_SLEEP_MODE);
+	conf->priv->sleep_inactivity = TRUE;
+    }
 }
 
 static void
@@ -467,8 +542,18 @@ xfpm_xfconf_class_init (XfpmXfconfClass *klass)
 			 NULL, NULL,
 			 g_cclosure_marshal_VOID__VOID,
 			 G_TYPE_NONE, 0, G_TYPE_NONE);
+			 
+     signals[INACTIVITY_TIMEOUT_CHANGED] =
+	    g_signal_new("inactivity-timeout-changed",
+			 XFPM_TYPE_XFCONF,
+			 G_SIGNAL_RUN_LAST,
+			 G_STRUCT_OFFSET(XfpmXfconfClass, inactivity_timeout_changed),
+			 NULL, NULL,
+			 g_cclosure_marshal_VOID__VOID,
+			 G_TYPE_NONE, 0, G_TYPE_NONE);
     
     object_class->finalize = xfpm_xfconf_finalize;
+    
     g_type_class_add_private (klass, sizeof(XfpmXfconfPrivate));
 }
 
@@ -486,7 +571,6 @@ xfpm_xfconf_init (XfpmXfconf *conf)
     }	
     else
     {
-    
 	conf->priv->channel = xfconf_channel_new ("xfce4-power-manager");
 
 	g_signal_connect (conf->priv->channel, "property-changed",
@@ -540,6 +624,8 @@ gboolean xfpm_xfconf_get_property_bool (XfpmXfconf *conf, const gchar *property)
     else if ( xfpm_strequal (property, DPMS_ENABLED_CFG) )
 	return conf->priv->dpms_enabled;
 #endif /* HAVE_DPMS */
+    else if ( xfpm_strequal (property, INACTIVITY_SLEEP_MODE) )
+	return conf->priv->sleep_inactivity;
     
     g_warn_if_reached ();
 
@@ -590,6 +676,10 @@ gint xfpm_xfconf_get_property_int (XfpmXfconf *conf, const gchar *property)
 	return conf->priv->brightness_on_battery_timeout;
     else if ( xfpm_strequal (property, CRITICAL_POWER_LEVEL) )
 	return conf->priv->critical_level;
+    else if ( xfpm_strequal (property, ON_AC_INACTIVITY_TIMEOUT ) )
+	return conf->priv->inactivity_on_ac;
+    else if ( xfpm_strequal (property, ON_BATTERY_INACTIVITY_TIMEOUT ) )
+	return conf->priv->inactivity_on_battery;
 
     g_warn_if_reached ();
 
diff --git a/src/xfpm-xfconf.h b/src/xfpm-xfconf.h
index 2fdd4877..9055fc5e 100644
--- a/src/xfpm-xfconf.h
+++ b/src/xfpm-xfconf.h
@@ -53,6 +53,8 @@ typedef struct
     
     void                 (*tray_icon_settings_changed)          (XfpmXfconf *conf);
     
+    void                 (*inactivity_timeout_changed)		(XfpmXfconf *conf);
+    
 } XfpmXfconfClass;
 
 GType        		  xfpm_xfconf_get_type           	(void) G_GNUC_CONST;
-- 
GitLab