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.

Sun, 25 Feb 2007 22:13:58 +0000

author
Daniel Atallah <datallah@pidgin.im>
date
Sun, 25 Feb 2007 22:13:58 +0000
changeset 15770
e0454c66f042
parent 15769
813f36d31f6c
child 15773
dda44491c7f6

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.

pidgin/win32/gtkdocklet-win32.c file | annotate | diff | comparison | revisions
--- 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);
 }

mercurial