Index: src/kits/tracker/PoseList.h
===================================================================
--- src/kits/tracker/PoseList.h	(revision 21262)
+++ src/kits/tracker/PoseList.h	(working copy)
@@ -64,7 +64,6 @@
 	BPose *DeepFindPose(const node_ref *node, int32 *index = NULL) const;
 		// same as FindPose, node can be a target of the actual
 		// pose if the pose is a symlink
-	BPose *FindVolumePose(const dev_t device, int32 *index = NULL) const;
 };
 
 // iteration glue, add permutations as needed
Index: src/kits/tracker/SettingsViews.cpp
===================================================================
--- src/kits/tracker/SettingsViews.cpp	(revision 21262)
+++ src/kits/tracker/SettingsViews.cpp	(working copy)
@@ -1072,9 +1072,7 @@
 		{
 			settings.SetShowVolumeSpaceBar(fSpaceBarShowCheckBox->Value() == 1);
 			Window()->PostMessage(kSettingsContentsModified);
-			BMessage notificationMessage;
-			notificationMessage.AddBool("ShowVolumeSpaceBar", settings.ShowVolumeSpaceBar());
-			tracker->SendNotices(kShowVolumeSpaceBar, &notificationMessage);
+			tracker->PostMessage(kShowVolumeSpaceBar);
 			break;
 		}
 
@@ -1094,6 +1092,7 @@
 			}
 			break;
 		}
+
 		case kSpaceBarColorChanged:
 		{
 			switch (fCurrentColor) {
@@ -1109,8 +1108,7 @@
 			}
 
 			Window()->PostMessage(kSettingsContentsModified);
-			BMessage notificationMessage;
-			tracker->SendNotices(kSpaceBarColorChanged, &notificationMessage);
+			tracker->PostMessage(kSpaceBarColorChanged);
 			break;
 		}
 
Index: src/kits/tracker/PoseView.cpp
===================================================================
--- src/kits/tracker/PoseView.cpp	(revision 21262)
+++ src/kits/tracker/PoseView.cpp	(working copy)
@@ -803,9 +803,6 @@
 		app->StopWatching(this, kShowSelectionWhenInactiveChanged);
 		app->StopWatching(this, kTransparentSelectionChanged);
 		app->StopWatching(this, kSortFolderNamesFirstChanged);
-		app->StopWatching(this, kShowVolumeSpaceBar);
-		app->StopWatching(this, kSpaceBarColorChanged);
-		app->StopWatching(this, kUpdateVolumeSpaceBar);
 		app->Unlock();
 	}
 
@@ -890,9 +887,6 @@
 		app->StartWatching(this, kShowSelectionWhenInactiveChanged);
 		app->StartWatching(this, kTransparentSelectionChanged);
 		app->StartWatching(this, kSortFolderNamesFirstChanged);
-		app->StartWatching(this, kShowVolumeSpaceBar);
-		app->StartWatching(this, kSpaceBarColorChanged);
-		app->StartWatching(this, kUpdateVolumeSpaceBar);
 		app->Unlock();
 	}
 
@@ -2331,20 +2325,6 @@
 							Invalidate();
 						}
 						break;
-
-					case kShowVolumeSpaceBar:
-						bool enabled;
-						if (message->FindBool("ShowVolumeSpaceBar", &enabled) == B_OK)
-							TrackerSettings().SetShowVolumeSpaceBar(enabled);
-						// supposed to fall through
-					case kSpaceBarColorChanged:
-						UpdateVolumeIcons();
-						break;
-					case kUpdateVolumeSpaceBar:
-						dev_t device;
-						message->FindInt32("device", (int32 *)&device);
-						UpdateVolumeIcon(device);	
-						break;
 				}
 			}
 			break;
@@ -5214,34 +5194,21 @@
 
 
 void 
-BPoseView::UpdateVolumeIcon(dev_t device, bool forceUpdate)
+BPoseView::UpdateIcon(BPose *pose)
 {
-	int32 index;
-	BPose *pose = fPoseList->FindVolumePose(device,&index);
-	if (pose == NULL)
-		return;
-
-	if (pose->UpdateVolumeSpaceBar(TrackerSettings().ShowVolumeSpaceBar()) || forceUpdate) {
-		BPoint loc(0, index * fListElemHeight);
-		pose->UpdateIcon(loc, this);
+	BPoint location;
+	if (ViewMode() == kListMode) {
+		// need to find the index of the pose in the pose list
+		int32 count = fPoseList->CountItems();
+		for (int32 index = 0; index < count; index++) {
+			if (fPoseList->ItemAt(index) == pose) {
+				location.Set(0, index * fListElemHeight);
+				break;
+			}
+		}
 	}
-}
 
-
-void 
-BPoseView::UpdateVolumeIcons()
-{
-	BVolumeRoster roster;
-
-	BVolume volume;
-	while(roster.GetNextVolume(&volume) == B_NO_ERROR) {
-		BDirectory dir;
-		volume.GetRootDirectory(&dir);
-		node_ref nodeRef;
-		dir.GetNodeRef(&nodeRef);
-
-		UpdateVolumeIcon(nodeRef.device, true);
-	}
+	pose->UpdateIcon(location, this);
 }
 
 
Index: src/kits/tracker/Tracker.cpp
===================================================================
--- src/kits/tracker/Tracker.cpp	(revision 21262)
+++ src/kits/tracker/Tracker.cpp	(working copy)
@@ -483,6 +483,12 @@
 			break;
 		}
 
+		case kShowVolumeSpaceBar:
+		case kSpaceBarColorChanged: {
+			gPeriodicUpdatePoses.DoPeriodicUpdate(true);
+			break;
+		}
+
 		default:
 			_inherited::MessageReceived(message);
 			break;
@@ -497,20 +503,7 @@
 		return;
 
 	// update the volume icon's free space bars
-	BVolumeRoster roster;
-
- 	BVolume volume;
-	while (roster.GetNextVolume(&volume) == B_OK) {
-		BDirectory dir;
-		volume.GetRootDirectory(&dir);
-		node_ref nodeRef;
-		dir.GetNodeRef(&nodeRef);
-
-		BMessage notificationMessage;
-		notificationMessage.AddInt32("device", *(int32 *)&nodeRef.device);
-
-		SendNotices(kUpdateVolumeSpaceBar, &notificationMessage);
-	}
+	gPeriodicUpdatePoses.DoPeriodicUpdate(false);
 }
 
 
Index: src/kits/tracker/Pose.cpp
===================================================================
--- src/kits/tracker/Pose.cpp	(revision 21262)
+++ src/kits/tracker/Pose.cpp	(working copy)
@@ -49,32 +49,15 @@
 
 
 int32
-CalcFreeSpace(dev_t device)
+CalcFreeSpace(BVolume *volume)
 {
-	BVolume volume(device);
-	fs_info info;
-	if (volume.InitCheck() == B_OK && fs_stat_dev(device,&info) == B_OK) {
-		// Philosophy here:
-		// Bars go on all drives with read/write capabilities
-		// Exceptions: Not on CDDA, but on NTFS/Ext2
-		// Also note that some volumes may return 0 when
-		// BVolume::Capacity() is called (believe-me... That *DOES*
-		// happen) so we also check for that.
-		off_t capacity = volume.Capacity();
-		if (((!volume.IsReadOnly() && strcmp(info.fsh_name,"cdda"))
-			|| !strcmp(info.fsh_name,"ntfs")
-			|| !strcmp(info.fsh_name,"ext2"))
-			&& (capacity > 0)) {
-			int32 percent = static_cast<int32>(volume.FreeBytes() / (capacity / 100));
+	off_t capacity = volume->Capacity();
+	int32 percent = static_cast<int32>(volume->FreeBytes() / (capacity / 100));
 
-			// warn below 20 MB of free space (if this is less than 10% of free space)
-			if (volume.FreeBytes() < 20 * 1024 * 1024 && percent < 10)
-				return -2 - percent;
-
-			return percent;
-		}
-	}
-	return -1;
+	// warn below 20 MB of free space (if this is less than 10% of free space)
+	if (volume->FreeBytes() < 20 * 1024 * 1024 && percent < 10)
+		return -2 - percent;
+	return percent;
 }
 
 
@@ -98,9 +81,32 @@
 {
 	CreateWidgets(view);
 
-	if (model->IsVolume() && TrackerSettings().ShowVolumeSpaceBar()) {
+	if (model->IsVolume()) {
+		fs_info info;
 		dev_t device = model->NodeRef()->device;
-		fPercent = CalcFreeSpace(device);
+		BVolume *volume = new BVolume(device);
+		if (volume->InitCheck() == B_OK
+			&& fs_stat_dev(device, &info) == B_OK) {
+			// Philosophy here:
+			// Bars go on all drives with read/write capabilities
+			// Exceptions: Not on CDDA, but on NTFS/Ext2
+			// Also note that some volumes may return 0 when
+			// BVolume::Capacity() is called (believe-me... That *DOES*
+			// happen) so we also check for that.
+			off_t capacity = volume->Capacity();
+			if (((!volume->IsReadOnly() && strcmp(info.fsh_name,"cdda"))
+				|| !strcmp(info.fsh_name,"ntfs")
+				|| !strcmp(info.fsh_name,"ext2"))
+				&& capacity > 0) {
+				// The volume is ok and we want space bars on it
+				gPeriodicUpdatePoses.AddPose(this, view,
+					_PeriodicUpdateCallback, volume);
+				if (TrackerSettings().ShowVolumeSpaceBar())
+					fPercent = CalcFreeSpace(volume);
+			} else
+				delete volume;
+		} else
+			delete volume;
 	}
 
 	if ((fClipboardMode = FSClipboardFindNodeMode(model,true)) != 0
@@ -112,6 +118,13 @@
 
 BPose::~BPose()
 {
+	if (fModel->IsVolume()) {
+		// we might be registered for periodic updates
+		BVolume *volume = NULL;
+		if (gPeriodicUpdatePoses.RemovePose(this, (void **)&volume))
+			delete volume;
+	}
+
 	delete fModel;
 }
 
@@ -285,8 +298,16 @@
 
 
 bool
-BPose::UpdateVolumeSpaceBar(bool enabled)
+BPose::_PeriodicUpdateCallback(BPose *pose, void *cookie)
 {
+	return pose->UpdateVolumeSpaceBar((BVolume *)cookie);
+}
+
+
+bool
+BPose::UpdateVolumeSpaceBar(BVolume *volume)
+{
+	bool enabled = TrackerSettings().ShowVolumeSpaceBar();
 	if (!enabled) {
 		if (fPercent == -1)
 			return false;
@@ -295,9 +316,7 @@
 		return true;
 	}
 
-	dev_t device = TargetModel()->NodeRef()->device;
-	int32 percent = CalcFreeSpace(device);
-
+	int32 percent = CalcFreeSpace(volume);
 	if (fPercent != percent) {
 		if (percent > 100)
 			fPercent = 100;
Index: src/kits/tracker/Utilities.h
===================================================================
--- src/kits/tracker/Utilities.h	(revision 21262)
+++ src/kits/tracker/Utilities.h	(working copy)
@@ -46,6 +46,7 @@
 #include <MenuItem.h>
 #include <MessageFilter.h>
 #include <Mime.h>
+#include <ObjectList.h>
 #include <Point.h>
 #include <Path.h>
 #include <String.h>
@@ -62,6 +63,8 @@
 namespace BPrivate {
 
 class Benaphore;
+class BPose;
+class BPoseView;
 
 // global variables
 extern const rgb_color kBlack;
@@ -83,6 +86,38 @@
 
 // misc typedefs, constants and structs
 
+// Periodically updated poses (ones with a volume space bar) register
+// themselfs in this global list. This way they can be iterated over instead
+// of sending around update messages.
+
+class PeriodicUpdatePoses {
+	public:
+		PeriodicUpdatePoses();
+		~PeriodicUpdatePoses();
+
+		typedef bool (*PeriodicUpdateCallback)(BPose *pose, void *cookie);
+
+		void AddPose(BPose *pose, BPoseView *poseView,
+			PeriodicUpdateCallback callback, void *cookie);
+		bool RemovePose(BPose *pose, void **cookie);
+
+		void DoPeriodicUpdate(bool forceRedraw);
+
+	private:
+		struct periodic_pose {
+			BPose					*pose;
+			BPoseView				*pose_view;
+			PeriodicUpdateCallback	callback;
+			void					*cookie;
+		};
+
+		Benaphore *fLock;
+		BObjectList<periodic_pose> fPoseList;
+};
+
+extern PeriodicUpdatePoses gPeriodicUpdatePoses;
+
+
 // PoseInfo is the structure that gets saved as attributes for every node on
 // disk, defining the node's position and visibility
 class PoseInfo {
Index: src/kits/tracker/PoseView.h
===================================================================
--- src/kits/tracker/PoseView.h	(revision 21262)
+++ src/kits/tracker/PoseView.h	(working copy)
@@ -159,8 +159,7 @@
 		void SetAutoScroll(bool);
 		void SetPoseEditing(bool);
 
-		void UpdateVolumeIcon(dev_t device, bool forceUpdate = false);
-		void UpdateVolumeIcons();
+		void UpdateIcon(BPose *pose);
 
 		// file change notification handler
 		virtual bool FSNotification(const BMessage *);
Index: src/kits/tracker/Utilities.cpp
===================================================================
--- src/kits/tracker/Utilities.cpp	(revision 21262)
+++ src/kits/tracker/Utilities.cpp	(working copy)
@@ -35,6 +35,7 @@
 #include "Attributes.h"
 #include "MimeTypes.h"
 #include "Model.h"
+#include "PoseView.h"
 #include "Utilities.h"
 #include "ContainerWindow.h"
 
@@ -158,7 +159,81 @@
 	textView->DisallowChar(B_PAGE_DOWN);
 	textView->DisallowChar(B_FUNCTION_KEY);
 }
- 
+
+
+PeriodicUpdatePoses::PeriodicUpdatePoses()
+	:	fPoseList(20, true)
+{
+	fLock = new Benaphore("PeriodicUpdatePoses");
+}
+
+
+PeriodicUpdatePoses::~PeriodicUpdatePoses()
+{
+	fLock->Lock();
+	fPoseList.MakeEmpty();
+	delete fLock;
+}
+
+
+void
+PeriodicUpdatePoses::AddPose(BPose *pose, BPoseView *poseView,
+	PeriodicUpdateCallback callback, void *cookie)
+{
+	periodic_pose *periodic = new periodic_pose;
+	periodic->pose = pose;
+	periodic->pose_view = poseView;
+	periodic->callback = callback;
+	periodic->cookie = cookie;
+	fPoseList.AddItem(periodic);
+}
+
+
+bool
+PeriodicUpdatePoses::RemovePose(BPose *pose, void **cookie)
+{
+	int32 count = fPoseList.CountItems();
+	for (int32 index = 0; index < count; index++) {
+		if (fPoseList.ItemAt(index)->pose == pose) {
+			if (!fLock->Lock())
+				return false;
+
+			periodic_pose *periodic = fPoseList.RemoveItemAt(index);
+			if (cookie)
+				*cookie = periodic->cookie;
+			delete periodic;
+			fLock->Unlock();
+			return true;
+		}
+	}
+
+	return false;
+}
+
+
+void
+PeriodicUpdatePoses::DoPeriodicUpdate(bool forceRedraw)
+{
+	if (!fLock->Lock())
+		return;
+
+	int32 count = fPoseList.CountItems();
+	for (int32 index = 0; index < count; index++) {
+		periodic_pose *periodic = fPoseList.ItemAt(index);
+		if (periodic->callback(periodic->pose, periodic->cookie)
+			|| forceRedraw) {
+			periodic->pose_view->LockLooper();
+			periodic->pose_view->UpdateIcon(periodic->pose);
+			periodic->pose_view->UnlockLooper();
+		}
+	}
+
+	fLock->Unlock();
+}
+
+
+static PeriodicUpdatePoses gPeriodicUpdatePoses;
+
 }	// namespace BPrivate
 
 
Index: src/kits/tracker/Pose.h
===================================================================
--- src/kits/tracker/Pose.h	(revision 21262)
+++ src/kits/tracker/Pose.h	(working copy)
@@ -96,7 +96,7 @@
 		void UpdateAllWidgets(int32 poseIndex, BPoint poseLoc, BPoseView *);
 		void UpdateWidgetAndModel(Model *resolvedModel, const char *attrName,
 				uint32 attrType, int32 poseIndex, BPoint poseLoc, BPoseView *view);
-		bool UpdateVolumeSpaceBar(bool enabled);
+		bool UpdateVolumeSpaceBar(BVolume *volume);
 		void UpdateIcon(BPoint poseLoc, BPoseView *);
 
 		//void UpdateFixedSymlink(BPoint poseLoc, BPoseView *);	
@@ -126,6 +126,7 @@
 #endif
 
 	private:
+		static bool _PeriodicUpdateCallback(BPose *pose, void *cookie);
 		void EditPreviousNextWidgetCommon(BPoseView *poseView, bool next);
 		void CreateWidgets(BPoseView *);
 		bool TestLargeIconPixel(BPoint) const;
Index: src/kits/tracker/PoseList.cpp
===================================================================
--- src/kits/tracker/PoseList.cpp	(revision 21262)
+++ src/kits/tracker/PoseList.cpp	(working copy)
@@ -105,20 +105,3 @@
 
 	return NULL;
 }
-
-BPose *
-PoseList::FindVolumePose(const dev_t device, int32 *resultingIndex) const
-{
-	int32 count = CountItems();
-	for (int32 index = 0; index < count; index++) {
-		BPose *pose = ItemAt(index);
-		Model *model = pose->TargetModel();
-		ASSERT(model);
-		if (model->IsVolume() && model->NodeRef()->device == device) {
-			if (resultingIndex)
-				*resultingIndex = index;
-			return pose;
-		}
-	}
-	return NULL;
-}
