[network-manager-applet] applet: load icons when needed (bgo #609134)



commit aca38ba8c0b94a40bbac8d2b42462492182339cb
Author: Sebastien Bacher <seb128 ubuntu com>
Date:   Tue Feb 23 17:22:59 2010 -0800

    applet: load icons when needed (bgo #609134)
    
    Instead of loading all icons when the applet starts up, load them
    when they are needed.  This helps reduce applet startup time and
    conserves memory.
    
    (major cleanups to this patch by dcbw)

 src/ap-menu-item.c        |   18 +++--
 src/applet-device-bt.c    |    2 +-
 src/applet-device-cdma.c  |    2 +-
 src/applet-device-gsm.c   |    2 +-
 src/applet-device-wifi.c  |   11 ++-
 src/applet-device-wired.c |    2 +-
 src/applet.c              |  182 +++++++++++++++++++++++++--------------------
 src/applet.h              |    6 +-
 8 files changed, 125 insertions(+), 100 deletions(-)
---
diff --git a/src/ap-menu-item.c b/src/ap-menu-item.c
index aee0e7e..94acf55 100644
--- a/src/ap-menu-item.c
+++ b/src/ap-menu-item.c
@@ -146,7 +146,7 @@ nm_network_menu_item_best_strength (NMNetworkMenuItem * item,
                                     guint8 strength,
                                     NMApplet *applet)
 {
-	GdkPixbuf *pixbuf = NULL;
+	GdkPixbuf *icon = NULL, *pixbuf, *top;
 
 	g_return_if_fail (item != NULL);
 	g_return_if_fail (NM_IS_NETWORK_MENU_ITEM (item));
@@ -160,19 +160,21 @@ nm_network_menu_item_best_strength (NMNetworkMenuItem * item,
 	item->int_strength = strength;
 
 	if (strength > 80)
-		pixbuf = gdk_pixbuf_copy (applet->wireless_100_icon);
+		icon = nma_icon_check_and_load ("nm-signal-100", &applet->wireless_100_icon, applet);
 	else if (strength > 55)
-		pixbuf = gdk_pixbuf_copy (applet->wireless_75_icon);
+		icon = nma_icon_check_and_load ("nm-signal-75", &applet->wireless_75_icon, applet);
 	else if (strength > 30)
-		pixbuf = gdk_pixbuf_copy (applet->wireless_50_icon);
+		icon = nma_icon_check_and_load ("nm-signal-50", &applet->wireless_50_icon, applet);
 	else if (strength > 5)
-		pixbuf = gdk_pixbuf_copy (applet->wireless_25_icon);
+		icon = nma_icon_check_and_load ("nm-signal-25", &applet->wireless_25_icon, applet);
 	else
-		pixbuf = gdk_pixbuf_copy (applet->wireless_00_icon);
+		icon = nma_icon_check_and_load ("nm-signal-00", &applet->wireless_00_icon, applet);
 
-	if (item->is_encrypted) {
-		GdkPixbuf *top = applet->secure_lock_icon;
+	pixbuf = gdk_pixbuf_copy (icon);
 
+	/* If the AP is "secure", composite the lock icon on top of the signal bars */
+	if (item->is_encrypted) {
+		top = nma_icon_check_and_load ("nm-secure-lock", &applet->secure_lock_icon, applet);
 		gdk_pixbuf_composite (top, pixbuf, 0, 0, gdk_pixbuf_get_width (top),
 							  gdk_pixbuf_get_height (top),
 							  0, 0, 1.0, 1.0,
diff --git a/src/applet-device-bt.c b/src/applet-device-bt.c
index 52dccf9..29c9a86 100644
--- a/src/applet-device-bt.c
+++ b/src/applet-device-bt.c
@@ -240,7 +240,7 @@ bt_get_icon (NMDevice *device,
 		*tip = g_strdup_printf (_("Requesting a network address for '%s'..."), id);
 		break;
 	case NM_DEVICE_STATE_ACTIVATED:
-		pixbuf = applet->wwan_icon;
+		pixbuf = nma_icon_check_and_load ("nm-device-wwan", &applet->wwan_icon, applet);
 		*tip = g_strdup_printf (_("Mobile broadband connection '%s' active"), id);
 		break;
 	default:
diff --git a/src/applet-device-cdma.c b/src/applet-device-cdma.c
index f0e9141..6a603ca 100644
--- a/src/applet-device-cdma.c
+++ b/src/applet-device-cdma.c
@@ -362,7 +362,7 @@ cdma_get_icon (NMDevice *device,
 		*tip = g_strdup_printf (_("Requesting a network address for '%s'..."), id);
 		break;
 	case NM_DEVICE_STATE_ACTIVATED:
-		pixbuf = applet->wwan_icon;
+		pixbuf = nma_icon_check_and_load ("nm-device-wwan", &applet->wwan_icon, applet);
 		*tip = g_strdup_printf (_("Mobile broadband connection '%s' active"), id);
 		break;
 	default:
diff --git a/src/applet-device-gsm.c b/src/applet-device-gsm.c
index 89f006e..afd231b 100644
--- a/src/applet-device-gsm.c
+++ b/src/applet-device-gsm.c
@@ -355,7 +355,7 @@ gsm_get_icon (NMDevice *device,
 		*tip = g_strdup_printf (_("Requesting a network address for '%s'..."), id);
 		break;
 	case NM_DEVICE_STATE_ACTIVATED:
-		pixbuf = applet->wwan_icon;
+		pixbuf = nma_icon_check_and_load ("nm-device-wwan", &applet->wwan_icon, applet);
 		*tip = g_strdup_printf (_("Mobile broadband connection '%s' active"), id);
 		break;
 	default:
diff --git a/src/applet-device-wifi.c b/src/applet-device-wifi.c
index 48045f2..bc82afd 100644
--- a/src/applet-device-wifi.c
+++ b/src/applet-device-wifi.c
@@ -490,6 +490,7 @@ create_new_ap_item (NMDeviceWifi *device,
 	nm_network_menu_item_set_ssid (item, (GByteArray *) ssid);
 
 	dev_caps = nm_device_wifi_get_capabilities (device);
+	nma_icon_check_and_load ("nm-adhoc", &applet->adhoc_icon, applet);
 	nm_network_menu_item_set_detail (item, ap, applet->adhoc_icon, dev_caps);
 	nm_network_menu_item_best_strength (item, nm_access_point_get_strength (ap), applet);
 	nm_network_menu_item_add_dupe (item, ap);
@@ -1270,15 +1271,15 @@ wireless_get_icon (NMDevice *device,
 			strength = CLAMP (strength, 0, 100);
 
 			if (strength > 80)
-				pixbuf = applet->wireless_100_icon;
+				pixbuf = nma_icon_check_and_load ("nm-signal-100", &applet->wireless_100_icon, applet);
 			else if (strength > 55)
-				pixbuf = applet->wireless_75_icon;
+				pixbuf = nma_icon_check_and_load ("nm-signal-75", &applet->wireless_75_icon, applet);
 			else if (strength > 30)
-				pixbuf = applet->wireless_50_icon;
+				pixbuf = nma_icon_check_and_load ("nm-signal-50", &applet->wireless_50_icon, applet);
 			else if (strength > 5)
-				pixbuf = applet->wireless_25_icon;
+				pixbuf = nma_icon_check_and_load ("nm-signal-25", &applet->wireless_25_icon, applet);
 			else
-				pixbuf = applet->wireless_00_icon;
+				pixbuf = nma_icon_check_and_load ("nm-signal-00", &applet->wireless_00_icon, applet);
 
 			*tip = g_strdup_printf (_("Wireless network connection '%s' active: %s (%d%%)"),
 			                        id, ssid, strength);
diff --git a/src/applet-device-wired.c b/src/applet-device-wired.c
index 8bb7760..7f10e57 100644
--- a/src/applet-device-wired.c
+++ b/src/applet-device-wired.c
@@ -310,7 +310,7 @@ wired_get_icon (NMDevice *device,
 		*tip = g_strdup_printf (_("Requesting a wired network address for '%s'..."), id);
 		break;
 	case NM_DEVICE_STATE_ACTIVATED:
-		pixbuf = applet->wired_icon;
+		pixbuf = nma_icon_check_and_load ("nm-device-wired", &applet->wired_icon, applet);
 		*tip = g_strdup_printf (_("Wired network connection '%s' active"), id);
 		break;
 	default:
diff --git a/src/applet.c b/src/applet.c
index 820faaa..075f873 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -1980,6 +1980,7 @@ foo_set_icon (NMApplet *applet, GdkPixbuf *pixbuf, guint32 layer)
 		applet->icon_layers[layer] = g_object_ref (pixbuf);
 
 	if (!applet->icon_layers[0]) {
+		nma_icon_check_and_load ("nm-no-connection", &applet->no_connection_icon, applet);
 		pixbuf = g_object_ref (applet->no_connection_icon);
 	} else {
 		pixbuf = gdk_pixbuf_copy (applet->icon_layers[0]);
@@ -2250,6 +2251,18 @@ applet_common_get_device_icon (NMDeviceState state, NMApplet *applet)
 	}
 
 	if (stage >= 0) {
+		int i, j;
+
+		for (i = 0; i < NUM_CONNECTING_STAGES; i++) {
+			for (j = 0; j < NUM_CONNECTING_FRAMES; j++) {
+				char *name;
+
+				name = g_strdup_printf ("nm-stage%02d-connecting%02d", i+1, j+1);
+				nma_icon_check_and_load (name, &applet->network_connecting_icons[i][j], applet);
+				g_free (name);
+			}
+		}
+
 		pixbuf = applet->network_connecting_icons[stage][applet->animation_step];
 		applet->animation_step++;
 		if (applet->animation_step >= NUM_CONNECTING_FRAMES)
@@ -2410,11 +2423,11 @@ applet_update_icon (gpointer user_data)
 	switch (state) {
 	case NM_STATE_UNKNOWN:
 	case NM_STATE_ASLEEP:
-		pixbuf = applet->no_connection_icon;
+		pixbuf = nma_icon_check_and_load ("nm-no-connection", &applet->no_connection_icon, applet);
 		dev_tip = g_strdup (_("Networking disabled"));
 		break;
 	case NM_STATE_DISCONNECTED:
-		pixbuf = applet->no_connection_icon;
+		pixbuf = nma_icon_check_and_load ("nm-no-connection", &applet->no_connection_icon, applet);
 		dev_tip = g_strdup (_("No network connection"));
 		break;
 	default:
@@ -2428,14 +2441,24 @@ applet_update_icon (gpointer user_data)
 	pixbuf = NULL;
 	active_vpn = applet_get_first_active_vpn_connection (applet, &vpn_state);
 	if (active_vpn) {
+		int i;
+
 		switch (vpn_state) {
 		case NM_VPN_CONNECTION_STATE_ACTIVATED:
-			pixbuf = applet->vpn_lock_icon;
+			pixbuf = nma_icon_check_and_load ("nm-vpn-active-lock", &applet->vpn_lock_icon, applet);
 			break;
 		case NM_VPN_CONNECTION_STATE_PREPARE:
 		case NM_VPN_CONNECTION_STATE_NEED_AUTH:
 		case NM_VPN_CONNECTION_STATE_CONNECT:
 		case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET:
+			for (i = 0; i < NUM_VPN_CONNECTING_FRAMES; i++) {
+				char *name;
+
+				name = g_strdup_printf ("nm-vpn-connecting%02d", i+1);
+				nma_icon_check_and_load (name, &applet->vpn_connecting_icons[i], applet);
+				g_free (name);
+			}
+
 			pixbuf = applet->vpn_connecting_icons[applet->animation_step];
 			applet->animation_step++;
 			if (applet->animation_step >= NUM_VPN_CONNECTING_FRAMES)
@@ -2664,117 +2687,110 @@ periodic_update_active_connection_timestamps (gpointer user_data)
 
 /*****************************************************************************/
 
-#define CLEAR_ICON(x) \
-	if (x) { \
-		g_object_unref (x); \
-		x = NULL; \
+static void
+nma_clear_icon (GdkPixbuf **icon, NMApplet *applet)
+{
+	g_return_if_fail (icon != NULL);
+	g_return_if_fail (applet != NULL);
+
+	if (*icon && (*icon != applet->fallback_icon)) {
+		g_object_unref (*icon);
+		*icon = NULL;
 	}
+}
 
 static void nma_icons_free (NMApplet *applet)
 {
 	int i, j;
 
-	if (!applet->icons_loaded)
-		return;
-
 	for (i = 0; i <= ICON_LAYER_MAX; i++)
-		CLEAR_ICON(applet->icon_layers[i]);
-
-	CLEAR_ICON(applet->no_connection_icon);
-	CLEAR_ICON(applet->wired_icon);
-	CLEAR_ICON(applet->adhoc_icon);
-	CLEAR_ICON(applet->wwan_icon);
-	CLEAR_ICON(applet->vpn_lock_icon);
-	CLEAR_ICON(applet->wireless_00_icon);
-	CLEAR_ICON(applet->wireless_25_icon);
-	CLEAR_ICON(applet->wireless_50_icon);
-	CLEAR_ICON(applet->wireless_75_icon);
-	CLEAR_ICON(applet->wireless_100_icon);
-	CLEAR_ICON(applet->secure_lock_icon);
+		nma_clear_icon (&applet->icon_layers[i], applet);
+
+	nma_clear_icon (&applet->no_connection_icon, applet);
+	nma_clear_icon (&applet->wired_icon, applet);
+	nma_clear_icon (&applet->adhoc_icon, applet);
+	nma_clear_icon (&applet->wwan_icon, applet);
+	nma_clear_icon (&applet->vpn_lock_icon, applet);
+	nma_clear_icon (&applet->wireless_00_icon, applet);
+	nma_clear_icon (&applet->wireless_25_icon, applet);
+	nma_clear_icon (&applet->wireless_50_icon, applet);
+	nma_clear_icon (&applet->wireless_75_icon, applet);
+	nma_clear_icon (&applet->wireless_100_icon, applet);
+	nma_clear_icon (&applet->secure_lock_icon, applet);
 
 	for (i = 0; i < NUM_CONNECTING_STAGES; i++) {
 		for (j = 0; j < NUM_CONNECTING_FRAMES; j++)
-			CLEAR_ICON(applet->network_connecting_icons[i][j]);
+			nma_clear_icon (&applet->network_connecting_icons[i][j], applet);
 	}
 
 	for (i = 0; i < NUM_VPN_CONNECTING_FRAMES; i++)
-		CLEAR_ICON(applet->vpn_connecting_icons[i]);
+		nma_clear_icon (&applet->vpn_connecting_icons[i], applet);
 
 	for (i = 0; i <= ICON_LAYER_MAX; i++)
-		CLEAR_ICON(applet->icon_layers[i]);
-
-	applet->icons_loaded = FALSE;
+		nma_clear_icon (&applet->icon_layers[i], applet);
 }
 
-#define ICON_LOAD(icon, name) \
-	{ \
-		icon = gtk_icon_theme_load_icon (applet->icon_theme, name, applet->icon_size, 0, &err); \
-		if (icon == NULL) { \
-			g_warning ("Icon %s missing: %s", name, \
-			           (err && err->message) ? err->message : "unknown"); \
-			g_clear_error (&err); \
-			goto out; \
-		} \
-	}
-
-static gboolean
-nma_icons_load (NMApplet *applet)
+GdkPixbuf *
+nma_icon_check_and_load (const char *name, GdkPixbuf **icon, NMApplet *applet)
 {
-	int i, j;
-	GError *err = NULL;
-
-	g_return_val_if_fail (!applet->icons_loaded, FALSE);
-	g_return_val_if_fail (applet->icon_size > 0, FALSE);
+	GError *error = NULL;
 
-	ICON_LOAD(applet->no_connection_icon, "nm-no-connection");
-	ICON_LOAD(applet->wired_icon, "nm-device-wired");
-	ICON_LOAD(applet->adhoc_icon, "nm-adhoc");
-	ICON_LOAD(applet->wwan_icon, "nm-device-wwan");
-	ICON_LOAD(applet->vpn_lock_icon, "nm-vpn-active-lock");
+	g_return_val_if_fail (name != NULL, NULL);
+	g_return_val_if_fail (icon != NULL, NULL);
+	g_return_val_if_fail (applet != NULL, NULL);
 
-	ICON_LOAD(applet->wireless_00_icon, "nm-signal-00");
-	ICON_LOAD(applet->wireless_25_icon, "nm-signal-25");
-	ICON_LOAD(applet->wireless_50_icon, "nm-signal-50");
-	ICON_LOAD(applet->wireless_75_icon, "nm-signal-75");
-	ICON_LOAD(applet->wireless_100_icon, "nm-signal-100");
-	ICON_LOAD(applet->secure_lock_icon, "nm-secure-lock");
+	/* icon already loaded successfully */
+	if (*icon && (*icon != applet->fallback_icon))
+		return *icon;
 
-	for (i = 0; i < NUM_CONNECTING_STAGES; i++) {
-		for (j = 0; j < NUM_CONNECTING_FRAMES; j++) {
-			char *name;
+	/* Try to load the icon; if the load fails, log the problem, and set
+	 * the icon to the fallback icon if requested.
+	 */
+	*icon = gtk_icon_theme_load_icon (applet->icon_theme, name, applet->icon_size, 0, &error);
+	if (!*icon) {
+		g_warning ("Icon %s missing: (%d) %s",
+		           name,
+		           error ? error->code : -1,
+			       (error && error->message) ? error->message : "(unknown)");
+		g_clear_error (&error);
 
-			name = g_strdup_printf ("nm-stage%02d-connecting%02d", i+1, j+1);
-			ICON_LOAD(applet->network_connecting_icons[i][j], name);
-			g_free (name);
-		}
+		*icon = applet->fallback_icon;
 	}
+	return *icon;
+}
 
-	for (i = 0; i < NUM_VPN_CONNECTING_FRAMES; i++) {
-		char *name;
+#define FALLBACK_ICON_NAME "gtk-dialog-error"
 
-		name = g_strdup_printf ("nm-vpn-connecting%02d", i+1);
-		ICON_LOAD(applet->vpn_connecting_icons[i], name);
-		g_free (name);
-	}
+static gboolean
+nma_icons_reload (NMApplet *applet)
+{
+	GError *error = NULL;
 
-	applet->icons_loaded = TRUE;
+	g_return_val_if_fail (applet->icon_size > 0, FALSE);
 
-out:
-	if (!applet->icons_loaded) {
-		GtkWidget *dialog;
+	nma_icons_free (applet);
 
-		dialog = applet_warning_dialog_show (_("The NetworkManager applet could not find some required resources.  It cannot continue.\n"));
-		gtk_dialog_run (GTK_DIALOG (dialog));
-		g_main_loop_quit (applet->loop);
+
+	applet->fallback_icon = gtk_icon_theme_load_icon (applet->icon_theme,
+	                                                  FALLBACK_ICON_NAME,
+	                                                  applet->icon_size, 0,
+	                                                  &error);
+	if (!applet->fallback_icon) {
+		g_warning ("Fallback icon '%s' missing: (%d) %s",
+		           FALLBACK_ICON_NAME,
+		           error ? error->code : -1,
+			       (error && error->message) ? error->message : "(unknown)");
+		g_clear_error (&error);
+		/* Die if we can't get even a fallback icon */
+		g_assert (applet->fallback_icon);
 	}
 
-	return applet->icons_loaded;
+	return TRUE;
 }
 
 static void nma_icon_theme_changed (GtkIconTheme *icon_theme, NMApplet *applet)
 {
-	nma_icons_free (applet);
-	nma_icons_load (applet);
+	nma_icons_reload (applet);
 }
 
 static void nma_icons_init (NMApplet *applet)
@@ -2825,8 +2841,7 @@ status_icon_size_changed_cb (GtkStatusIcon *icon,
 	 */
 	applet->icon_size = MAX (16, size);
 
-	nma_icons_free (applet);
-	nma_icons_load (applet);
+	nma_icons_reload (applet);
 
 	applet_schedule_update_icon (applet);
 
@@ -3073,6 +3088,9 @@ static void finalize (GObject *object)
 	if (applet->nm_client)
 		g_object_unref (applet->nm_client);
 
+	if (applet->fallback_icon)
+		g_object_unref (applet->fallback_icon);
+
 	if (applet->gconf_settings) {
 		g_object_unref (applet->gconf_settings);
 		applet->gconf_settings = NULL;
diff --git a/src/applet.h b/src/applet.h
index f24250e..fc2907a 100644
--- a/src/applet.h
+++ b/src/applet.h
@@ -102,7 +102,6 @@ typedef struct
 
 	/* Data model elements */
 	guint			update_icon_id;
-	gboolean		icons_loaded;
 
 	GtkIconTheme *	icon_theme;
 	GdkPixbuf *		no_connection_icon;
@@ -121,6 +120,7 @@ typedef struct
 #define NUM_VPN_CONNECTING_FRAMES 14
 	GdkPixbuf *		vpn_connecting_icons[NUM_VPN_CONNECTING_FRAMES];
 	GdkPixbuf *		vpn_lock_icon;
+	GdkPixbuf *		fallback_icon;
 
 	/* Active status icon pixbufs */
 	GdkPixbuf *		icon_layers[ICON_LAYER_MAX + 1];
@@ -265,4 +265,8 @@ GtkWidget * applet_new_menu_item_helper (NMConnection *connection,
                                          NMConnection *active,
                                          gboolean add_active);
 
+GdkPixbuf * nma_icon_check_and_load (const char *name,
+                                     GdkPixbuf **icon,
+                                     NMApplet *applet);
+
 #endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]