banshee r3272 - in trunk/banshee: . src/Clients/Nereid/Nereid src/Core/Banshee.Services src/Core/Banshee.ThickClient src/Core/Banshee.ThickClient/Banshee.Gui src/Extensions/Banshee.NotificationArea src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea src/Extensions/Banshee.NotificationArea/Resources src/Libraries/Hyena src/Libraries/Hyena.Gui



Author: abock
Date: Tue Feb 19 21:07:28 2008
New Revision: 3272
URL: http://svn.gnome.org/viewvc/banshee?rev=3272&view=rev

Log:
2008-02-19  Aaron Bockover  <abock gnome org>

    This commit adds most of the functionality of the notification area
    back, and adds a new layer of cross platform support, so it should work
    on Windows with limited functionality since Windows doesn't support
    what the raw X11 version can

    * src/Clients/Nereid/Nereid/PlayerInterface.cs:
    * src/Clients/Nereid/Nereid/PlayerWindowSchema.cs:
    * src/Core/Banshee.ThickClient/Banshee.Gui/BaseClientWindow.cs: Moved
    some windowing/state functionality into BaseClientWindow; includes stuff
    like ToggleVisibility

    * src/Core/Banshee.ThickClient/Banshee.Gui/GtkElementsService.cs: Expose
    PrimaryWindow as BaseClientWindow and added the PrimaryCloseHandler

    * src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationAreaService.cs:
    Major refactor of the notification area; get most of the basic interaction
    functionality working again (clicking the icon, toggling window visibility,
    popup menu; push the actual notification area down a level into the new
    INotificationAreaBox abstraction, implementing common events in the
    service layer

    * src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/INotificationAreaBox.cs:
    An interface to expose common functionality of the area boxes so that
    the service can implement common functionality once

    * src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationAreaBox.cs:
    An advanced INotificationAreaBox implementation that supports more events
    on the notification area; this is functionally on par with Banshee stable
    but will only work on X11; when it fails, GtkNotificationAreaBox will work

    * src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/GtkNotificationAreaBox.cs:
    An INotificationAreaBox implementation that wraps GtkStatusIcon; this is
    a very basic one since the GtkStatusApi is extremely limited due to
    cross platform support; only the context menu and left click are supported,
    but it will work on Windows



Added:
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BaseClientWindow.cs
   trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/GtkNotificationAreaBox.cs
   trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/INotificationAreaBox.cs
   trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationArea.cs
      - copied, changed from r3271, /trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationArea.cs
   trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationAreaBox.cs
Removed:
   trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationArea.cs
Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/src/Clients/Nereid/Nereid/PlayerInterface.cs
   trunk/banshee/src/Clients/Nereid/Nereid/PlayerWindowSchema.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Services.mdp
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/GtkElementsService.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.ThickClient.mdp
   trunk/banshee/src/Core/Banshee.ThickClient/Makefile.am
   trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea.mdp
   trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationAreaService.cs
   trunk/banshee/src/Extensions/Banshee.NotificationArea/Makefile.am
   trunk/banshee/src/Extensions/Banshee.NotificationArea/Resources/Banshee.NotificationArea.addin.xml
   trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.mdp
   trunk/banshee/src/Libraries/Hyena/Hyena.mdp

Modified: trunk/banshee/src/Clients/Nereid/Nereid/PlayerInterface.cs
==============================================================================
--- trunk/banshee/src/Clients/Nereid/Nereid/PlayerInterface.cs	(original)
+++ trunk/banshee/src/Clients/Nereid/Nereid/PlayerInterface.cs	Tue Feb 19 21:07:28 2008
@@ -51,7 +51,7 @@
 
 namespace Nereid
 {
-    public class PlayerInterface : Window, IService, IDisposable, IHasTrackSelection, IHasSourceView
+    public class PlayerInterface : BaseClientWindow, IService, IDisposable, IHasTrackSelection, IHasSourceView
     {
         // Major Layout Components
         private VBox primary_vbox;
@@ -67,27 +67,18 @@
         private ObjectListView object_view;
         private Label status_label;
         
-        // Cached service references
-        private GtkElementsService elements_service;
-        private InterfaceActionService action_service;
-        
         public PlayerInterface () : base ("Banshee Music Player")
         {
-            elements_service = ServiceManager.Get<GtkElementsService> ("GtkElementsService");
-            action_service = ServiceManager.Get<InterfaceActionService> ("InterfaceActionService");
-            
-            ConfigureWindow ();
+        }
+        
+        protected override void Initialize ()
+        {
             BuildPrimaryLayout ();
             ConnectEvents ();
             LoadSettings ();
-            ResizeMoveWindow ();
             
-            elements_service.PrimaryWindow = this;
-
-            action_service.TrackActions.TrackSelector = this;
-            action_service.SourceActions.SourceView = this;
-            
-            AddAccelGroup (action_service.UIManager.AccelGroup);
+            ActionService.TrackActions.TrackSelector = this;
+            ActionService.SourceActions.SourceView = this;
             
             composite_view.TrackView.HasFocus = true;
             
@@ -109,16 +100,11 @@
 
 #region Interface Construction
         
-        private void ConfigureWindow ()
-        {
-            WindowPosition = WindowPosition.Center;
-        }
-        
         private void BuildPrimaryLayout ()
         {
             primary_vbox = new VBox ();
             
-            Widget menu = action_service.UIManager.GetWidget ("/MainMenu");
+            Widget menu = ActionService.UIManager.GetWidget ("/MainMenu");
             menu.Show ();
             primary_vbox.PackStart (menu, false, false, 0);
            
@@ -136,7 +122,7 @@
             toolbar_alignment.TopPadding = 3;
             toolbar_alignment.BottomPadding = 3;
             
-            header_toolbar = (Toolbar)action_service.UIManager.GetWidget ("/HeaderToolbar");
+            header_toolbar = (Toolbar)ActionService.UIManager.GetWidget ("/HeaderToolbar");
             header_toolbar.ShowArrow = false;
             header_toolbar.ToolbarStyle = ToolbarStyle.BothHoriz;
             
@@ -147,15 +133,15 @@
             
             ConnectedSeekSlider seek_slider = new ConnectedSeekSlider ();
             seek_slider.Show ();
-            action_service.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/SeekSlider", seek_slider);
+            ActionService.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/SeekSlider", seek_slider);
             
             TrackInfoDisplay track_info_display = new TrackInfoDisplay ();
             track_info_display.Show ();
-            action_service.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/TrackInfoDisplay", track_info_display, true);
+            ActionService.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/TrackInfoDisplay", track_info_display, true);
             
             ConnectedVolumeButton volume_button = new ConnectedVolumeButton ();
             volume_button.Show ();
-            action_service.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/VolumeButton", volume_button);
+            ActionService.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/VolumeButton", volume_button);
         }
 
         private void BuildViews ()
@@ -201,7 +187,7 @@
                 status_label.Style.Foreground (StateType.Normal), status_label.Style.Background (StateType.Normal)));
             
             ActionButton song_properties_button = new ActionButton
-                (action_service.TrackActions["TrackPropertiesAction"]);
+                (ActionService.TrackActions["TrackPropertiesAction"]);
             song_properties_button.IconSize = IconSize.Menu;
             song_properties_button.Padding = 0;
             song_properties_button.LabelVisible = false;
@@ -222,31 +208,7 @@
 
 #endregion
 
-#region Configuration Loading/Saving        
-        
-        private void ResizeMoveWindow ()
-        {
-            int x = PlayerWindowSchema.XPos.Get ();
-            int y = PlayerWindowSchema.YPos.Get (); 
-            int width = PlayerWindowSchema.Width.Get ();
-            int height = PlayerWindowSchema.Height.Get ();
-           
-            if(width != 0 && height != 0) {
-                Resize (width, height);
-            }
-
-            if (x == 0 && y == 0) {
-                SetPosition (WindowPosition.Center);
-            } else {
-                Move (x, y);
-            }
-            
-            if (PlayerWindowSchema.Maximized.Get ()) {
-                Maximize ();
-            } else {
-                Unmaximize ();
-            }
-        }
+#region Configuration Loading/Saving
         
         private void LoadSettings ()
         {
@@ -262,8 +224,8 @@
             // Service events
             ServiceManager.SourceManager.ActiveSourceChanged += OnActiveSourceChanged;
 
-            action_service.TrackActions ["SearchForSameArtistAction"].Activated += OnProgrammaticSearch;
-            action_service.TrackActions ["SearchForSameAlbumAction"].Activated += OnProgrammaticSearch;
+            ActionService.TrackActions ["SearchForSameArtistAction"].Activated += OnProgrammaticSearch;
+            ActionService.TrackActions ["SearchForSameAlbumAction"].Activated += OnProgrammaticSearch;
 
             // UI events
             view_container.SearchEntry.Changed += OnSearchEntryChanged;
@@ -415,41 +377,7 @@
 #endregion
         
 #region Gtk.Window Overrides
-        
-        protected override bool OnConfigureEvent (Gdk.EventConfigure evnt)
-        {
-            int x, y, width, height;
-
-            if((GdkWindow.State & Gdk.WindowState.Maximized) != 0) {
-                return base.OnConfigureEvent (evnt);
-            }
-            
-            GetPosition (out x, out y);
-            GetSize (out width, out height);
-           
-            PlayerWindowSchema.XPos.Set (x);
-            PlayerWindowSchema.YPos.Set (y);
-            PlayerWindowSchema.Width.Set (width);
-            PlayerWindowSchema.Height.Set (height);
-            
-            return base.OnConfigureEvent (evnt);
-        }
-        
-        protected override bool OnWindowStateEvent (Gdk.EventWindowState evnt)
-        {
-            if ((evnt.NewWindowState & Gdk.WindowState.Withdrawn) == 0) {
-                PlayerWindowSchema.Maximized.Set ((evnt.NewWindowState & Gdk.WindowState.Maximized) != 0);
-            }
-            
-            return base.OnWindowStateEvent (evnt);
-        }
 
-        protected override bool OnDeleteEvent (Gdk.Event evnt)
-        {
-            Banshee.ServiceStack.Application.Shutdown ();
-            return true;
-        }
-        
         private bool accel_group_active = true;
         
         protected override bool OnKeyPressEvent (Gdk.EventKey evnt)
@@ -459,12 +387,12 @@
             if (Focus is Entry && (GtkUtilities.NoImportantModifiersAreSet () && 
                 evnt.Key != Gdk.Key.Control_L && evnt.Key != Gdk.Key.Control_R)) {
                 if (accel_group_active) {
-                    RemoveAccelGroup (action_service.UIManager.AccelGroup);
+                    RemoveAccelGroup (ActionService.UIManager.AccelGroup);
                     accel_group_active = false;
                  }
             } else {
                 if (!accel_group_active) {
-                    AddAccelGroup (action_service.UIManager.AccelGroup);
+                    AddAccelGroup (ActionService.UIManager.AccelGroup);
                     accel_group_active = true;
                 }
             }

Modified: trunk/banshee/src/Clients/Nereid/Nereid/PlayerWindowSchema.cs
==============================================================================
--- trunk/banshee/src/Clients/Nereid/Nereid/PlayerWindowSchema.cs	(original)
+++ trunk/banshee/src/Clients/Nereid/Nereid/PlayerWindowSchema.cs	Tue Feb 19 21:07:28 2008
@@ -33,41 +33,6 @@
 {
     public static class PlayerWindowSchema
     {
-        public static readonly SchemaEntry<int> Width = new SchemaEntry<int>(
-            "player_window", "width",
-            1024,
-            "Window Width",
-            "Width of the main interface window."
-        );
-
-        public static readonly SchemaEntry<int> Height = new SchemaEntry<int>(
-            "player_window", "height",
-            700,
-            "Window Height",
-            "Height of the main interface window."
-        );
-
-        public static readonly SchemaEntry<int> XPos = new SchemaEntry<int>(
-            "player_window", "x_pos",
-            0,
-            "Window Position X",
-            "Pixel position of Main Player Window on the X Axis"
-        );
-
-        public static readonly SchemaEntry<int> YPos = new SchemaEntry<int>(
-            "player_window", "y_pos",
-            0,
-            "Window Position Y",
-            "Pixel position of Main Player Window on the Y Axis"
-        );
-
-        public static readonly SchemaEntry<bool> Maximized = new SchemaEntry<bool>(
-            "player_window", "maximized",
-            false,
-            "Window Maximized",
-            "True if main window is to be maximized, false if it is not."
-        );
-
         public static readonly SchemaEntry<int> SourceViewWidth = new SchemaEntry<int>(
             "player_window", "source_view_width",
             175,

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Services.mdp
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Services.mdp	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Services.mdp	Tue Feb 19 21:07:28 2008
@@ -135,6 +135,7 @@
     <ProjectReference type="Gac" localcopy="True" refto="glib-sharp, Version=2.10.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
     <ProjectReference type="Gac" localcopy="True" refto="TagLib, Version=0.0.0.0, Culture=neutral" />
   </References>
+  <Deployment.LinuxDeployData generateScript="False" />
   <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="True" RelativeMakefileName="Makefile.am">
     <BuildFilesVar Sync="True" Name="SOURCES" />
     <DeployFilesVar />
@@ -144,5 +145,4 @@
     <AsmRefVar />
     <ProjectRefVar />
   </MonoDevelop.Autotools.MakefileInfo>
-  <Deployment.LinuxDeployData generateScript="False" />
 </Project>
\ No newline at end of file

Added: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BaseClientWindow.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BaseClientWindow.cs	Tue Feb 19 21:07:28 2008
@@ -0,0 +1,204 @@
+//
+// BaseClientWindow.cs
+//
+// Author:
+//   Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using Gtk;
+
+using Banshee.ServiceStack;
+using Banshee.Configuration;
+
+namespace Banshee.Gui
+{
+    public abstract class BaseClientWindow : Window
+    {
+        private GtkElementsService elements_service;
+        protected GtkElementsService ElementsService {
+            get { return elements_service; }
+        }
+        
+        private InterfaceActionService action_service;
+        protected InterfaceActionService ActionService {
+            get { return action_service; }
+        }
+    
+        public BaseClientWindow (string title) : base (title)
+        {
+            elements_service = ServiceManager.Get<GtkElementsService> ("GtkElementsService");
+            action_service = ServiceManager.Get<InterfaceActionService> ("InterfaceActionService");
+            
+            ConfigureWindow ();
+            ResizeMoveWindow ();
+            
+            elements_service.PrimaryWindow = this;
+            
+            AddAccelGroup (action_service.UIManager.AccelGroup);
+            
+            Initialize ();
+        }
+        
+        public void ToggleVisibility ()
+        {
+            if (IsActive) {
+                SaveWindowSizePosition ();
+                Visible = false;
+            } else {
+                RestoreWindowSizePosition ();
+                Present ();
+            }
+        }
+        
+        private int x, y, w, h;
+        private bool maximized;
+        
+        private void SaveWindowSizePosition ()
+        {
+            maximized = ((GdkWindow.State & Gdk.WindowState.Maximized) > 0);
+
+            if (!maximized) {
+                GetPosition (out x, out y);
+                GetSize (out w, out h);
+            }
+        }
+
+        private void RestoreWindowSizePosition () 
+        {
+            if (maximized) {
+                Maximize ();
+            } else {
+                Resize (w, h);
+                Move (x, y);
+            }
+        }
+        
+        protected abstract void Initialize ();
+    
+        protected virtual void ConfigureWindow ()
+        {
+            WindowPosition = WindowPosition.Center;
+        }
+    
+        protected virtual void ResizeMoveWindow ()
+        {
+            int x = XPosSchema.Get ();
+            int y = YPosSchema.Get (); 
+            int width = WidthSchema.Get ();
+            int height = HeightSchema.Get ();
+           
+            if(width != 0 && height != 0) {
+                Resize (width, height);
+            }
+
+            if (x == 0 && y == 0) {
+                SetPosition (WindowPosition.Center);
+            } else {
+                Move (x, y);
+            }
+            
+            if (MaximizedSchema.Get ()) {
+                Maximize ();
+            } else {
+                Unmaximize ();
+            }
+        }
+        
+        protected override bool OnDeleteEvent (Gdk.Event evnt)
+        {
+             if (ElementsService.PrimaryWindowClose != null) {
+                if (ElementsService.PrimaryWindowClose ()) {
+                    return true;
+                }
+            }
+            
+            Banshee.ServiceStack.Application.Shutdown ();
+            return base.OnDeleteEvent (evnt);
+        }
+
+        protected override bool OnConfigureEvent (Gdk.EventConfigure evnt)
+        {
+            int x, y, width, height;
+
+            if ((GdkWindow.State & Gdk.WindowState.Maximized) != 0) {
+                return base.OnConfigureEvent (evnt);
+            }
+            
+            GetPosition (out x, out y);
+            GetSize (out width, out height);
+           
+            XPosSchema.Set (x);
+            YPosSchema.Set (y);
+            WidthSchema.Set (width);
+            HeightSchema.Set (height);
+            
+            return base.OnConfigureEvent (evnt);
+        }
+        
+        protected override bool OnWindowStateEvent (Gdk.EventWindowState evnt)
+        {
+            if ((evnt.NewWindowState & Gdk.WindowState.Withdrawn) == 0) {
+                MaximizedSchema.Set ((evnt.NewWindowState & Gdk.WindowState.Maximized) != 0);
+            }
+            
+            return base.OnWindowStateEvent (evnt);
+        }
+        
+        public static readonly SchemaEntry<int> WidthSchema = new SchemaEntry<int>(
+            "player_window", "width",
+            1024,
+            "Window Width",
+            "Width of the main interface window."
+        );
+
+        public static readonly SchemaEntry<int> HeightSchema = new SchemaEntry<int>(
+            "player_window", "height",
+            700,
+            "Window Height",
+            "Height of the main interface window."
+        );
+
+        public static readonly SchemaEntry<int> XPosSchema = new SchemaEntry<int>(
+            "player_window", "x_pos",
+            0,
+            "Window Position X",
+            "Pixel position of Main Player Window on the X Axis"
+        );
+
+        public static readonly SchemaEntry<int> YPosSchema = new SchemaEntry<int>(
+            "player_window", "y_pos",
+            0,
+            "Window Position Y",
+            "Pixel position of Main Player Window on the Y Axis"
+        );
+
+        public static readonly SchemaEntry<bool> MaximizedSchema = new SchemaEntry<bool>(
+            "player_window", "maximized",
+            false,
+            "Window Maximized",
+            "True if main window is to be maximized, false if it is not."
+        );
+    }
+}

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/GtkElementsService.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/GtkElementsService.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/GtkElementsService.cs	Tue Feb 19 21:07:28 2008
@@ -39,10 +39,13 @@
 {
     public class GtkElementsService : IService, IPropertyStoreExpose
     {
+        public delegate bool PrimaryWindowCloseHandler ();
+        
         private PropertyStore property_store = new PropertyStore ();
         private BansheeIconFactory icon_factory = new BansheeIconFactory ();
         
-        private Window primary_window;
+        private BaseClientWindow primary_window;
+        private PrimaryWindowCloseHandler primary_window_close_handler;
         
         public event EventHandler ThemeChanged;
         
@@ -81,7 +84,7 @@
             }
         }
         
-        public Window PrimaryWindow {
+        public BaseClientWindow PrimaryWindow {
             get { return primary_window; }
             set {
                 if (primary_window != null) {
@@ -92,7 +95,7 @@
                 primary_window = value;
                 
                 if (primary_window != null) {
-                    property_store.Set<Window> ("PrimaryWindow", primary_window);
+                    property_store.Set<BaseClientWindow> ("PrimaryWindow", primary_window);
                     
                     primary_window.StyleSet += OnStyleSet;
                     primary_window.Realized += OnPrimaryWindowRealized;
@@ -103,6 +106,11 @@
             }
         }
         
+        public PrimaryWindowCloseHandler PrimaryWindowClose {
+            get { return primary_window_close_handler; }
+            set { primary_window_close_handler = value; }
+        }
+        
         public BansheeIconFactory IconFactory {
             get { return icon_factory; }
         }

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.ThickClient.mdp
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.ThickClient.mdp	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.ThickClient.mdp	Tue Feb 19 21:07:28 2008
@@ -90,6 +90,7 @@
     <File name="Banshee.Query.Gui/SmartPlaylistQueryValueEntry.cs" subtype="Code" buildaction="Compile" />
     <File name="Banshee.Gui.Widgets/ConnectedMessageBar.cs" subtype="Code" buildaction="Compile" />
     <File name="Banshee.Sources.Gui/SourceIconResolver.cs" subtype="Code" buildaction="Compile" />
+    <File name="Banshee.Gui/BaseClientWindow.cs" subtype="Code" buildaction="Compile" />
   </Contents>
   <References>
     <ProjectReference type="Project" localcopy="False" refto="Hyena.Gui" />
@@ -105,6 +106,7 @@
     <ProjectReference type="Gac" localcopy="True" refto="glib-sharp, Version=2.10.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
     <ProjectReference type="Gac" localcopy="True" refto="pango-sharp, Version=2.10.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
   </References>
+  <Deployment.LinuxDeployData generateScript="False" />
   <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="True" RelativeMakefileName="Makefile.am">
     <BuildFilesVar Sync="True" Name="SOURCES" />
     <DeployFilesVar />
@@ -114,5 +116,4 @@
     <AsmRefVar />
     <ProjectRefVar />
   </MonoDevelop.Autotools.MakefileInfo>
-  <Deployment.LinuxDeployData generateScript="False" />
 </Project>
\ No newline at end of file

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Makefile.am
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Makefile.am	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Makefile.am	Tue Feb 19 21:07:28 2008
@@ -50,6 +50,7 @@
 	Banshee.Gui.Widgets/UserJobTileHost.cs \
 	Banshee.Gui/BansheeActionGroup.cs \
 	Banshee.Gui/BansheeIconFactory.cs \
+	Banshee.Gui/BaseClientWindow.cs \
 	Banshee.Gui/CommonServices.cs \
 	Banshee.Gui/GlobalActions.cs \
 	Banshee.Gui/GtkBaseClient.cs \

Modified: trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea.mdp
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea.mdp	(original)
+++ trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea.mdp	Tue Feb 19 21:07:28 2008
@@ -8,10 +8,13 @@
     </Configuration>
   </Configurations>
   <Contents>
-    <File name="Banshee.NotificationArea/NotificationArea.cs" subtype="Code" buildaction="Compile" />
+    <File name="Banshee.NotificationArea/X11NotificationArea.cs" subtype="Code" buildaction="Compile" />
     <File name="Banshee.NotificationArea/NotificationAreaService.cs" subtype="Code" buildaction="Compile" />
     <File name="Resources/NotificationAreaMenu.xml" subtype="Code" buildaction="EmbedAsResource" />
     <File name="Resources/Banshee.NotificationArea.addin.xml" subtype="Code" buildaction="EmbedAsResource" />
+    <File name="Banshee.NotificationArea/X11NotificationAreaBox.cs" subtype="Code" buildaction="Compile" />
+    <File name="Banshee.NotificationArea/INotificationAreaBox.cs" subtype="Code" buildaction="Compile" />
+    <File name="Banshee.NotificationArea/GtkNotificationAreaBox.cs" subtype="Code" buildaction="Compile" />
   </Contents>
   <References>
     <ProjectReference type="Project" localcopy="True" refto="Banshee.Core" />

Added: trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/GtkNotificationAreaBox.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/GtkNotificationAreaBox.cs	Tue Feb 19 21:07:28 2008
@@ -0,0 +1,61 @@
+//
+// GtkNotificationAreaBox.cs
+//
+// Author:
+//   Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using Mono.Unix;
+using Gtk;
+
+using Banshee.Gui;
+
+namespace Banshee.NotificationArea
+{
+    public class GtkNotificationAreaBox : StatusIcon, INotificationAreaBox
+    {
+        public event EventHandler Disconnected;
+        
+        public event EventHandler Activated {
+            add { base.Activate += value; }
+            remove { base.Activate -= value; }
+        }
+        
+        public event PopupMenuHandler PopupMenuEvent {
+            add { base.PopupMenu += value; }
+            remove { base.PopupMenu -= value; }
+        }
+        
+        public GtkNotificationAreaBox ()
+        {
+            IconName = "music-player-banshee";
+        }
+        
+        public void PositionMenu (Menu menu, out int x, out int y, out bool push_in)
+        {
+            StatusIcon.PositionMenu (menu, out x, out y, out push_in, Handle);
+        }
+    }
+}

Added: trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/INotificationAreaBox.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/INotificationAreaBox.cs	Tue Feb 19 21:07:28 2008
@@ -0,0 +1,42 @@
+//
+// INotificationAreaBox.cs
+//
+// Author:
+//   Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using Gtk;
+
+namespace Banshee.NotificationArea
+{
+    public interface INotificationAreaBox : IDisposable
+    {
+        event EventHandler Disconnected;
+        event EventHandler Activated;
+        event PopupMenuHandler PopupMenuEvent;
+        
+        void PositionMenu (Menu menu, out int x, out int y, out bool push_in);
+    }
+}

Modified: trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationAreaService.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationAreaService.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationAreaService.cs	Tue Feb 19 21:07:28 2008
@@ -34,18 +34,25 @@
 
 //using Notifications;
 
-using Banshee.Gui;
 using Banshee.ServiceStack;
 using Banshee.Configuration;
-
-using NotificationAreaIcon = NotificationArea;
+using Banshee.Gui;
+using Banshee.MediaEngine;
 
 namespace Banshee.NotificationArea 
 {
-    public class NotificationAreaService : IExtensionService
+    public class NotificationAreaService : IExtensionService, IDisposable
     {
-        private NotificationAreaIcon notif_area;
-        private EventBox event_box;
+        private INotificationAreaBox notif_area;
+        private GtkElementsService elements_service;
+        private InterfaceActionService interface_action_service;
+    
+        private Menu menu;
+		//private RatingMenuItem rating_menu_item;
+        private BansheeActionGroup actions;
+        private uint ui_manager_id;
+        
+        private bool show_notifications = true;
     
         public NotificationAreaService ()
         {
@@ -53,443 +60,175 @@
         
         void IExtensionService.Initialize ()
         {
-            // TODO: Add something like ServiceManager.NotifyStartup ("InterfaceActionService", Initialize);
-            
-            if (ServiceManager.Contains ("InterfaceActionService")) {
-                BuildNotificationArea ();
-            } else {
-                ServiceManager.ServiceStarted += delegate (ServiceStartedArgs args) {
-                   if (args.Service is Banshee.Gui.InterfaceActionService) {
-                       BuildNotificationArea ();
-                   }
-                };
+            elements_service = ServiceManager.Get<GtkElementsService> ();
+            interface_action_service = ServiceManager.Get<InterfaceActionService> ();
+        
+            if (!ServiceStartup ()) {
+                ServiceManager.ServiceStarted += OnServiceStarted;
             }
         }
         
-        private void BuildNotificationArea () 
+        private void OnServiceStarted (ServiceStartedArgs args) 
         {
-            notif_area = new NotificationAreaIcon (Catalog.GetString ("Banshee"));
-            notif_area.DestroyEvent += OnNotificationAreaDestroyEvent;
-
-            event_box = new EventBox ();
-            //event_box.ButtonPressEvent += OnNotificationAreaIconClick;
-            //event_box.EnterNotifyEvent += OnEnterNotifyEvent;
-            //event_box.LeaveNotifyEvent += OnLeaveNotifyEvent;
-            //event_box.ScrollEvent += OnMouseScroll;
-            
-            event_box.Add (new Gtk.Image (IconThemeUtils.LoadIcon (22, "music-player-banshee")));
-
-            notif_area.Add (event_box);
-            notif_area.ShowAll ();
-            
-            //if(!QuitOnCloseSchema.Get()) {
-            //    RegisterCloseHandler();
-            //}
+            if (args.Service is Banshee.Gui.InterfaceActionService) {
+                interface_action_service = (InterfaceActionService)args.Service;
+            } else if (args.Service is GtkElementsService) {
+                elements_service = (GtkElementsService)args.Service;
+            }
+                    
+            ServiceStartup ();
         }
         
-        private void OnNotificationAreaDestroyEvent (object o, EventArgs args)
+        private bool ServiceStartup ()
         {
-            // Ensure we don't keep the destroyed reference around
-            if (notif_area != null) {
-                notif_area.DestroyEvent -= OnNotificationAreaDestroyEvent;
+            if (elements_service == null || interface_action_service == null) {
+                return false;
             }
             
+            Initialize ();
+            
+            ServiceManager.ServiceStarted -= OnServiceStarted;
             BuildNotificationArea ();
-        }
-    
-        string IService.ServiceName {
-            get { return "NotificationAreaService"; }
-        }
-    
-        /*protected override string ConfigurationName { get { return "notification_area"; } }
-        public override string DisplayName { get { return Catalog.GetString("Notification Area Icon"); } }
-
-        public override string Description {
-            get { return Catalog.GetString("Shows the Notification Area Icon"); }
-        }
-
-        public override string[] Authors {
-            get {
-                return new string[] {
-                    "Sebastian Dr\u00f6ge",
-                    "Aaron Bockover",
-                    "Ruben Vermeersch",
-                    "Gabriel Burt"
-                };
-            }
-        }
-
-        private Menu menu;
-        private bool menu_is_reversed = false;
-		private RatingMenuItem rating_menu_item;
-        private ActionGroup actions;
-        private uint ui_manager_id;
-
-        private TrackInfoPopup popup;
-        private bool can_show_popup = false;
-        private bool cursor_over_trayicon = false;
-        private bool show_notifications = false;
-        private TrackInfo current_track = null;
-        private string notify_last_title = null;
-        private string notify_last_artist = null;
-
-        private static readonly uint SkipDelta = 10;
-        private static readonly int VolumeDelta = 10;
-        
-        protected override void PluginInitialize()
-        {
+            
+            return true;
         }
         
-        protected override void InterfaceInitialize() 
+        private void Initialize ()
         {
-            Init();
-
-            actions = new ActionGroup("NotificationArea");
-
-            actions.Add(new ActionEntry [] {
-                new ActionEntry("CloseAction", Stock.Close,
-                    Catalog.GetString("_Close"), "<Control>W",
-                    Catalog.GetString("Close"), CloseWindow)
+            interface_action_service.GlobalActions.Add (new ActionEntry [] {
+                new ActionEntry ("CloseAction", Stock.Close,
+                    Catalog.GetString ("_Close"), "<Control>W",
+                    Catalog.GetString ("Close"), CloseWindow)
             });
-
-            actions.Add(new ToggleActionEntry [] {
-                new ToggleActionEntry("ToggleNotificationsAction", null,
-                    Catalog.GetString("_Show Notifications"), null,
-                    Catalog.GetString("Show notifications when song changes"), ToggleNotifications, ShowNotifications)
+            
+            actions = new BansheeActionGroup ("NotificationArea");
+            actions.Add (new ToggleActionEntry [] {
+                new ToggleActionEntry ("ToggleNotificationsAction", null,
+                    Catalog.GetString ("_Show Notifications"), null,
+                    Catalog.GetString ("Show notifications when song changes"), ToggleNotifications, ShowNotifications)
             });
-
-            Globals.ActionManager.UI.InsertActionGroup(actions, 0);
-            ui_manager_id = Globals.ActionManager.UI.AddUiFromResource("NotificationAreaIconMenu.xml");      
-            menu = (Menu) Globals.ActionManager.UI.GetWidget("/NotificationAreaIconMenu");
-
-            for(int i = 0; i < menu.Children.Length; i++) {
-                if(menu.Children[i].Name == "Next") {
-                    rating_menu_item = new RatingMenuItem();
-                    rating_menu_item.Activated += OnItemRatingActivated;
-                    ToggleRatingMenuSensitive();
-                    menu.Insert(rating_menu_item, i + 2);
-                    break;
-                }
-            }
-
-            menu.Show();
             
-            popup = new TrackInfoPopup();
-            PlayerEngineCore.EventChanged += OnPlayerEngineEventChanged;
-
-            // When we're already playing fill the TrackInfoPopup with the current track
-            if (PlayerEngineCore.CurrentState == PlayerEngineState.Playing) {
-                FillPopup();
-            }
-
-            // Forcefully load this value
-            show_notifications = ShowNotifications;
-            InterfaceElements.MainWindow.KeyPressEvent += OnKeyPressEvent;
+            interface_action_service.AddActionGroup (actions);
+            
+            ui_manager_id = interface_action_service.UIManager.AddUiFromResource ("NotificationAreaMenu.xml");      
+            menu = (Menu)interface_action_service.UIManager.GetWidget("/NotificationAreaIconMenu");
+            menu.Show ();
+            
+            ServiceManager.PlayerEngine.EventChanged += OnPlayerEngineEventChanged;
         }
-
-        protected override void PluginDispose() 
+        
+        public void Dispose ()
         {
             if (notif_area != null) {
-                notif_area.Destroy();
-                event_box = null;
+                notif_area.Dispose ();
                 notif_area = null;
             }
             
-            InterfaceElements.PrimaryWindowClose = null;
+            ServiceManager.PlayerEngine.EventChanged -= OnPlayerEngineEventChanged;
             
-            PlayerEngineCore.EventChanged -= OnPlayerEngineEventChanged;
+            elements_service.PrimaryWindowClose = null;
             
-            Globals.ActionManager.UI.RemoveUi(ui_manager_id);
-            Globals.ActionManager.UI.RemoveActionGroup(actions);
-        }
-
-        public override Gtk.Widget GetConfigurationWidget()
-        {            
-            return new NotificationAreaIconConfigPage(this);
-        }
-        
-
-        
-        private void RegisterCloseHandler()
-        {
-            if(InterfaceElements.PrimaryWindowClose == null) {
-                InterfaceElements.PrimaryWindowClose = OnPrimaryWindowClose;
-            }
-        }
-        
-        private void UnregisterCloseHandler()
-        {
-            if(InterfaceElements.PrimaryWindowClose != null) {
-                InterfaceElements.PrimaryWindowClose = null;
-            }
+            interface_action_service.UIManager.RemoveUi (ui_manager_id);
+            interface_action_service.UIManager.RemoveActionGroup (actions);
+            
+            elements_service = null;
+            interface_action_service = null;
         }
         
-        private bool OnPrimaryWindowClose()
-        {
-            CloseWindow(null, null);
-            return true;
-        }
-
-        private void OnDestroyEvent(object o, DestroyEventArgs args) 
-        {
-            Init();
-        }
-
-        private void CloseWindow(object o, EventArgs args)
+        private void BuildNotificationArea () 
         {
-            try {
-                if(NotifyOnCloseSchema.Get()) {
-                    Gdk.Pixbuf image = Branding.ApplicationLogo.ScaleSimple(42, 42, Gdk.InterpType.Bilinear);
-                    Notification nf = new Notification(
-                        Catalog.GetString("Still Running"), 
-                        Catalog.GetString("Banshee was closed to the notification area. " + 
-                            "Use the <i>Quit</i> option to end your session."),
-                        image, event_box);
-                    nf.Urgency = Urgency.Low;
-                    nf.Timeout = 4500;
-                    nf.Show();
-                    
-                    NotifyOnCloseSchema.Set(false);
+            if (Environment.OSVersion.Platform == PlatformID.Unix) {
+                try {
+                    notif_area = new X11NotificationAreaBox ();
+                } catch {
                 }
-            } catch {
-            }
-
-            ShowHideMainWindow();
-        }
-
-        private void ToggleNotifications(object o, EventArgs args)
-        {
-            ShowNotifications = (actions["ToggleNotificationsAction"] as ToggleAction).Active;
-        }
-
-        private void ShowHideMainWindow()
-        {
-            if (InterfaceElements.MainWindow.IsActive) {
-                SaveWindowSizePosition();
-                InterfaceElements.MainWindow.Visible = false;
-            } else {
-                RestoreWindowSizePosition();
-                InterfaceElements.MainWindow.Present();
-            }
-        }
-
-        private void ShowNotification()
-        {
-            // This has to happen before the next if, otherwise the last_* members aren't set correctly.
-            if(current_track == null || (notify_last_title == current_track.DisplayTrackTitle 
-                && notify_last_artist == current_track.DisplayArtistName)) {
-                return;
             }
             
-            notify_last_title = current_track.DisplayTrackTitle;
-            notify_last_artist = current_track.DisplayArtistName;
-
-            if(cursor_over_trayicon || !show_notifications || InterfaceElements.MainWindow.HasToplevelFocus) {
-                return;
+            if (notif_area == null) {
+                notif_area = new GtkNotificationAreaBox ();
             }
             
-            string message = String.Format("{0}\n<i>{1}</i>", 
-                GLib.Markup.EscapeText(current_track.DisplayTrackTitle),
-                GLib.Markup.EscapeText(current_track.DisplayArtistName));
-            
-            Gdk.Pixbuf image = null;
+            notif_area.Disconnected += OnNotificationAreaDisconnected;
+            notif_area.Activated += OnNotificationAreaActivated;
+            notif_area.PopupMenuEvent += OnNotificationAreaPopupMenuEvent;
             
-            try {
-                if(current_track.CoverArtFileName != null) {
-                    image = new Gdk.Pixbuf(current_track.CoverArtFileName);
-                } 
-            } catch {
-            }
-            
-            if(image == null) {
-                image = Branding.DefaultCoverArt;
-            }
-            
-            image = image.ScaleSimple(42, 42, Gdk.InterpType.Bilinear);
-            
-            try {
-                Notification nf = new Notification(Catalog.GetString("Now Playing"), message, image, event_box);
-                nf.Urgency = Urgency.Low;
-                nf.Timeout = 4500;
-                nf.Show();
-            } catch(Exception e) {
-                LogCore.Instance.PushError(Catalog.GetString("Cannot show notification"), e.Message, false);
+            if (!QuitOnCloseSchema.Get ()) {
+                RegisterCloseHandler ();
             }
         }
-
-        [GLib.ConnectBefore]
-        private void OnKeyPressEvent(object o, KeyPressEventArgs args)
+        
+        private void RegisterCloseHandler ()
         {
-            bool handled = false;
-            
-            if (args.Event.Key == Gdk.Key.w && (args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
-                handled = true;
-                ShowHideMainWindow();
+            if (elements_service.PrimaryWindowClose == null) {
+                elements_service.PrimaryWindowClose = OnPrimaryWindowClose;
             }
-            
-            args.RetVal = handled;
         }
-
-        private void OnNotificationAreaIconClick(object o, ButtonPressEventArgs args) 
-        {
-            if(args.Event.Type != Gdk.EventType.ButtonPress) {
-                return;
-            }
         
-            switch(args.Event.Button) {
-                case 1:
-                    if((args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
-                        Globals.ActionManager["PreviousAction"].Activate();
-                    } else {
-                        ShowHideMainWindow();
-                    }
-                    break;
-                case 2:
-                    Globals.ActionManager["PlayPauseAction"].Activate();
-                    break;
-                case 3:
-                    if((args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
-                        Globals.ActionManager["NextAction"].Activate();
-                    } else {
-                        menu.Popup(null, null, new MenuPositionFunc(PositionMenu), 
-                            args.Event.Button, args.Event.Time);
-                    }
-                    break;
-            }
-        }
-
-        private void OnItemRatingActivated(object o, EventArgs args)
+        private void UnregisterCloseHandler ()
         {
-            if(PlayerEngineCore.CurrentTrack != null) {
-                PlayerEngineCore.CurrentTrack.Rating = (uint)rating_menu_item.Value;
-                PlayerEngineCore.TrackInfoUpdated();
+            if (elements_service.PrimaryWindowClose != null) {
+                elements_service.PrimaryWindowClose = null;
             }
         }
         
-        private void ToggleRatingMenuSensitive() 
+        private bool OnPrimaryWindowClose ()
         {
-            if(PlayerEngineCore.CurrentTrack != null && (SourceManager.ActiveSource is LibrarySource || 
-                SourceManager.ActiveSource is PlaylistSource ||
-                SourceManager.ActiveSource is SmartPlaylistSource)) {
-                rating_menu_item.Reset((int)PlayerEngineCore.CurrentTrack.Rating);
-                rating_menu_item.Show();
-            } else {
-                rating_menu_item.Hide();
-            }
+            CloseWindow (null, null);
+            return true;
         }
-
-        private void PositionMenu(Menu menu, out int x, out int y, out bool push_in) 
+        
+        private void OnNotificationAreaDisconnected (object o, EventArgs args)
         {
-            bool on_bottom = PositionWidget(menu, out x, out y, 0);
-            push_in = true;
-            
-            if((on_bottom && !menu_is_reversed) || (!on_bottom && menu_is_reversed)) {
-                menu_is_reversed = !menu_is_reversed;
-                Widget [] frozen_children = new Widget[menu.Children.Length - 1];
-                Array.Copy(menu.Children, 1, frozen_children, 0, frozen_children.Length);
-                for(int i = 0; i < frozen_children.Length; i++) {
-                    menu.ReorderChild(frozen_children[i], 0);
-                }
+            // Ensure we don't keep the destroyed reference around
+            if (notif_area != null) {
+                notif_area.Disconnected -= OnNotificationAreaDisconnected;
+                notif_area.Activated -= OnNotificationAreaActivated;
+                notif_area.PopupMenuEvent -= OnNotificationAreaPopupMenuEvent;
             }
-        }
-
-        private bool PositionWidget(Widget widget, out int x, out int y, int yPadding) 
-        {
-            int button_y, panel_width, panel_height;
-            Gtk.Requisition requisition = widget.SizeRequest();
-            
-            event_box.GdkWindow.GetOrigin(out x, out button_y);
-            (event_box.Toplevel as Gtk.Window).GetSize(out panel_width, out panel_height);
             
-            bool on_bottom = button_y + panel_height + requisition.Height >= event_box.Screen.Height;
-
-            y = on_bottom
-                ? button_y - requisition.Height - yPadding
-                : button_y + panel_height + yPadding;
-                
-            return on_bottom;
-        }
-
-        private void OnMouseScroll(object o, ScrollEventArgs args) 
-        {
-            switch(args.Event.Direction) {
-                case Gdk.ScrollDirection.Up:
-                    if((args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
-                        PlayerEngineCore.Volume += (ushort)VolumeDelta;
-                    } else if((args.Event.State & Gdk.ModifierType.ShiftMask) != 0) {
-                        PlayerEngineCore.Position += SkipDelta;
-                    } else {
-                        Globals.ActionManager["NextAction"].Activate();
-                    }
-                    break;
-                case Gdk.ScrollDirection.Down:
-                    if((args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
-                        if (PlayerEngineCore.Volume < (ushort)VolumeDelta)
-                            PlayerEngineCore.Volume = 0;
-                        else
-                            PlayerEngineCore.Volume -= (ushort)VolumeDelta;
-                    } else if((args.Event.State & Gdk.ModifierType.ShiftMask) != 0) {
-                        PlayerEngineCore.Position -= SkipDelta;
-                    } else {
-                        Globals.ActionManager["PreviousAction"].Activate();
-                    }
-                    break;
-            }
-        }
-
-        private void HidePopup() 
-        {
-            popup.Hide();
+            BuildNotificationArea ();
         }
         
-        private void ShowPopup() 
+        private void OnNotificationAreaActivated (object o, EventArgs args)
         {
-            PositionPopup();
-            popup.Show();
+            elements_service.PrimaryWindow.ToggleVisibility ();
         }
         
-        private void PositionPopup() 
+        private void OnNotificationAreaPopupMenuEvent (object o, PopupMenuArgs args)
         {
-            int x, y;
-            Gtk.Requisition event_box_req = event_box.SizeRequest();
-            Gtk.Requisition popup_req = popup.SizeRequest();
-            
-            PositionWidget(popup, out x, out y, 5);
-            
-            x = x - (popup_req.Width / 2) + (event_box_req.Width / 2);     
-            if(x + popup_req.Width >= event_box.Screen.Width) { 
-                x = event_box.Screen.Width - popup_req.Width - 5;
-            } else if(x < 5) {
-                x = 5;
-            }
-            
-            popup.Move(x, y);
+            menu.Popup (null, null, notif_area.PositionMenu, 3, Gtk.Global.CurrentEventTime);
         }
         
-        private void OnEnterNotifyEvent(object o, EnterNotifyEventArgs args) 
+        private void CloseWindow (object o, EventArgs args)
         {
-            cursor_over_trayicon = true;
-            if(can_show_popup) {
-                // only show the popup when the cursor is still over the
-                // tray icon after 500ms
-                GLib.Timeout.Add(500, delegate {
-                    if ((cursor_over_trayicon) && (can_show_popup)) {
-                        ShowPopup();
-                    }
-                    return false;
-                });
+            try {
+                if (NotifyOnCloseSchema.Get ()) {
+                    /*Gdk.Pixbuf image = Branding.ApplicationLogo.ScaleSimple(42, 42, Gdk.InterpType.Bilinear);
+                    Notification nf = new Notification(
+                        Catalog.GetString("Still Running"), 
+                        Catalog.GetString("Banshee was closed to the notification area. " + 
+                            "Use the <i>Quit</i> option to end your session."),
+                        image, event_box);
+                    nf.Urgency = Urgency.Low;
+                    nf.Timeout = 4500;
+                    nf.Show();*/
+                    
+                    NotifyOnCloseSchema.Set (false);
+                }
+            } catch {
             }
+
+            elements_service.PrimaryWindow.ToggleVisibility ();
         }
-        
-        private void OnLeaveNotifyEvent(object o, LeaveNotifyEventArgs args) 
+
+        private void ToggleNotifications (object o, EventArgs args)
         {
-            cursor_over_trayicon = false;
-            HidePopup();
+            ShowNotifications = ((ToggleAction)actions["ToggleNotificationsAction"]).Active;
         }
-
-        private void OnPlayerEngineEventChanged(object o, PlayerEngineEventArgs args) 
+        
+        private void OnPlayerEngineEventChanged (object o, PlayerEngineEventArgs args) 
         {
-            switch (args.Event) {
+            /*switch (args.Event) {
                 case PlayerEngineEvent.Iterate:
                     if(PlayerEngineCore.CurrentTrack != null) {
                         popup.Duration = (uint)PlayerEngineCore.CurrentTrack.Duration.TotalSeconds;
@@ -523,72 +262,39 @@
                          return false;
                     });
                     break;
-            }
-        }
-
-        private void FillPopup() 
-        {
-            can_show_popup = true;
-            popup.Artist = PlayerEngineCore.CurrentTrack.DisplayArtistName;
-            popup.Album = PlayerEngineCore.CurrentTrack.AlbumTitle;
-            popup.TrackTitle = PlayerEngineCore.CurrentTrack.DisplayTrackTitle;
-            try {
-                popup.CoverArtFileName = PlayerEngineCore.CurrentTrack.CoverArtFileName;
-            } catch {
-            }
-            popup.QueueDraw();
-            if (!popup.Visible) {
-                PositionPopup();
-            }
-        }
-
-        private int x, y, w, h;
-        private bool maximized;
-        private void SaveWindowSizePosition()
-        {
-            maximized = ((InterfaceElements.MainWindow.GdkWindow.State & Gdk.WindowState.Maximized) > 0);
-
-            if (!maximized) {
-                InterfaceElements.MainWindow.GetPosition(out x, out y);
-                InterfaceElements.MainWindow.GetSize(out w, out h);
-            }
+            }*/
         }
-
-        private void RestoreWindowSizePosition() 
-        {
-            if (maximized) {
-                InterfaceElements.MainWindow.Maximize();
-            } else {
-                InterfaceElements.MainWindow.Resize(w, h);
-                InterfaceElements.MainWindow.Move(x, y);
-            }
-        }
-
+        
         public bool ShowNotifications {
             get { 
-                show_notifications = ShowNotificationsSchema.Get(); 
+                show_notifications = ShowNotificationsSchema.Get (); 
                 return show_notifications;
             }
+            
             set { 
-                ShowNotificationsSchema.Set(value);
+                ShowNotificationsSchema.Set (value);
                 show_notifications = value;
             }
         }
         
         public bool QuitOnClose {
             get {
-                return QuitOnCloseSchema.Get();
+                return QuitOnCloseSchema.Get ();
             }
             
             set {
-                QuitOnCloseSchema.Set(value);
-                if(value) {
-                    UnregisterCloseHandler();
+                QuitOnCloseSchema.Set (value);
+                if (value) {
+                    UnregisterCloseHandler ();
                 } else {
-                    RegisterCloseHandler();
+                    RegisterCloseHandler ();
                 }
             }
-        }*/
+        }
+    
+        string IService.ServiceName {
+            get { return "NotificationAreaService"; }
+        }
         
         public static readonly SchemaEntry<bool> EnabledSchema = new SchemaEntry<bool>(
             "plugins.notification_area", "enabled",

Copied: trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationArea.cs (from r3271, /trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationArea.cs)
==============================================================================
--- /trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationArea.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationArea.cs	Tue Feb 19 21:07:28 2008
@@ -1,31 +1,35 @@
-/***************************************************************************
- *  NotificationAreaIcon.cs
- *
- * Copyright (C) 2005 Todd Berman <tberman off net>
- * Copyright (C) 2005 Ed Catmur <ed catmur co uk>
- * Copyright (C) 2005 Novell, Inc. (Miguel de Icaza, Aaron Bockover)
- ****************************************************************************/
-
-/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
- *
- *  Permission is hereby granted, free of charge, to any person obtaining a
- *  copy of this software and associated documentation files (the "Software"),  
- *  to deal in the Software without restriction, including without limitation  
- *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
- *  and/or sell copies of the Software, and to permit persons to whom the  
- *  Software is furnished to do so, subject to the following conditions:
- *
- *  The above copyright notice and this permission notice shall be included in 
- *  all copies or substantial portions of the Software.
- *
- *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
- *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
- *  DEALINGS IN THE SOFTWARE.
- */
+//
+// X11NotificationArea.cs
+//
+// Authors:
+//   Todd Berman <tberman off net>
+//   Ed Catmur <ed catmur co uk>
+//   Miguel de Icaza <miguel novell com>
+//   Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2005 Todd Berman
+// Copyright (C) 2005 Ed Catmur
+// Copyright (C) 2005-2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
 
 // NOTE: throughout IntPtr is used for the Xlib long type, as this tends to 
 // have the correct width and does not require any configure checks.
@@ -38,7 +42,7 @@
 
 #pragma warning disable 0169
 
-public class NotificationArea : Plug
+public class X11NotificationArea : Plug
 {
 	private uint stamp;
 	private Orientation orientation;
@@ -51,13 +55,13 @@
 	private IntPtr manager_window;
 	private FilterFunc filter;
 	
-	public NotificationArea (string name)
+	public X11NotificationArea (string name)
 	{
 		Title = name;
 		Init ();
 	}
 
-	public NotificationArea (string name, Gdk.Screen screen)
+	public X11NotificationArea (string name, Gdk.Screen screen)
 	{
 		Title = name;
 		Screen = screen;

Added: trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationAreaBox.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationAreaBox.cs	Tue Feb 19 21:07:28 2008
@@ -0,0 +1,360 @@
+//
+// X11NotificationAreaBox.cs
+//
+// Author:
+//   Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using Mono.Unix;
+using Gtk;
+
+using Banshee.ServiceStack;
+using Banshee.Gui;
+
+namespace Banshee.NotificationArea
+{
+    public class X11NotificationAreaBox : X11NotificationArea, INotificationAreaBox
+    {
+        private EventBox event_box;
+        private Image image;
+        
+        public event EventHandler Disconnected;
+        public event EventHandler Activated;
+        public event PopupMenuHandler PopupMenuEvent;
+        
+        public X11NotificationAreaBox () : base (Catalog.GetString ("Banshee"))
+        {
+            event_box = new EventBox ();
+            image = new Image ();
+            image.IconName = "music-player-banshee";
+            event_box.Add (image);
+            Add (event_box);
+            
+            event_box.ButtonPressEvent += OnButtonPressEvent;
+            //event_box.EnterNotifyEvent += OnEnterNotifyEvent;
+            //event_box.LeaveNotifyEvent += OnLeaveNotifyEvent;
+            //event_box.ScrollEvent += OnMouseScroll;
+            
+            ShowAll ();
+        }
+        
+        public void PositionMenu (Menu menu, out int x, out int y, out bool push_in) 
+        {
+            PositionWidget (menu, out x, out y, 0);
+            push_in = true;
+        }
+        
+        private bool PositionWidget (Widget widget, out int x, out int y, int yPadding) 
+        {
+            int button_y, panel_width, panel_height;
+            Gtk.Requisition requisition = widget.SizeRequest ();
+            
+            event_box.GdkWindow.GetOrigin (out x, out button_y);
+            (event_box.Toplevel as Gtk.Window).GetSize (out panel_width, out panel_height);
+            
+            bool on_bottom = button_y + panel_height + requisition.Height >= event_box.Screen.Height;
+
+            y = on_bottom
+                ? button_y - requisition.Height - yPadding
+                : button_y + panel_height + yPadding;
+                
+            return on_bottom;
+        }
+        
+        private void OnButtonPressEvent (object o, ButtonPressEventArgs args)
+        {
+            if (args.Event.Type != Gdk.EventType.ButtonPress) {
+                return;
+            }
+        
+            switch (args.Event.Button) {
+                case 1:
+                    if ((args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
+                        ServiceManager.PlaybackController.Next ();
+                    } else {
+                        OnActivated ();
+                    }
+                    break;
+                case 2:
+                    ServiceManager.PlayerEngine.TogglePlaying ();
+                    break;
+                case 3:
+                    if ((args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
+                        ServiceManager.PlaybackController.Next ();
+                    } else {
+                        OnPopupMenuEvent ();
+                    }
+                    break;
+            }
+        }
+        
+        protected virtual void OnActivated ()
+        {
+            EventHandler handler = Activated;
+            if (handler != null) {
+                handler (this, EventArgs.Empty);
+            }
+        }
+        
+        protected virtual void OnPopupMenuEvent ()
+        {
+            PopupMenuHandler handler = PopupMenuEvent;
+            if (handler != null) {
+                handler (this, new PopupMenuArgs ());
+            }
+        }
+        
+        protected override bool OnDestroyEvent (Gdk.Event evnt)
+        {
+            bool result = base.OnDestroyEvent (evnt);
+            
+            EventHandler handler = Disconnected;
+            if (handler != null) {
+                handler (this, EventArgs.Empty);
+            }
+            
+            return result;
+        }
+        
+        /*
+        private TrackInfoPopup popup;
+        private bool can_show_popup = false;
+        private bool cursor_over_trayicon = false;
+        private bool show_notifications = false;
+        private TrackInfo current_track = null;
+        private string notify_last_title = null;
+        private string notify_last_artist = null;
+
+        private static readonly uint SkipDelta = 10;
+        private static readonly int VolumeDelta = 10;
+        
+        protected override void PluginInitialize()
+        {
+        }
+        
+        protected override void InterfaceInitialize() 
+        {
+
+            
+            popup = new TrackInfoPopup();
+            PlayerEngineCore.EventChanged += OnPlayerEngineEventChanged;
+
+            // When we're already playing fill the TrackInfoPopup with the current track
+            if (PlayerEngineCore.CurrentState == PlayerEngineState.Playing) {
+                FillPopup();
+            }
+
+            // Forcefully load this value
+            show_notifications = ShowNotifications;
+            elements_service.MainWindow.KeyPressEvent += OnKeyPressEvent;
+        }
+
+        protected override void PluginDispose() 
+        {
+
+        }
+
+        public override Gtk.Widget GetConfigurationWidget()
+        {            
+            return new NotificationAreaIconConfigPage(this);
+        }
+
+        private void ShowNotification()
+        {
+            // This has to happen before the next if, otherwise the last_* members aren't set correctly.
+            if(current_track == null || (notify_last_title == current_track.DisplayTrackTitle 
+                && notify_last_artist == current_track.DisplayArtistName)) {
+                return;
+            }
+            
+            notify_last_title = current_track.DisplayTrackTitle;
+            notify_last_artist = current_track.DisplayArtistName;
+
+            if(cursor_over_trayicon || !show_notifications || elements_service.MainWindow.HasToplevelFocus) {
+                return;
+            }
+            
+            string message = String.Format("{0}\n<i>{1}</i>", 
+                GLib.Markup.EscapeText(current_track.DisplayTrackTitle),
+                GLib.Markup.EscapeText(current_track.DisplayArtistName));
+            
+            Gdk.Pixbuf image = null;
+            
+            try {
+                if(current_track.CoverArtFileName != null) {
+                    image = new Gdk.Pixbuf(current_track.CoverArtFileName);
+                } 
+            } catch {
+            }
+            
+            if(image == null) {
+                image = Branding.DefaultCoverArt;
+            }
+            
+            image = image.ScaleSimple(42, 42, Gdk.InterpType.Bilinear);
+            
+            try {
+                Notification nf = new Notification(Catalog.GetString("Now Playing"), message, image, event_box);
+                nf.Urgency = Urgency.Low;
+                nf.Timeout = 4500;
+                nf.Show();
+            } catch(Exception e) {
+                LogCore.Instance.PushError(Catalog.GetString("Cannot show notification"), e.Message, false);
+            }
+        }
+
+        [GLib.ConnectBefore]
+        private void OnKeyPressEvent(object o, KeyPressEventArgs args)
+        {
+            bool handled = false;
+            
+            if (args.Event.Key == Gdk.Key.w && (args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
+                handled = true;
+                ShowHideMainWindow();
+            }
+            
+            args.RetVal = handled;
+        }
+
+        
+
+        private void OnItemRatingActivated(object o, EventArgs args)
+        {
+            if(PlayerEngineCore.CurrentTrack != null) {
+                PlayerEngineCore.CurrentTrack.Rating = (uint)rating_menu_item.Value;
+                PlayerEngineCore.TrackInfoUpdated();
+            }
+        }
+        
+        private void ToggleRatingMenuSensitive() 
+        {
+            if(PlayerEngineCore.CurrentTrack != null && (SourceManager.ActiveSource is LibrarySource || 
+                SourceManager.ActiveSource is PlaylistSource ||
+                SourceManager.ActiveSource is SmartPlaylistSource)) {
+                rating_menu_item.Reset((int)PlayerEngineCore.CurrentTrack.Rating);
+                rating_menu_item.Show();
+            } else {
+                rating_menu_item.Hide();
+            }
+        }
+
+        private void OnMouseScroll(object o, ScrollEventArgs args) 
+        {
+            switch(args.Event.Direction) {
+                case Gdk.ScrollDirection.Up:
+                    if((args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
+                        PlayerEngineCore.Volume += (ushort)VolumeDelta;
+                    } else if((args.Event.State & Gdk.ModifierType.ShiftMask) != 0) {
+                        PlayerEngineCore.Position += SkipDelta;
+                    } else {
+                        Globals.ActionManager["NextAction"].Activate();
+                    }
+                    break;
+                case Gdk.ScrollDirection.Down:
+                    if((args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
+                        if (PlayerEngineCore.Volume < (ushort)VolumeDelta)
+                            PlayerEngineCore.Volume = 0;
+                        else
+                            PlayerEngineCore.Volume -= (ushort)VolumeDelta;
+                    } else if((args.Event.State & Gdk.ModifierType.ShiftMask) != 0) {
+                        PlayerEngineCore.Position -= SkipDelta;
+                    } else {
+                        Globals.ActionManager["PreviousAction"].Activate();
+                    }
+                    break;
+            }
+        }
+
+        private void HidePopup() 
+        {
+            popup.Hide();
+        }
+        
+        private void ShowPopup() 
+        {
+            PositionPopup();
+            popup.Show();
+        }
+        
+        private void PositionPopup() 
+        {
+            int x, y;
+            Gtk.Requisition event_box_req = event_box.SizeRequest();
+            Gtk.Requisition popup_req = popup.SizeRequest();
+            
+            PositionWidget(popup, out x, out y, 5);
+            
+            x = x - (popup_req.Width / 2) + (event_box_req.Width / 2);     
+            if(x + popup_req.Width >= event_box.Screen.Width) { 
+                x = event_box.Screen.Width - popup_req.Width - 5;
+            } else if(x < 5) {
+                x = 5;
+            }
+            
+            popup.Move(x, y);
+        }
+        
+        private void OnEnterNotifyEvent(object o, EnterNotifyEventArgs args) 
+        {
+            cursor_over_trayicon = true;
+            if(can_show_popup) {
+                // only show the popup when the cursor is still over the
+                // tray icon after 500ms
+                GLib.Timeout.Add(500, delegate {
+                    if ((cursor_over_trayicon) && (can_show_popup)) {
+                        ShowPopup();
+                    }
+                    return false;
+                });
+            }
+        }
+        
+        private void OnLeaveNotifyEvent(object o, LeaveNotifyEventArgs args) 
+        {
+            cursor_over_trayicon = false;
+            HidePopup();
+        }
+
+
+
+        private void FillPopup() 
+        {
+            can_show_popup = true;
+            popup.Artist = PlayerEngineCore.CurrentTrack.DisplayArtistName;
+            popup.Album = PlayerEngineCore.CurrentTrack.AlbumTitle;
+            popup.TrackTitle = PlayerEngineCore.CurrentTrack.DisplayTrackTitle;
+            try {
+                popup.CoverArtFileName = PlayerEngineCore.CurrentTrack.CoverArtFileName;
+            } catch {
+            }
+            popup.QueueDraw();
+            if (!popup.Visible) {
+                PositionPopup();
+            }
+        }
+
+        */
+    }
+}

Modified: trunk/banshee/src/Extensions/Banshee.NotificationArea/Makefile.am
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.NotificationArea/Makefile.am	(original)
+++ trunk/banshee/src/Extensions/Banshee.NotificationArea/Makefile.am	Tue Feb 19 21:07:28 2008
@@ -3,8 +3,11 @@
 LINK = $(REF_EXTENSION_NOTIFICATIONAREA)
 
 SOURCES =  \
-	Banshee.NotificationArea/NotificationArea.cs \
-	Banshee.NotificationArea/NotificationAreaService.cs 
+	Banshee.NotificationArea/GtkNotificationAreaBox.cs \
+	Banshee.NotificationArea/INotificationAreaBox.cs \
+	Banshee.NotificationArea/NotificationAreaService.cs \
+	Banshee.NotificationArea/X11NotificationArea.cs \
+	Banshee.NotificationArea/X11NotificationAreaBox.cs 
 
 RESOURCES =  \
 	Resources/Banshee.NotificationArea.addin.xml \

Modified: trunk/banshee/src/Extensions/Banshee.NotificationArea/Resources/Banshee.NotificationArea.addin.xml
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.NotificationArea/Resources/Banshee.NotificationArea.addin.xml	(original)
+++ trunk/banshee/src/Extensions/Banshee.NotificationArea/Resources/Banshee.NotificationArea.addin.xml	Tue Feb 19 21:07:28 2008
@@ -7,7 +7,7 @@
     name="Notification Area Icon"
     category="User Interface"
     description="Displays an icon in the notification area and allows Banshee to be controlled through it."
-    author="Sebastian DrÃge, Aaron Bockover, Gabriel Burt, Ruben Vermeersch"
+    author="Aaron Bockover, Sebastian DrÃge, Gabriel Burt, Ruben Vermeersch"
     url="http://banshee-project.org/";
     defaultEnabled="true">
 

Modified: trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.mdp
==============================================================================
--- trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.mdp	(original)
+++ trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.mdp	Tue Feb 19 21:07:28 2008
@@ -59,6 +59,7 @@
     <ProjectReference type="Project" localcopy="False" refto="Hyena" />
     <ProjectReference type="Gac" localcopy="True" refto="pango-sharp, Version=2.8.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
   </References>
+  <Deployment.LinuxDeployData generateScript="False" />
   <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="True" RelativeMakefileName="Makefile.am">
     <BuildFilesVar Sync="True" Name="SOURCES" />
     <DeployFilesVar />
@@ -68,5 +69,4 @@
     <AsmRefVar />
     <ProjectRefVar />
   </MonoDevelop.Autotools.MakefileInfo>
-  <Deployment.LinuxDeployData generateScript="False" />
 </Project>
\ No newline at end of file

Modified: trunk/banshee/src/Libraries/Hyena/Hyena.mdp
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.mdp	(original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.mdp	Tue Feb 19 21:07:28 2008
@@ -86,6 +86,7 @@
     <ProjectReference type="Gac" localcopy="True" refto="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
     <ProjectReference type="Gac" localcopy="True" refto="Mono.Data.Sqlite, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
   </References>
+  <Deployment.LinuxDeployData generateScript="False" />
   <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="True" RelativeMakefileName="Makefile.am">
     <BuildFilesVar Sync="True" Name="SOURCES" />
     <DeployFilesVar />
@@ -95,5 +96,4 @@
     <AsmRefVar />
     <ProjectRefVar />
   </MonoDevelop.Autotools.MakefileInfo>
-  <Deployment.LinuxDeployData generateScript="False" />
 </Project>
\ No newline at end of file



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