diff --git a/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationArea.cs b/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationArea.cs
index fd2febf..d65c74f 100644
--- a/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationArea.cs
+++ b/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationArea.cs
@@ -52,7 +52,10 @@ public class X11NotificationArea : Plug
 	private IntPtr system_tray_opcode_atom;
 	private IntPtr orientation_atom;
 	private IntPtr message_data_atom;
+	private IntPtr visual_atom;
 	private IntPtr manager_window;
+	private Visual manager_visual;
+	private bool manager_visual_rgba;
 	private FilterFunc filter;
 	
 	public X11NotificationArea (string name)
@@ -120,41 +123,79 @@ public class X11NotificationArea : Plug
 	{
 		stamp = 1;
 		orientation = Orientation.Horizontal;
+		AppPaintable = true;
 		AddEvents ((int)EventMask.PropertyChangeMask);
 		filter = new FilterFunc (ManagerFilter);
 	}
 
-        [GLib.ConnectBefore]
-        private void TransparentExposeEvent (object obj, Gtk.ExposeEventArgs args)
+	protected override bool OnExposeEvent (Gdk.EventExpose evnt)
 	{
-		Gtk.Widget widget = (Gtk.Widget)obj;
-		Gdk.Rectangle area = args.Event.Area;
+		Gdk.Rectangle area = evnt.Area;
 
-		widget.GdkWindow.ClearArea (area.X, area.Y, area.Width, area.Height);
-	}
+		if (manager_visual_rgba) {
+			Cairo.Context cr = Gdk.CairoHelper.Create (GdkWindow);
 
-	private void MakeTransparentAgain (object obj, Gtk.StyleSetArgs args)
-	{
-		Gtk.Widget widget = (Gtk.Widget)obj;
+			cr.SetSourceRGBA (0, 0, 0, 0);
+			cr.Operator = Cairo.Operator.Source;
+			Gdk.CairoHelper.Region (cr, evnt.Region);
+			cr.Fill ();
 
-		widget.GdkWindow.SetBackPixmap (null, true);
+			((IDisposable)cr.Target).Dispose ();
+			((IDisposable)cr).Dispose ();
+		} else {
+			GdkWindow.ClearArea (area.X, area.Y, area.Width, area.Height);
+		}
+
+		return true;
 	}
 
-        private void MakeTransparent (object obj, EventArgs args)
+	private void MakeTransparent (object obj, EventArgs args)
 	{
 		Gtk.Widget widget = (Gtk.Widget)obj;
 		if (widget.IsNoWindow || widget.IsAppPaintable)
 			return;
 
-		widget.AppPaintable = true;
-		widget.DoubleBuffered = false;
-		widget.GdkWindow.SetBackPixmap (null, true);
-		widget.ExposeEvent += TransparentExposeEvent;
-		widget.StyleSet += MakeTransparentAgain;
+		if (manager_visual_rgba)
+			widget.GdkWindow.Background = new Color (0, 0, 0);
+		else
+			widget.GdkWindow.SetBackPixmap (null, true);
+	}
+
+	protected override void OnStyleSet (Gtk.Style previous_style)
+	{
+		// The default handler resets the background according to the style. We either
+		// use a transparent background or a parent-relative background and ignore the
+		// style background. So, just don't chain up.
+	}
+	
+	void SetColormap ()
+	{
+		Gdk.Visual visual = manager_visual;
+		
+		if (visual != null) {
+			// To avoid uncertainty about colormaps, _NET_SYSTEM_TRAY_VISUAL is supposed
+			// to be either the screen default visual or a TrueColor visual; ignore it
+			// if it is something else
+			
+			VisualType visual_type = (VisualType)Marshal.ReadInt32 (visual.Handle, IntPtr.Size);
+
+			if (visual_type != VisualType.TrueColor)
+				visual = null;
+		}
+
+		if (visual == null || visual == Screen.SystemVisual)
+			Colormap = Screen.SystemColormap;
+		else if (visual == Screen.RgbVisual)
+			Colormap = Screen.RgbColormap;
+		else if (visual == Screen.RgbaVisual)
+			Colormap = Screen.RgbaColormap;
+		else
+			Colormap = new Colormap (visual, false);
 	}
 
 	protected override void OnRealized ()
 	{
+		SetColormap ();
 		base.OnRealized ();
 		MakeTransparent (this, EventArgs.Empty);
 		Display display = Screen.Display;
@@ -164,6 +205,7 @@ public class X11NotificationArea : Plug
 		system_tray_opcode_atom = XInternAtom (xdisplay, "_NET_SYSTEM_TRAY_OPCODE", false);
 		orientation_atom = XInternAtom (xdisplay, "_NET_SYSTEM_TRAY_ORIENTATION", false);
 		message_data_atom = XInternAtom (xdisplay, "_NET_SYSTEM_TRAY_MESSAGE_DATA", false);
+		visual_atom = XInternAtom (xdisplay, "_NET_SYSTEM_TRAY_VISUAL", false);
 		UpdateManagerWindow (false);
 		SendDockRequest ();
 		Screen.RootWindow.AddFilter (filter);
@@ -175,52 +217,69 @@ public class X11NotificationArea : Plug
 		base.OnAdded (child);
 	}
 
-	protected override void OnUnrealized ()
+	public override void Dispose ()
+	{
+		ClearManagerWindow ();
+		Screen.RootWindow.RemoveFilter (filter);
+		
+		base.Dispose ();
+	}
+	
+	private void ClearManagerWindow ()
 	{
 		if (manager_window != IntPtr.Zero) {
-			Gdk.Window gdkwin = Gdk.Window.ForeignNewForDisplay (Display, (uint)manager_window);
-			if (gdkwin != null) {
+			Gdk.Window gdkwin = Gdk.Window.LookupForDisplay (Display, (uint)manager_window);
+
+			if (gdkwin != null)
 				gdkwin.RemoveFilter (filter);
-			}
+		
+			manager_window = IntPtr.Zero;
+			manager_visual = null;
 		}
-	
-		Screen.RootWindow.RemoveFilter (filter);
-		base.OnUnrealized ();
 	}
 
 	private void UpdateManagerWindow (bool dock_if_realized)
 	{
-		if(Handle == IntPtr.Zero || Display == null || Display.Handle == IntPtr.Zero) {
+		if (Handle == IntPtr.Zero || Display == null || Display.Handle == IntPtr.Zero) {
 			return;
 		}
 
-		IntPtr xdisplay = gdk_x11_display_get_xdisplay (Display.Handle);
-	
 		if (manager_window != IntPtr.Zero) {
 			return;
 		}
 	
+		IntPtr xdisplay = gdk_x11_display_get_xdisplay (Display.Handle);
 		XGrabServer (xdisplay);
 	
 		manager_window = XGetSelectionOwner (xdisplay, selection_atom);
-		if (manager_window != IntPtr.Zero) {
+		if (manager_window != IntPtr.Zero)
 			XSelectInput (xdisplay, manager_window, (IntPtr) (EventMask.StructureNotifyMask | EventMask.PropertyChangeMask));
-		}
 	
 		XUngrabServer (xdisplay);
 		XFlush (xdisplay);
 
 		if (manager_window != IntPtr.Zero) {
-			Gdk.Window gdkwin = Gdk.Window.ForeignNewForDisplay (Display, (uint)manager_window);
-			if (gdkwin != null) {
+			Gdk.Window gdkwin = Gdk.Window.LookupForDisplay (Display, (uint)manager_window);
+			
+			if (gdkwin != null)
 				gdkwin.AddFilter (filter);
-			}
-		
+			
+			GetOrientationProperty ();
+			GetVisualProperty ();
+			
 			if (dock_if_realized && IsRealized) {
-				SendDockRequest ();
+				if ((manager_visual == null && Visual == Screen.SystemVisual) ||
+					(manager_visual == Visual)) {
+					// Already have the right visual, can just dock
+			
+					SendDockRequest ();
+				} else {
+					// Need to re-realize the widget to get the right visual
+					Hide ();
+					Unrealize ();
+					Show ();
+				}
 			}
-		
-			GetOrientationProperty ();
 		}
 	}
 
@@ -334,6 +393,53 @@ public class X11NotificationArea : Plug
 		}
 	}
 
+	private void GetVisualProperty ()
+	{
+		IntPtr display;
+		IntPtr type;
+		int format;
+		IntPtr prop_return;
+		IntPtr nitems, bytes_after;
+		int error, result;
+
+		if (manager_window == IntPtr.Zero) {
+			return;
+		}
+
+		display = gdk_x11_display_get_xdisplay (Display.Handle);
+   
+		gdk_error_trap_push ();
+		type = IntPtr.Zero;
+   
+		result = XGetWindowProperty (display, manager_window, visual_atom, (IntPtr) 0, 
+		 (IntPtr) System.Int32.MaxValue, false, (IntPtr) XAtom.Cardinal, out type, out format, 
+		 out nitems, out bytes_after, out prop_return);
+   
+		error = gdk_error_trap_pop ();
+
+		Visual visual = null;
+
+		if (error == 0 && result == 0 &&
+			type.ToInt32 () == 32 /*XA_VISUALID*/ &&
+			nitems.ToInt32 () == 1 &&
+			format == 32)
+		{
+			int visual_id = Marshal.ReadInt32 (prop_return);
+			visual = new Visual (gdk_x11_screen_lookup_visual (Screen.Handle, visual_id));
+		}
+
+		manager_visual = visual;
+		manager_visual_rgba = (visual != null) && (Screen.RgbaColormap != null);
+
+		// For the background-relative hack we use when we aren't using a real RGBA
+		// visual, we can't be double-buffered
+		DoubleBuffered = manager_visual_rgba;
+
+		if (prop_return != IntPtr.Zero) {
+			XFree (prop_return);
+		}
+	}
+
 	[DllImport ("libgdk-x11-2.0.so.0")]
 	private static extern IntPtr gdk_x11_display_get_xdisplay (IntPtr display);
 
@@ -341,6 +447,9 @@ public class X11NotificationArea : Plug
 	private static extern int gdk_x11_get_server_time (IntPtr window);
 
 	[DllImport ("libgdk-x11-2.0.so.0")]
+	private static extern IntPtr gdk_x11_screen_lookup_visual (IntPtr screen, int xvisualid);
+
+	[DllImport ("libgdk-x11-2.0.so.0")]
 	private static extern void gdk_error_trap_push ();
 
 	[DllImport ("libgdk-x11-2.0.so.0")]
