Index: gtkstatusicon.c
===================================================================
--- gtkstatusicon.c	(revision 19215)
+++ gtkstatusicon.c	(working copy)
@@ -39,6 +39,7 @@
 
 #include "gtkprivate.h"
 #include "gtkwidget.h"
+#include "gdk/gdkkeysyms.h"
 
 #ifdef GDK_WINDOWING_WIN32
 #include "gtkicontheme.h"
@@ -152,6 +153,9 @@
 #endif
 static gboolean gtk_status_icon_button_press     (GtkStatusIcon  *status_icon,
 						  GdkEventButton *event);
+static gboolean gtk_status_icon_key_press (GtkStatusIcon *status_icon,
+                                           GdkEventKey *event);
+static gboolean gtk_status_icon_popup_menu (GtkStatusIcon *status_icon);
 static void     gtk_status_icon_disable_blinking (GtkStatusIcon  *status_icon);
 static void     gtk_status_icon_reset_image_data (GtkStatusIcon  *status_icon);
 					   
@@ -494,11 +498,16 @@
 			    G_CALLBACK (gtk_status_icon_orientation_changed), status_icon);
   g_signal_connect_swapped (priv->tray_icon, "button-press-event",
 			    G_CALLBACK (gtk_status_icon_button_press), status_icon);
+  g_signal_connect_swapped (priv->tray_icon, "key-press-event",
+                            G_CALLBACK (gtk_status_icon_key_press), status_icon);
+  g_signal_connect_swapped (priv->tray_icon, "popup_menu",
+                            G_CALLBACK (gtk_status_icon_popup_menu), status_icon);
   g_signal_connect_swapped (priv->tray_icon, "screen-changed",
 		    	    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);
+  GTK_WIDGET_SET_FLAGS (priv->image, GTK_CAN_FOCUS);
 
   g_signal_connect_swapped (priv->image, "size-allocate",
 			    G_CALLBACK (gtk_status_icon_size_allocate), status_icon);
@@ -1218,6 +1227,28 @@
   return FALSE;
 }
 
+static gboolean
+gtk_status_icon_key_press (GtkStatusIcon *status_icon,
+                           GdkEventKey *event)
+{
+  if (((event->state & gtk_accelerator_get_default_mod_mask ()) == 0)
+      && (event->keyval == GDK_Return || event->keyval == GDK_space 
+          || event->keyval == GDK_ISO_Enter || event->keyval ==GDK_KP_Enter ))
+    {
+      emit_activate_signal (status_icon);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+gtk_status_icon_popup_menu (GtkStatusIcon *status_icon)
+{
+  emit_popup_menu_signal (status_icon, 0, gtk_get_current_event_time ());
+  return TRUE; 
+}
+
 static void
 gtk_status_icon_reset_image_data (GtkStatusIcon *status_icon)
 {
Index: gtktrayicon-x11.c
===================================================================
--- gtktrayicon-x11.c	(revision 19215)
+++ gtktrayicon-x11.c	(working copy)
@@ -139,9 +139,30 @@
 gtk_tray_icon_expose (GtkWidget      *widget, 
 		      GdkEventExpose *event)
 {
+  gint border_width;
+  gint x, y, width, height;
+  GtkWidget *focus_child;
+
   gdk_window_clear_area (widget->window, event->area.x, event->area.y,
 			 event->area.width, event->area.height);
 
+  focus_child = GTK_CONTAINER (widget)->focus_child;
+  if (focus_child && GTK_WIDGET_HAS_FOCUS (focus_child))
+    {
+      border_width = GTK_CONTAINER (widget)->border_width;
+
+      x = widget->allocation.x;
+      y = widget->allocation.y;
+
+      width  = widget->allocation.width  - 2 * border_width;
+      height = widget->allocation.height - 2 * border_width;
+
+      gtk_paint_focus (widget->style, widget->window,
+                       GTK_WIDGET_STATE (widget),
+                       &event->area, widget, "tray_icon",
+                       x, y, width, height);
+    }
+
   if (GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->expose_event)  
     return GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->expose_event (widget, event);
 
