Index: gtk/gtkstatusicon.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkstatusicon.c,v
retrieving revision 1.30
diff -p -u -B -r1.30 gtkstatusicon.c
--- gtk/gtkstatusicon.c	22 Dec 2006 07:18:20 -0000	1.30
+++ gtk/gtkstatusicon.c	22 Dec 2006 14:39:07 -0000
@@ -128,6 +128,9 @@ struct _GtkStatusIconPrivate
   guint         visible : 1;
 };
 
+static GObject* gtk_status_icon_constructor      (GType                  type,
+                                                  guint                  n_construct_properties,
+                                                  GObjectConstructParam *construct_params);
 static void     gtk_status_icon_finalize         (GObject        *object);
 static void     gtk_status_icon_set_property     (GObject        *object,
 						  guint           prop_id,
@@ -160,6 +163,7 @@ gtk_status_icon_class_init (GtkStatusIco
 {
   GObjectClass *gobject_class = (GObjectClass *) class;
 
+  gobject_class->constructor  = gtk_status_icon_constructor;
   gobject_class->finalize     = gtk_status_icon_finalize;
   gobject_class->set_property = gtk_status_icon_set_property;
   gobject_class->get_property = gtk_status_icon_get_property;
@@ -475,13 +479,11 @@ gtk_status_icon_init (GtkStatusIcon *sta
 		    	    G_CALLBACK (gtk_status_icon_screen_changed), status_icon);
   priv->image = gtk_image_new ();
   gtk_container_add (GTK_CONTAINER (priv->tray_icon), priv->image);
+  gtk_widget_show (priv->image);
 
   g_signal_connect_swapped (priv->image, "size-allocate",
 			    G_CALLBACK (gtk_status_icon_size_allocate), status_icon);
 
-  gtk_widget_show (priv->image);
-  gtk_widget_show (priv->tray_icon);
-
   status_icon->priv->tooltips = gtk_tooltips_new ();
   g_object_ref_sink (priv->tooltips);
 #endif
@@ -540,6 +542,30 @@ gtk_status_icon_init (GtkStatusIcon *sta
 #endif 
 }
 
+static GObject*
+gtk_status_icon_constructor (GType                  type,
+                             guint                  n_construct_properties,
+                             GObjectConstructParam *construct_params)
+{
+  GObject *object;
+  GtkStatusIcon *status_icon;
+  GtkStatusIconPrivate *priv;
+  
+  object = G_OBJECT_CLASS (gtk_status_icon_parent_class)->constructor (type,
+                                                                       n_construct_properties,
+                                                                       construct_params);
+
+#ifdef GDK_WINDOWING_X11
+  status_icon = GTK_STATUS_ICON (object);
+  priv = status_icon->priv;
+  
+  if (priv->visible)
+    gtk_widget_show (priv->tray_icon);
+#endif
+
+  return object;
+}
+
 static void
 gtk_status_icon_finalize (GObject *object)
 {
@@ -1623,8 +1649,10 @@ gtk_status_icon_set_visible (GtkStatusIc
 #ifdef GDK_WINDOWING_X11
       if (visible)
 	gtk_widget_show (priv->tray_icon);
-      else
+      else if (GTK_WIDGET_REALIZED (priv->tray_icon)) {
 	gtk_widget_hide (priv->tray_icon);
+	gtk_widget_unrealize (priv->tray_icon);
+      }
 #endif
 #ifdef GDK_WINDOWING_WIN32
       if (priv->nid.hWnd != NULL)
Index: gtk/gtktrayicon-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktrayicon-x11.c,v
retrieving revision 1.6
diff -p -u -B -r1.6 gtktrayicon-x11.c
--- gtk/gtktrayicon-x11.c	17 Aug 2006 17:35:55 -0000	1.6
+++ gtk/gtktrayicon-x11.c	22 Dec 2006 14:39:07 -0000
@@ -72,8 +72,7 @@ static gboolean gtk_tray_icon_delete    
 static gboolean gtk_tray_icon_expose    (GtkWidget      *widget, 
 					 GdkEventExpose *event);
 
-static void gtk_tray_icon_update_manager_window    (GtkTrayIcon *icon,
-						    gboolean     dock_if_realized);
+static void gtk_tray_icon_update_manager_window    (GtkTrayIcon *icon);
 static void gtk_tray_icon_manager_window_destroyed (GtkTrayIcon *icon);
 
 G_DEFINE_TYPE (GtkTrayIcon, gtk_tray_icon, GTK_TYPE_PLUG)
@@ -213,19 +212,31 @@ gtk_tray_icon_manager_filter (GdkXEvent 
       xev->xclient.message_type == icon->priv->manager_atom &&
       xev->xclient.data.l[1] == icon->priv->selection_atom)
     {
-      gtk_tray_icon_update_manager_window (icon, TRUE);
+      GTK_NOTE (PLUGSOCKET,
+		g_print ("GtkStatusIcon %p: tray manager appeared\n", icon));
+
+      gtk_tray_icon_update_manager_window (icon);
     }
   else if (xev->xany.window == icon->priv->manager_window)
     {
       if (xev->xany.type == PropertyNotify &&
 	  xev->xproperty.atom == icon->priv->orientation_atom)
 	{
+          GTK_NOTE (PLUGSOCKET,
+		    g_print ("GtkStatusIcon %p: got PropertyNotify on manager window for orientation atom\n", icon));
+
 	  gtk_tray_icon_get_orientation_property (icon);
 	}
-      if (xev->xany.type == DestroyNotify)
+      else if (xev->xany.type == DestroyNotify)
 	{
+          GTK_NOTE (PLUGSOCKET,
+		    g_print ("GtkStatusIcon %p: got DestroyNotify for manager window\n", icon));
+
 	  gtk_tray_icon_manager_window_destroyed (icon);
 	}
+      else
+        GTK_NOTE (PLUGSOCKET,
+		  g_print ("GtkStatusIcon %p: got other message on manager window\n", icon));
     }
   
   return GDK_FILTER_CONTINUE;
@@ -237,6 +248,9 @@ gtk_tray_icon_unrealize (GtkWidget *widg
   GtkTrayIcon *icon = GTK_TRAY_ICON (widget);
   GdkWindow *root_window;
 
+  GTK_NOTE (PLUGSOCKET,
+	    g_print ("GtkStatusIcon %p: unrealizing\n", icon));
+
   if (icon->priv->manager_window != None)
     {
       GdkWindow *gdkwin;
@@ -245,14 +259,15 @@ gtk_tray_icon_unrealize (GtkWidget *widg
                                               icon->priv->manager_window);
       
       gdk_window_remove_filter (gdkwin, gtk_tray_icon_manager_filter, icon);
+
+      icon->priv->manager_window = None;
     }
 
   root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget));
 
   gdk_window_remove_filter (root_window, gtk_tray_icon_manager_filter, icon);
 
-  if (GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->unrealize)
-    (* GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->unrealize) (widget);
+  GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->unrealize (widget);
 }
 
 static void
@@ -288,6 +303,10 @@ gtk_tray_icon_send_manager_message (GtkT
 static void
 gtk_tray_icon_send_dock_request (GtkTrayIcon *icon)
 {
+  GTK_NOTE (PLUGSOCKET,
+	    g_print ("GtkStatusIcon %p: sending dock request to manager window %x\n",
+	    	     icon, icon->priv->manager_window));
+
   gtk_tray_icon_send_manager_message (icon,
 				      SYSTEM_TRAY_REQUEST_DOCK,
 				      icon->priv->manager_window,
@@ -296,14 +315,22 @@ gtk_tray_icon_send_dock_request (GtkTray
 }
 
 static void
-gtk_tray_icon_update_manager_window (GtkTrayIcon *icon,
-				     gboolean     dock_if_realized)
+gtk_tray_icon_update_manager_window (GtkTrayIcon *icon)
 {
   Display *xdisplay;
-  
+
+  g_return_if_fail (GTK_WIDGET_REALIZED (icon));
+
+  GTK_NOTE (PLUGSOCKET,
+	    g_print ("GtkStatusIcon %p: updating tray icon manager window, current manager window: %x\n",
+		     icon, icon->priv->manager_window));
+
   if (icon->priv->manager_window != None)
     return;
 
+  GTK_NOTE (PLUGSOCKET,
+	    g_print ("GtkStatusIcon %p: trying to find manager window\n", icon));
+
   xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
   
   XGrabServer (xdisplay);
@@ -322,33 +349,40 @@ gtk_tray_icon_update_manager_window (Gtk
     {
       GdkWindow *gdkwin;
 
+      GTK_NOTE (PLUGSOCKET,
+		g_print ("GtkStatusIcon %p: is being managed by window %x\n",
+				icon, icon->priv->manager_window));
+
       gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
 					      icon->priv->manager_window);
       
       gdk_window_add_filter (gdkwin, gtk_tray_icon_manager_filter, icon);
 
-      if (dock_if_realized && GTK_WIDGET_REALIZED (icon))
-	gtk_tray_icon_send_dock_request (icon);
+      gtk_tray_icon_send_dock_request (icon);
 
       gtk_tray_icon_get_orientation_property (icon);
     }
+  else
+    GTK_NOTE (PLUGSOCKET,
+	      g_print ("GtkStatusIcon %p: no tray manager found\n", icon));
 }
 
 static void
 gtk_tray_icon_manager_window_destroyed (GtkTrayIcon *icon)
 {
+  GtkWidget *widget = GTK_WIDGET (icon);
   GdkWindow *gdkwin;
-  
+
+  g_return_if_fail (GTK_WIDGET_REALIZED (icon));
   g_return_if_fail (icon->priv->manager_window != None);
 
-  gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
-					  icon->priv->manager_window);
-      
-  gdk_window_remove_filter (gdkwin, gtk_tray_icon_manager_filter, icon);
+  GTK_NOTE (PLUGSOCKET,
+	    g_print ("GtkStatusIcon %p: tray manager window destroyed\n", icon));
 
-  icon->priv->manager_window = None;
+  gtk_widget_hide (widget);
+  gtk_widget_unrealize (widget);
 
-  gtk_tray_icon_update_manager_window (icon, TRUE);
+  gtk_widget_show (widget);
 }
 
 static gboolean 
@@ -358,17 +392,14 @@ gtk_tray_icon_delete (GtkWidget   *widge
   GtkTrayIcon *icon = GTK_TRAY_ICON (widget);
   GdkWindow *gdkwin;
 
-  if (icon->priv->manager_window != None)
-    {  
-      gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
-					      icon->priv->manager_window);
-      
-      gdk_window_remove_filter (gdkwin, gtk_tray_icon_manager_filter, icon);
-      
-      icon->priv->manager_window = None;
-    }
+  GTK_NOTE (PLUGSOCKET,
+	    g_print ("GtkStatusIcon %p: delete notify, tray manager window %x\n",
+	    	     icon, icon->priv->manager_window));
+
+  gtk_widget_hide (widget);
+  gtk_widget_unrealize (widget);
 
-  gtk_tray_icon_update_manager_window (icon, TRUE);  
+  gtk_widget_show (widget);
 
   return TRUE;
 }
@@ -383,8 +414,14 @@ gtk_tray_icon_realize (GtkWidget *widget
   char buffer[256];
   GdkWindow *root_window;
 
-  if (GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->realize)
-    GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->realize (widget);
+  GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->realize (widget);
+
+  GTK_NOTE (PLUGSOCKET,
+	    g_print ("GtkStatusIcon %p: realized, window: %x, socket window: %x\n",
+		     widget,
+		     GDK_WINDOW_XWINDOW (widget->window),
+		     GTK_PLUG (icon)->socket_window ?
+			     GDK_WINDOW_XWINDOW (GTK_PLUG (icon)->socket_window) : 0));
 
   screen = gtk_widget_get_screen (widget);
   display = gdk_screen_get_display (screen);
@@ -407,8 +444,7 @@ gtk_tray_icon_realize (GtkWidget *widget
 					      "_NET_SYSTEM_TRAY_ORIENTATION",
 					      False);
 
-  gtk_tray_icon_update_manager_window (icon, FALSE);
-  gtk_tray_icon_send_dock_request (icon);
+  gtk_tray_icon_update_manager_window (icon);
 
   root_window = gdk_screen_get_root_window (screen);
   
Index: tests/teststatusicon.c
===================================================================
RCS file: /cvs/gnome/gtk+/tests/teststatusicon.c,v
retrieving revision 1.5
diff -p -u -B -r1.5 teststatusicon.c
--- tests/teststatusicon.c	22 Dec 2006 07:18:21 -0000	1.5
+++ tests/teststatusicon.c	22 Dec 2006 14:39:07 -0000
@@ -22,6 +22,7 @@
  */
 
 #include <gtk/gtk.h>
+#include "prop-editor.h"
 
 typedef enum
 {
@@ -57,6 +58,13 @@ orientation_changed_cb (GtkStatusIcon *i
 }
 
 static void
+screen_changed_cb (GtkStatusIcon *icon)
+{
+  g_print ("status icon %p screen changed to %p\n", icon,
+	   gtk_status_icon_get_screen (icon));
+}
+
+static void
 update_icons (void)
 {
   GSList *l;
@@ -66,7 +74,7 @@ update_icons (void)
   if (status == TEST_STATUS_INFO)
     {
       icon_name = GTK_STOCK_DIALOG_INFO;
-      tooltip = "Some Infromation ...";
+      tooltip = "Some Information ...";
     }
   else
     {
@@ -216,6 +224,20 @@ check_activated (GtkCheckMenuItem *item)
 }
 
 static void
+do_properties (GtkMenuItem   *item,
+	       GtkStatusIcon *icon)
+{
+	static GtkWidget *editor = NULL;
+
+	if (editor == NULL) {
+		editor = create_prop_editor (G_OBJECT (icon), GTK_TYPE_STATUS_ICON);
+		g_signal_connect (editor, "destroy", G_CALLBACK (gtk_widget_destroyed), &editor);
+	}
+
+	gtk_window_present (GTK_WINDOW (editor));
+}
+
+static void
 do_quit (GtkMenuItem *item)
 {
   GSList *l;
@@ -255,6 +277,13 @@ popup_menu (GtkStatusIcon *icon,
 
   gtk_widget_show (menuitem);
 
+  menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PROPERTIES, NULL);
+  g_signal_connect (menuitem, "activate", G_CALLBACK (do_properties), icon);
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+
+  gtk_widget_show (menuitem);
+
   menuitem = gtk_menu_item_new_with_label ("Quit");
   g_signal_connect (menuitem, "activate", G_CALLBACK (do_quit), NULL);
 
@@ -263,7 +292,8 @@ popup_menu (GtkStatusIcon *icon,
   gtk_widget_show (menuitem);
 
   gtk_menu_popup (GTK_MENU (menu), 
-		  NULL, NULL, NULL, NULL, 
+		  NULL, NULL,
+		  gtk_status_icon_position_menu, icon,
 		  button, activate_time);
 }
 
@@ -290,6 +320,7 @@ main (int argc, char **argv)
       g_signal_connect (icon, "size-changed", G_CALLBACK (size_changed_cb), NULL);
       g_signal_connect (icon, "notify::embedded", G_CALLBACK (embedded_changed_cb), NULL);
       g_signal_connect (icon, "notify::orientation", G_CALLBACK (orientation_changed_cb), NULL);
+      g_signal_connect (icon, "notify::screen", G_CALLBACK (screen_changed_cb), NULL);
       g_print ("icon size %d\n", gtk_status_icon_get_size (icon));
       gtk_status_icon_set_blinking (GTK_STATUS_ICON (icon), FALSE);
 
@@ -300,7 +331,8 @@ main (int argc, char **argv)
                         G_CALLBACK (popup_menu), NULL);
 
       icons = g_slist_append (icons, icon);
- 
+
+      update_icons ();
       timeout = g_timeout_add (2000, timeout_handler, icon);
     }
 
Index: tests/Makefile.am
===================================================================
RCS file: /cvs/gnome/gtk+/tests/Makefile.am,v
retrieving revision 1.65
diff -p -u -B -r1.65 Makefile.am
--- tests/Makefile.am	28 Aug 2006 16:14:39 -0000	1.65
+++ tests/Makefile.am	22 Dec 2006 14:39:07 -0000
@@ -247,6 +247,7 @@ testspinbutton_SOURCES =    	\
 	testspinbutton.c
 
 teststatusicon_SOURCES =    	\
+	prop-editor.c		\
 	teststatusicon.c
 
 testmerge_SOURCES = 		\
