changeset 15709:b2b756b59d81

Cache the converted docklet HICONs. Sean noticed that there are actually .ico files in pixmaps/tray/16 (something that I missed). I'm not sure if I should just use those and eliminate the stock pixmap to HICON conversion hackery or if we can just get rid of those and avoid the duplication.
author Daniel Atallah <daniel.atallah@gmail.com>
date Sun, 25 Feb 2007 22:13:58 +0000
parents c50358666110
children a34da2c2d8ba
files pidgin/win32/gtkdocklet-win32.c
diffstat 1 files changed, 23 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/win32/gtkdocklet-win32.c	Sun Feb 25 21:40:40 2007 +0000
+++ b/pidgin/win32/gtkdocklet-win32.c	Sun Feb 25 22:13:58 2007 +0000
@@ -45,8 +45,7 @@
  *  LOCALS
  */
 static HWND systray_hwnd = NULL;
-static const char *prev_icon_name = NULL;
-static HICON prev_hicon = NULL;
+static HICON cached_icons[DOCKLET_STATUS_CONNECTING + 1];
 static GtkWidget *image = NULL;
 static NOTIFYICONDATA _nicon_data;
 
@@ -456,28 +455,11 @@
 }
 
 
-
-static void systray_change_icon(const char *icon_name) {
-	HICON hicon;
-
-	/* Avoid looking up the icon if it hasn't really changed.
-	 * This will happen when re-displaying the icon when blinking.  */
-	if (icon_name == prev_icon_name) {
-		hicon = prev_hicon;
-		prev_hicon = NULL;
-	} else
-		hicon = load_hicon_from_stock(icon_name);
-
+static void systray_change_icon(HICON hicon) {
 	g_return_if_fail(hicon != NULL);
 
 	_nicon_data.hIcon = hicon;
 	Shell_NotifyIcon(NIM_MODIFY, &_nicon_data);
-
-	if (prev_hicon)
-		DestroyIcon(prev_hicon);
-	prev_hicon = hicon;
-	prev_icon_name = icon_name;
-
 }
 
 static void systray_remove_nid(void) {
@@ -485,11 +467,14 @@
 }
 
 static void winpidgin_tray_update_icon(DockletStatus icon) {
-	const gchar *icon_name = NULL;
 
 	g_return_if_fail(image != NULL);
+	g_return_if_fail(icon < (sizeof(cached_icons) / sizeof(HICON)));
 
-	switch (icon) {
+	/* Look up and cache the HICON if we don't already have it */
+	if (cached_icons[icon] == NULL) {
+		const gchar *icon_name = NULL;
+		switch (icon) {
 		case DOCKLET_STATUS_OFFLINE:
 			icon_name = PIDGIN_STOCK_TRAY_OFFLINE;
 			break;
@@ -511,10 +496,14 @@
 		case DOCKLET_STATUS_XA:
 			icon_name = PIDGIN_STOCK_TRAY_XA;
 			break;
+		}
+
+		g_return_if_fail(icon_name != NULL);
+
+		cached_icons[icon] = load_hicon_from_stock(icon_name);
 	}
 
-	if(icon_name)
-		systray_change_icon(icon_name);
+	systray_change_icon(cached_icons[icon]);
 }
 
 static void winpidgin_tray_blank_icon() {
@@ -567,10 +556,17 @@
 }
 
 static void winpidgin_tray_destroy() {
+	int cached_cnt = sizeof(cached_icons) / sizeof(HICON);
 	systray_remove_nid();
 	DestroyWindow(systray_hwnd);
 	pidgin_docklet_remove();
 
+	while (--cached_cnt >= 0) {
+		if (cached_icons[cached_cnt] != NULL)
+			DestroyIcon(cached_icons[cached_cnt]);
+		cached_icons[cached_cnt] = NULL;
+	}
+
 	g_object_unref(image);
 	image = NULL;
 }
@@ -587,5 +583,8 @@
 
 /* Used by docklet's plugin load func */
 void docklet_ui_init() {
+	/* Initialize the cached icons to NULL */
+	ZeroMemory(cached_icons, sizeof(cached_icons));
+
 	pidgin_docklet_set_ui_ops(&winpidgin_tray_ops);
 }