From 7d15171a30aacf3dfc47ba2ccafeed8c9553419e Mon Sep 17 00:00:00 2001
From: ali <ali@ali-xfce.org>
Date: Tue, 25 Aug 2009 20:13:22 +0000
Subject: [PATCH] Attempt to reduce memory usage

---
 INSTALL                      |  17 ++-
 Makefile.am                  | 227 +++++++++++++++++++++++++++--------
 NEWS                         |   1 +
 libxfpm/hal-battery.c        | 207 +++++++++++++++-----------------
 src/xfpm-brightness-widget.c | 196 +++++++++++++++++++-----------
 src/xfpm-supply.c            |  45 +++++--
 6 files changed, 448 insertions(+), 245 deletions(-)

diff --git a/INSTALL b/INSTALL
index 8b82ade0..2550dab7 100644
--- a/INSTALL
+++ b/INSTALL
@@ -2,7 +2,7 @@ Installation Instructions
 *************************
 
 Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006, 2007, 2008 Free Software Foundation, Inc.
+2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    This file is free documentation; the Free Software Foundation gives
 unlimited permission to copy, distribute and modify it.
@@ -159,7 +159,7 @@ Particular systems
 CC is not installed, it is recommended to use the following options in
 order to use an ANSI C compiler:
 
-     ./configure CC="cc -Ae"
+     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
 
 and if that doesn't work, install pre-built binaries of GCC for HP-UX.
 
@@ -174,6 +174,16 @@ and if that doesn't work, try
 
      ./configure CC="cc -nodtk"
 
+   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'.  So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+   On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'.  It is recommended to use the following options:
+
+     ./configure --prefix=/boot/common
+
 Specifying the System Type
 ==========================
 
@@ -189,7 +199,8 @@ type, such as `sun4', or a canonical name which has the form:
 
 where SYSTEM can have one of these forms:
 
-     OS KERNEL-OS
+     OS
+     KERNEL-OS
 
    See the file `config.sub' for the possible values of each field.  If
 `config.sub' isn't included in this package, then this package doesn't
diff --git a/Makefile.am b/Makefile.am
index fa225bb6..04dc4490 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,52 +1,181 @@
-@SET_MAKE@
+bin_PROGRAMS = xfce4-power-manager
+
+xfce4_power_manager_SOURCES = 			\
+	xfpm-enum-types.c			\
+	xfpm-enum-types.h			\
+	xfpm-marshal.c				\
+	xfpm-marshal.h				\
+	org.freedesktop.PowerManagement.h	\
+	org.freedesktop.PowerManagement.Inhibit.h\
+	org.freedesktop.PowerManagement.Backlight.h\
+	xfce-power-manager-dbus-server.h	\
+	xfce-power-manager-dbus-client.h	\
+	xfpm-main.c				\
+	xfpm-manager.c				\
+	xfpm-manager.h				\
+	xfpm-engine.c				\
+	xfpm-engine.h				\
+	xfpm-session.c				\
+	xfpm-session.h				\
+	xfpm-xfconf.c				\
+	xfpm-xfconf.h				\
+	xfpm-supply.c				\
+	xfpm-supply.h				\
+	xfpm-adapter.c				\
+	xfpm-adapter.h				\
+	xfpm-battery.c				\
+	xfpm-battery.h				\
+	xfpm-battery-info.c			\
+	xfpm-battery-info.h			\
+	xfpm-dpms.c				\
+	xfpm-dpms.h				\
+	xfpm-cpu.c				\
+	xfpm-cpu.h				\
+	xfpm-button.c				\
+	xfpm-button.h				\
+	xfpm-button-xf86.c			\
+	xfpm-button-xf86.h			\
+	xfpm-button-hal.c			\
+	xfpm-button-hal.h			\
+	xfpm-backlight.c			\
+	xfpm-backlight.h			\
+	xfpm-brightness-hal.c			\
+	xfpm-brightness-hal.h			\
+	xfpm-brightness-widget.c		\
+	xfpm-brightness-widget.h		\
+	xfpm-idle.c				\
+	xfpm-idle.h				\
+	xfpm-inhibit.c				\
+	xfpm-inhibit.h				\
+	xfpm-screen-saver.c			\
+	xfpm-screen-saver.h			\
+	xfpm-dbus-monitor.c			\
+	xfpm-dbus-monitor.h			\
+	xfpm-tray-icon.c			\
+	xfpm-tray-icon.h			\
+	xfpm-shutdown.c				\
+	xfpm-shutdown.h				\
+	xfpm-network-manager.c			\
+	xfpm-network-manager.h			\
+	xfpm-errors.c				\
+	xfpm-errors.h				\
+	xfpm-config.h				\
+	xfpm-enum.h				\
+	xfpm-debug.c				\
+	xfpm-debug.h
+
+
+xfce4_power_manager_CFLAGS =			\
+	-I$(top_srcdir)				\
+	-I$(top_srcdir)/libxfpm			\
+	-DLOCALEDIR=\"$(localedir)\"		\
+	-DG_LOG_DOMAIN=\"xfce4-power-manager\" 	\
+	$(GTK_CFLAGS)				\
+	$(GLIB_CFLAGS)				\
+	$(GOBJECT_CFLAGS)			\
+	$(GTHREAD_CFLAGS)			\
+	$(DBUS_CFLAGS)				\
+	$(DBUS_GLIB_CFLAGS)			\
+	$(LIBXFCE4GUI_CFLAGS)			\
+	$(LIBXFCE4UTIL_CFLAGS)			\
+	$(XFCONF_CFLAGS)			\
+	$(LIBNOTIFY_CFLAGS)			\
+	$(DPMS_CFLAGS)              	
+
+xfce4_power_manager_LDADD   =			\
+	$(top_builddir)/libxfpm/libxfpmhal.la	\
+	$(top_builddir)/libxfpm/libxfpmhalpower.la\
+	$(top_builddir)/libxfpm/libxfpmcommon.la\
+	$(GTK_LIBS)				\
+	$(GLIB_LIBS)				\
+	$(GOBJECT_LIBS)				\
+	$(GTHREAD_LIBS)				\
+	$(DBUS_LIBS)				\
+	$(DBUS_GLIB_LIBS)			\
+	$(LIBXFCE4GUI_LIBS)			\
+	$(LIBXFCE4UTIL_LIBS)			\
+	$(XFCONF_LIBS)				\
+	$(LIBNOTIFY_LIBS)			\
+	$(DPMS_LIBS)		
+
+manpagedir = $(mandir)/man1
+
+manpage_DATA = xfce4-power-manager.1
+
+xfpm_glib_headers = 				\
+	$(srcdir)/xfpm-enum-glib.h			
+
+if MAINTAINER_MODE
+
+BUILT_SOURCES = 					\
+	xfce-power-manager-dbus-server.h		\
+	xfce-power-manager-dbus-client.h		\
+	org.freedesktop.PowerManagement.h		\
+	org.freedesktop.PowerManagement.Inhibit.h	\
+	org.freedesktop.PowerManagement.Backlight.h	\
+	xfpm-marshal.c					\
+	xfpm-marshal.h					\
+	xfpm-enum-types.c				\
+	xfpm-enum-types.h
+
+xfpm-enum-types.h: $(xfpm_glib_headers)
+	( cd $(srcdir) && glib-mkenums \
+		--fhead "#ifndef _XFPM_ENUM_TYPES_H\n#define _XFPM_ENUM_TYPES_H\n#include <glib-object.h>\nG_BEGIN_DECLS\n" \
+		--fprod "/* enumerations from \"@filename@\" */\n" \
+		--vhead "GType @enum_name@_get_type (void);\n#define XFPM_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
+		--ftail "G_END_DECLS\n\n#endif /* _XFPM_ENUM_TYPES_H__ */" \
+		$(xfpm_glib_headers) ) >> xgen \
+	&& (cmp -s xgen xfpm-enum-types.h || cp xgen xfpm-enum-types.h ) \
+	&& rm -f xgen xgen~
+
+xfpm-enum-types.c: xfpm-enum-types.h
+	( cd $(srcdir) && glib-mkenums \
+		--fhead "#include <xfpm-enum-types.h>\n" \
+		--fhead "#include \"xfpm-enum-glib.h\"\n\n" \
+		--fprod "\n/* enumerations from \"@filename@\" */\n" \
+		--vhead "GType\n@enum_name@_get_type (void)\n{\n\tstatic GType type = 0;\n\tif (type == 0) {\n\tstatic const G@Type@Value values[] = {"\
+		--vprod "\t{ @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+		--vtail "\t{ 0, NULL, NULL }\n\t};\n\ttype = g_@type@_register_static (\"@EnumName@\", values);\n  }\n\treturn type;\n}\n" \
+		$(xfpm_glib_headers) ) > xgen \
+	&& cp xgen xfpm-enum-types.c  \
+	&& rm -f xgen xgen~
+
+xfpm-marshal.c: xfpm-marshal.list
+	echo "#include \"xfpm-marshal.h\"" > $@ && \
+	glib-genmarshal $< --prefix=_xfpm_marshal --body >> $@
+
+xfpm-marshal.h: xfpm-marshal.list
+	glib-genmarshal $< --prefix=_xfpm_marshal --header > $@
+
+xfce-power-manager-dbus-server.h: $(srcdir)/org.xfce.Power.Manager.xml
+	dbus-binding-tool --mode=glib-server --prefix=xfpm_manager $< >$@
+
+xfce-power-manager-dbus-client.h: $(srcdir)/org.xfce.Power.Manager.xml
+	dbus-binding-tool --mode=glib-client --prefix=xfpm_manager $< >$@
+
+org.freedesktop.PowerManagement.h: $(srcdir)/org.freedesktop.PowerManagement.xml
+	dbus-binding-tool --mode=glib-server --prefix=xfpm_engine $< >$@
+
+org.freedesktop.PowerManagement.Inhibit.h: $(srcdir)/org.freedesktop.PowerManagement.Inhibit.xml
+	dbus-binding-tool --mode=glib-server --prefix=xfpm_inhibit $< >$@
+
+org.freedesktop.PowerManagement.Backlight.h: $(srcdir)/org.freedesktop.PowerManagement.Backlight.xml
+	dbus-binding-tool --mode=glib-server --prefix=xfpm_backlight $< >$@
 
-if BUILD_PANEL_PLUGINS
-plugins_dir = panel-plugins
 endif
 
-SUBDIRS =        	\
-	data		\
-	libxfpm		\
-	src		\
-	settings	\
-	$(plugins_dir)	\
-	po           	\
-	doc
-
-
-EXTRA_DIST = 			\
-	TODO			\
-	intltool-extract.in 	\
-	intltool-merge.in 	\
-	intltool-update.in
-
-DISTCLEANFILES = \
-	intltool-extract \
-	intltool-merge \
-	intltool-update
-
-distclean-local:
-	rm -rf *.cache
-
-rpm: dist
-	rpmbuild -ta $(PACKAGE)-$(VERSION).tar.gz
-	@rm -f $(PACKAGE)-$(VERSION).tar.gz
-
-html: Makefile
-	make -C doc html
-
-dist-bz2: dist
-	zcat $(PACKAGE)-$(VERSION).tar.gz | \
-	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
-
-distcheck-bz2: distcheck
-	zcat $(PACKAGE)-$(VERSION).tar.gz | \
-	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
-         
-snapshot: dist
-	mv $(PACKAGE)-$(VERSION).tar.gz \
-	$(PACKAGE)-$(VERSION)-r@REVISION@.tar.gz
-
-snapshot-bz2: dist-bz2
-	mv $(PACKAGE)-$(VERSION).tar.bz2 \
-	$(PACKAGE)-$(VERSION)-r@REVISION@.tar.bz2         
+@INTLTOOL_DESKTOP_RULE@
+autostartdir = $(sysconfdir)/xdg/autostart
+autostart_in_files = xfce4-power-manager.desktop.in
+autostart_DATA = $(autostart_in_files:.desktop.in=.desktop)
+
+EXTRA_DIST = 					\
+	xfpm-marshal.list			\
+	xfpm-enum-glib.h			\
+	$(autostart_in_files)			\
+	$(manpage_DATA)
+
+DISTCLEANFILES =				\
+	$(BUILT_SOURCES)			\
+	xfce4-power-manager.desktop
+
diff --git a/NEWS b/NEWS
index 0007ae68..b78879ff 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@
 - Don't lock screen on lid event when multiple monitor are connected.
 - Force DPMSModeOff on lid close event if it is not done in Hardware.
 - Fix a crash in set_client_id (bug #5673).
+- Reduce memory usage on some places.
 
 0.8.3.1
 =======
diff --git a/libxfpm/hal-battery.c b/libxfpm/hal-battery.c
index 8753fbaa..5a3734b1 100644
--- a/libxfpm/hal-battery.c
+++ b/libxfpm/hal-battery.c
@@ -43,6 +43,11 @@ static void hal_battery_get_property(GObject *object,
 #define HAL_BATTERY_GET_PRIVATE(o) \
 (G_TYPE_INSTANCE_GET_PRIVATE((o), HAL_TYPE_BATTERY, HalBatteryPrivate))
 
+#define FREE_STR_PROP(str)            		    \
+    if ( str )                                      \
+        g_free (str);                               \
+    str = NULL;
+
 struct HalBatteryPrivate
 {
     /* Properties read-only */
@@ -52,10 +57,6 @@ struct HalBatteryPrivate
     gboolean  is_charging;
     gboolean  is_discharging;
     
-    gchar    *unit;
-    gchar    *technology;
-    gchar    *vendor;
-    gchar    *model;
     guint     percentage;
 
     guint32   current_charge;
@@ -97,6 +98,19 @@ static guint signals[LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE(HalBattery, hal_battery, HAL_TYPE_DEVICE)
 
+static gchar *
+hal_battery_get_info_string (HalBattery *battery, const gchar *key)
+{
+    gchar *val = NULL;
+    
+    if ( hal_device_has_key (HAL_DEVICE (battery), key) )
+    {
+	val = hal_device_get_property_string (HAL_DEVICE(battery), key);
+    }
+    
+    return val;
+}
+
 static void
 hal_battery_class_init(HalBatteryClass *klass)
 {
@@ -231,10 +245,6 @@ hal_battery_init (HalBattery *battery)
     battery->priv->is_charging     = FALSE;
     battery->priv->is_discharging  = FALSE;
 
-    battery->priv->unit            = NULL;
-    battery->priv->vendor          = NULL;
-    battery->priv->technology      = NULL;
-    battery->priv->model           = NULL;
     battery->priv->type            = HAL_DEVICE_TYPE_UNKNOWN;
     
     battery->priv->percentage      = 0;
@@ -245,6 +255,44 @@ hal_battery_init (HalBattery *battery)
     battery->priv->reporting_last_full = 0;
 }
 
+static const gchar * G_GNUC_PURE
+_translate_technology (const gchar *tech)
+{
+    if ( !g_strcmp0 (tech, "lithium-ion") )
+    {
+	return _("Lithium ion");
+    }
+    else if ( !g_strcmp0 (tech, "lead-acid") )
+    {
+	return _("Lead acid");
+    }
+    else if ( !g_strcmp0 (tech, "lithium-polymer") )
+    {
+	return _("Lithium polymer");
+    }
+    else if ( !g_strcmp0 (tech, "nickel-metal-hydride") )
+    {
+	return _("Nickel metal hydride");
+    }
+    
+    return _("Unknown");
+}
+
+static const gchar * G_GNUC_PURE
+_translate_unit (const gchar *unit)
+{
+    if ( !g_strcmp0 (unit, "mWh") )
+    {
+	return _("mWh");
+    }
+    else if ( !g_strcmp0 (unit, "mAh") )
+    {
+	return _("mAh");
+    }
+    
+    return _("Unknown unit");
+}
+
 static void hal_battery_get_property(GObject *object,
 				    guint prop_id,
 				    GValue *value,
@@ -267,18 +315,51 @@ static void hal_battery_get_property(GObject *object,
 	case PROP_IS_DISCHARGING:
 		g_value_set_boolean (value, battery->priv->is_discharging);
 		break;
+		
 	case PROP_UNIT:
-		g_value_set_string (value, battery->priv->unit);
+	{
+		gchar *unit = NULL;
+		gchar *val;
+		val = hal_battery_get_info_string (battery, "battery.reporting.unit");
+		if ( val )
+		{
+		    unit = g_strdup(_translate_unit (val));
+		    g_free (val);
+		}
+		g_value_set_string (value, unit);
 		break;
+	}
 	case PROP_TECHNOLOGY:
-		g_value_set_string (value, battery->priv->technology);
+	{
+		gchar *val;
+		gchar *technology = NULL;
+		val = hal_battery_get_info_string (battery, "battery.technology");
+		if ( val )
+		{
+		    technology = g_strdup (_translate_technology (val));
+		    g_free (val);
+		}
+		
+		g_value_set_string (value, technology);
+		g_free (technology);
 		break;
+	}
 	case PROP_VENDOR:
-		g_value_set_string (value, battery->priv->vendor);
+	{
+		gchar *vendor = NULL;
+		vendor = hal_battery_get_info_string (battery, "battery.vendor");
+		g_value_set_string (value, vendor);
+		g_free (vendor);
 		break;
+	}
 	case PROP_MODEL:
-		g_value_set_string (value, battery->priv->model);
+	{
+		gchar *model = NULL;
+		model = hal_battery_get_info_string (battery, "battery.model");
+		g_value_set_string (value, model);
+		g_free (model);
 		break;
+	}
 	case PROP_PERCENTAGE:
 		g_value_set_uint (value, battery->priv->percentage);
 		break;
@@ -310,18 +391,6 @@ hal_battery_finalize(GObject *object)
 
     battery = HAL_BATTERY(object);
     
-    if ( battery->priv->technology )
-    	g_free (battery->priv->technology);
-	
-    if ( battery->priv->vendor )
-    	g_free (battery->priv->vendor);
-	
-    if ( battery->priv->model )
-    	g_free (battery->priv->model);
-	
-    if ( battery->priv->unit )
-    	g_free (battery->priv->unit);
-
     G_OBJECT_CLASS(hal_battery_parent_class)->finalize(object);
 }
 
@@ -426,7 +495,6 @@ hal_battery_refresh_all (HalBattery *battery)
     else
     	battery->priv->time = 0;
     
-    //FIXME: calculate the percentage if it is not found on HAL
     if ( hal_device_has_key(HAL_DEVICE(battery), "battery.charge_level.percentage") )
      	battery->priv->percentage = 
     		hal_device_get_property_int(HAL_DEVICE(battery), "battery.charge_level.percentage");
@@ -435,93 +503,9 @@ hal_battery_refresh_all (HalBattery *battery)
     if ( hal_device_has_key(HAL_DEVICE(battery), "battery.reporting.last_full") )
      	battery->priv->reporting_last_full = 
     		hal_device_get_property_int(HAL_DEVICE(battery), "battery.reporting.last_full");
-		
-}
 
-static const gchar * G_GNUC_PURE
-_translate_technology (const gchar *tech)
-{
-    if ( !g_strcmp0 (tech, "lithium-ion") )
-    {
-	return _("Lithium ion");
-    }
-    else if ( !g_strcmp0 (tech, "lead-acid") )
-    {
-	return _("Lead acid");
-    }
-    else if ( !g_strcmp0 (tech, "lithium-polymer") )
-    {
-	return _("Lithium polymer");
-    }
-    else if ( !g_strcmp0 (tech, "nickel-metal-hydride") )
-    {
-	return _("Nickel metal hydride");
-    }
-    
-    return _("Unknown");
-}
-
-static const gchar * G_GNUC_PURE
-_translate_unit (const gchar *unit)
-{
-    if ( !g_strcmp0 (unit, "mWh") )
-    {
-	return _("mWh");
-    }
-    else if ( !g_strcmp0 (unit, "mAh") )
-    {
-	return _("mAh");
-    }
-    
-    return _("Unknown unit");
-}
-
-static void
-hal_battery_get_battery_info (HalBattery *battery)
-{
-    if ( hal_device_has_key (HAL_DEVICE(battery), "battery.technology") )
-    {
-	gchar *tech = hal_device_get_property_string (HAL_DEVICE(battery), "battery.technology");
-	if ( tech )
-	{
-	    battery->priv->technology = g_strdup (_translate_technology (tech));
-	    g_free (tech);
-	}
-    }
-    
-    if ( hal_device_has_key (HAL_DEVICE(battery), "battery.vendor") )
-    {
-	gchar *vendor = hal_device_get_property_string (HAL_DEVICE(battery), "battery.vendor");
-	if ( vendor )
-	{
-	    battery->priv->vendor = g_strdup ( vendor);
-	    g_free (vendor);
-	}
-    }
-    
-    if ( hal_device_has_key (HAL_DEVICE(battery), "battery.model") )
-    {
-	gchar *model = hal_device_get_property_string (HAL_DEVICE(battery), "battery.model");
-	if ( model )
-	{
-	    battery->priv->model = g_strdup (model);
-	    g_free (model);
-	}
-    }
-    
     battery->priv->reporting_design = hal_device_get_property_int (HAL_DEVICE(battery), 
-							                   "battery.reporting.design");
-							      
-    if ( hal_device_has_key (HAL_DEVICE(battery), "battery.reporting.unit") )
-    {
-	gchar *unit = hal_device_get_property_string (HAL_DEVICE(battery), "battery.reporting.unit");
-	
-	if ( unit )
-	{
-	    battery->priv->unit = g_strdup(_translate_unit(unit));
-	    g_free(unit);	    
-	}
-    }
+								   "battery.reporting.design");
 }
 
 static void
@@ -537,10 +521,8 @@ hal_battery_battery_changed_cb (HalBattery *battery, const gchar *key)
 	hal_battery_refresh_all (battery);
     	g_signal_emit (G_OBJECT (battery), signals[BATTERY_CHANGED], 0);
     }
-    
 }
 
-
 static void
 hal_battery_property_modified_cb(HalBattery *battery, 
 			         const gchar *udi,
@@ -563,7 +545,6 @@ hal_battery_new (const gchar *udi)
     battery->priv->type = hal_battery_get_device_type (battery);
    
     hal_battery_refresh_all (battery);
-    hal_battery_get_battery_info (battery);
 	
     hal_device_watch (HAL_DEVICE(battery));
     
diff --git a/src/xfpm-brightness-widget.c b/src/xfpm-brightness-widget.c
index dc6d49ff..6f902407 100644
--- a/src/xfpm-brightness-widget.c
+++ b/src/xfpm-brightness-widget.c
@@ -57,6 +57,7 @@ struct XfpmBrightnessWidgetPrivate
     guint      		 level;
     guint      		 max_level;
     gulong     		 timeout_id;
+    gulong		 destroy_id;
     
     gboolean		 check_server_caps;
     gboolean		 notify_osd;
@@ -144,40 +145,16 @@ xfpm_brightness_widget_timeout (XfpmBrightnessWidget *widget)
 }
 
 static void
-xfpm_brightness_widget_class_init (XfpmBrightnessWidgetClass *klass)
-{
-    GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-    object_class->finalize = xfpm_brightness_widget_finalize;
-    
-    g_type_class_add_private (klass, sizeof (XfpmBrightnessWidgetPrivate));
-}
-
-static void
-xfpm_brightness_widget_init (XfpmBrightnessWidget *widget)
+xfpm_brightness_widget_create_popup (XfpmBrightnessWidget *widget)
 {
     GtkWidget *vbox;
     GtkWidget *img;
     GtkWidget *align;
+    GtkObject *adj;
     
-    widget->priv = XFPM_BRIGHTNESS_WIDGET_GET_PRIVATE (widget);
-    
-    widget->priv->monitor = xfpm_dbus_monitor_new ();
-    
-    widget->priv->level  = 0;
-    widget->priv->max_level = 0;
-    widget->priv->timeout_id = 0;
-    widget->priv->notify_osd = FALSE;
-    widget->priv->check_server_caps = TRUE;
-    
-    xfpm_dbus_monitor_add_service (widget->priv->monitor, 
-				   DBUS_BUS_SESSION,
-				   "org.freedesktop.Notifications");
-    
-    widget->priv->sig_1 = g_signal_connect (widget->priv->monitor, "service-connection-changed",
-					    G_CALLBACK (xfpm_brightness_widget_service_connection_changed_cb),
-					    widget);
-    
+    if ( widget->priv->window != NULL )
+	return;
+	
     widget->priv->window = gtk_window_new (GTK_WINDOW_POPUP);
 
     g_object_set (G_OBJECT (widget->priv->window), 
@@ -204,15 +181,86 @@ xfpm_brightness_widget_init (XfpmBrightnessWidget *widget)
     
     widget->priv->progress_bar = gtk_progress_bar_new ();
     
+    adj = gtk_adjustment_new (0., 0., widget->priv->max_level, 1., 0., 0.);
+
+    g_object_set (G_OBJECT (widget->priv->progress_bar),
+		  "adjustment", adj,
+		  NULL);
+    
     gtk_box_pack_start (GTK_BOX (vbox), widget->priv->progress_bar, TRUE, TRUE, 0);
     
     gtk_widget_show_all (align);
+}
+
+static void
+xfpm_brightness_widget_create_notification (XfpmBrightnessWidget *widget)
+{
+    if ( widget->priv->n == NULL )
+    {
+	widget->priv->n = notify_notification_new (" ",
+						   "",
+					           NULL,
+					           NULL);
+    }
+}
+
+static gboolean
+xfpm_brightness_widget_destroy (gpointer data)
+{
+    XfpmBrightnessWidget *widget;
+    
+    widget = XFPM_BRIGHTNESS_WIDGET (data);
+    
+    if ( widget->priv->window )
+    {
+	gtk_widget_destroy (widget->priv->window);
+	widget->priv->window = NULL;
+    }
+    
+    
+    if ( widget->priv->n )
+    {
+	g_object_unref (widget->priv->n);
+	widget->priv->n = NULL;
+    }
+    
+    return FALSE;
+}
+
+static void
+xfpm_brightness_widget_class_init (XfpmBrightnessWidgetClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    object_class->finalize = xfpm_brightness_widget_finalize;
     
-    widget->priv->n = notify_notification_new (" ",
-					       "",
-					       NULL,
-					       NULL);
-					       
+    g_type_class_add_private (klass, sizeof (XfpmBrightnessWidgetPrivate));
+}
+
+static void
+xfpm_brightness_widget_init (XfpmBrightnessWidget *widget)
+{
+    widget->priv = XFPM_BRIGHTNESS_WIDGET_GET_PRIVATE (widget);
+    
+    widget->priv->monitor = xfpm_dbus_monitor_new ();
+    
+    widget->priv->level  = 0;
+    widget->priv->max_level = 0;
+    widget->priv->timeout_id = 0;
+    widget->priv->destroy_id = 0;
+    widget->priv->notify_osd = FALSE;
+    widget->priv->check_server_caps = TRUE;
+    widget->priv->window = NULL;
+    widget->priv->progress_bar = NULL;
+    widget->priv->n = NULL;
+    
+    xfpm_dbus_monitor_add_service (widget->priv->monitor, 
+				   DBUS_BUS_SESSION,
+				   "org.freedesktop.Notifications");
+    
+    widget->priv->sig_1 = g_signal_connect (widget->priv->monitor, "service-connection-changed",
+					    G_CALLBACK (xfpm_brightness_widget_service_connection_changed_cb),
+					    widget);
 }
 
 static void
@@ -225,14 +273,53 @@ xfpm_brightness_widget_finalize (GObject *object)
     if ( g_signal_handler_is_connected (G_OBJECT (widget->priv->monitor), widget->priv->sig_1) )
 	g_signal_handler_disconnect (G_OBJECT (widget->priv->monitor), widget->priv->sig_1);
 	
-    g_object_unref (widget->priv->n);
+    xfpm_brightness_widget_destroy (widget);
+    
     g_object_unref (widget->priv->monitor);
 
-    gtk_widget_destroy (widget->priv->window);
-
     G_OBJECT_CLASS (xfpm_brightness_widget_parent_class)->finalize (object);
 }
 
+static void
+xfpm_brightness_widget_show (XfpmBrightnessWidget *widget)
+{
+    if ( widget->priv->notify_osd )
+    {
+	xfpm_brightness_widget_create_notification (widget);
+	xfpm_brightness_widget_display_notification (widget);
+    }
+    else
+    {
+	GtkAdjustment *adj;
+	
+	xfpm_brightness_widget_create_popup (widget);
+	g_object_get (G_OBJECT (widget->priv->progress_bar),
+		      "adjustment", &adj,
+		      NULL);
+	
+	gtk_adjustment_set_value (adj, widget->priv->level);
+	
+	if ( !GTK_WIDGET_VISIBLE (widget->priv->window))
+	    gtk_window_present (GTK_WINDOW (widget->priv->window));
+	
+	if ( widget->priv->timeout_id != 0 )
+	    g_source_remove (widget->priv->timeout_id);
+	    
+	widget->priv->timeout_id = 
+	    g_timeout_add (900, (GSourceFunc) xfpm_brightness_widget_timeout, widget);
+    }
+    
+    if ( widget->priv->destroy_id != 0 )
+    {
+	g_source_remove (widget->priv->destroy_id);
+	widget->priv->destroy_id = 0;
+    }
+    
+    /* Release the memory after 60 seconds */
+    widget->priv->destroy_id = g_timeout_add_seconds (60, (GSourceFunc) xfpm_brightness_widget_destroy, widget);
+}
+    
+
 XfpmBrightnessWidget *
 xfpm_brightness_widget_new (void)
 {
@@ -244,24 +331,13 @@ xfpm_brightness_widget_new (void)
 
 void xfpm_brightness_widget_set_max_level (XfpmBrightnessWidget *widget, guint level)
 {
-    GtkObject *adj;
-    
     g_return_if_fail (XFPM_IS_BRIGHTNESS_WIDGET (widget));
 
-    adj = gtk_adjustment_new (0., 0., level, 1., 0., 0.);
-
     widget->priv->max_level = level;
-    
-    g_object_set (G_OBJECT (widget->priv->progress_bar),
-		  "adjustment", adj,
-		  NULL);
-    
 }
 
 void xfpm_brightness_widget_set_level (XfpmBrightnessWidget *widget, guint level)
 {
-    GtkAdjustment *adj;
-    
     g_return_if_fail (XFPM_IS_BRIGHTNESS_WIDGET (widget));
     
     widget->priv->level = level;
@@ -271,26 +347,6 @@ void xfpm_brightness_widget_set_level (XfpmBrightnessWidget *widget, guint level
 	widget->priv->notify_osd = xfpm_brightness_widget_server_is_notify_osd ();
 	widget->priv->check_server_caps = FALSE;
     }
-	
-    if ( widget->priv->notify_osd )
-    {
-	xfpm_brightness_widget_display_notification (widget);
-    }
-    else
-    {
-	g_object_get (G_OBJECT (widget->priv->progress_bar),
-		      "adjustment", &adj,
-		      NULL);
-	
-	gtk_adjustment_set_value (adj, level);
-	
-	if ( !GTK_WIDGET_VISIBLE (widget->priv->window))
-	    gtk_window_present (GTK_WINDOW (widget->priv->window));
-	
-	if ( widget->priv->timeout_id != 0 )
-	    g_source_remove (widget->priv->timeout_id);
-	    
-	widget->priv->timeout_id = 
-	    g_timeout_add (900, (GSourceFunc) xfpm_brightness_widget_timeout, widget);
-    }
+    
+    xfpm_brightness_widget_show (widget);
 }
diff --git a/src/xfpm-supply.c b/src/xfpm-supply.c
index d33a0df0..4b2c5a6f 100644
--- a/src/xfpm-supply.c
+++ b/src/xfpm-supply.c
@@ -50,6 +50,7 @@
 
 static void xfpm_supply_finalize   (GObject *object);
 static void xfpm_supply_refresh_tray_icon (XfpmSupply *supply);
+static void xfpm_supply_hide_adapter_icon (XfpmSupply *supply);
 
 #define XFPM_SUPPLY_GET_PRIVATE(o) \
 (G_TYPE_INSTANCE_GET_PRIVATE((o), XFPM_TYPE_SUPPLY, XfpmSupplyPrivate))
@@ -172,15 +173,11 @@ xfpm_supply_init (XfpmSupply *supply)
     supply->priv->power   = hal_power_new      ();
     supply->priv->notify  = xfpm_notify_new    ();
     supply->priv->conf    = xfpm_xfconf_new    ();
-    supply->priv->tray    = xfpm_tray_icon_new ();
+    supply->priv->tray    = NULL;
     supply->priv->inhibit = xfpm_inhibit_new   ();
     supply->priv->inhibited = FALSE;
     supply->priv->low_power = FALSE;
     
-    xfpm_tray_icon_set_visible (supply->priv->tray, FALSE);
-    xfpm_tray_icon_set_icon (supply->priv->tray, "xfpm-ac-adapter");
-    xfpm_tray_icon_set_show_info_menu (supply->priv->tray, FALSE);
-    
     g_signal_connect (supply->priv->inhibit, "has-inhibit-changed",
 		      G_CALLBACK (xfpm_supply_has_inhibit_changed_cb), supply);
 			  
@@ -204,13 +201,41 @@ xfpm_supply_finalize (GObject *object)
 	
     g_object_unref (supply->priv->adapter);
     
-    g_object_unref (supply->priv->tray);
-    
     g_object_unref (supply->priv->inhibit);
+    xfpm_supply_hide_adapter_icon (supply);
 	
     G_OBJECT_CLASS(xfpm_supply_parent_class)->finalize(object);
 }
 
+static void
+xfpm_supply_hide_adapter_icon (XfpmSupply *supply)
+{
+    if ( supply->priv->tray )
+    {
+	g_object_unref (supply->priv->tray);
+	supply->priv->tray = NULL;
+    }
+}
+
+static void
+xfpm_supply_show_tray_icon (XfpmSupply *supply)
+{
+#ifdef DEBUG 
+    /* This shouldn't happen at all*/
+    if ( supply->priv->tray )
+    {
+	g_critical ("Already have tray icon for adapter!");
+	xfpm_supply_hide_adapter_icon (supply);
+    }
+#endif    
+
+    supply->priv->tray = xfpm_tray_icon_new ();
+    
+    xfpm_tray_icon_set_visible (supply->priv->tray, FALSE);
+    xfpm_tray_icon_set_icon (supply->priv->tray, "xfpm-ac-adapter");
+    xfpm_tray_icon_set_show_info_menu (supply->priv->tray, FALSE);
+}
+
 static void
 xfpm_supply_refresh_tray_icon (XfpmSupply *supply)
 {
@@ -226,20 +251,20 @@ xfpm_supply_refresh_tray_icon (XfpmSupply *supply)
     {
 	if ( g_hash_table_size (supply->priv->hash) == 0 )
 	{
+	    xfpm_supply_show_tray_icon (supply);
 	    xfpm_tray_icon_set_tooltip (supply->priv->tray,
 					supply->priv->adapter_present ? 
 					(_("Adapter present")) :
 					(_("Adapter not present")) );
-	    xfpm_tray_icon_set_visible (supply->priv->tray, TRUE);
 	}
 	else
 	{
-	    xfpm_tray_icon_set_visible (supply->priv->tray, FALSE);
+	    xfpm_supply_hide_adapter_icon (supply);
 	}
     }
     else
     {
-	xfpm_tray_icon_set_visible (supply->priv->tray, FALSE);
+	xfpm_supply_hide_adapter_icon (supply);
     }
 }
 
-- 
GitLab