=== modified file 'gdk/gdkwindow.h'
--- gdk/gdkwindow.h	
+++ gdk/gdkwindow.h	
@@ -463,6 +463,8 @@ void	      gdk_window_set_title	   (GdkW
 					    const gchar	  *title);
 void          gdk_window_set_role          (GdkWindow       *window,
 					    const gchar     *role);
+void          gdk_window_set_startup_id    (GdkWindow       *window,
+					    const gchar     *startup_id);					  
 void          gdk_window_set_transient_for (GdkWindow       *window, 
 					    GdkWindow       *parent);
 void	      gdk_window_set_background	 (GdkWindow	  *window,
=== modified file 'gdk/x11/gdkdisplay-x11.c'
--- gdk/x11/gdkdisplay-x11.c	
+++ gdk/x11/gdkdisplay-x11.c	
@@ -1219,5 +1219,20 @@ gdk_x11_display_get_user_time (GdkDispla
   return GDK_DISPLAY_X11 (display)->user_time;
 }
 
+/**
+ * gdk_x11_display_get_startup_notification_id:
+ * @display: a #GdkDisplay
+ *
+ * Returns: the startup notification ID for 
+ * @display.
+ *
+ * Since: 2.12
+ */
+G_CONST_RETURN gchar *
+gdk_x11_display_get_startup_notification_id (GdkDisplay *display)
+{
+  return GDK_DISPLAY_X11 (display)->startup_notification_id;
+}
+
 #define __GDK_DISPLAY_X11_C__
 #include "gdkaliasdef.c"
=== modified file 'gdk/x11/gdkwindow-x11.c'
--- gdk/x11/gdkwindow-x11.c	
+++ gdk/x11/gdkwindow-x11.c	
@@ -2806,6 +2806,40 @@ gdk_window_set_role (GdkWindow   *window
 }
 
 /**
+ * gdk_window_set_startup_id:
+ * @window: a toplevel #GdkWindow
+ * @startup_id: a string with startup-notification identifier
+ *
+ * When using GTK+, typically you should use gtk_window_set_startup_id()
+ * instead of this low-level function.
+ *
+ * Since: 2.12
+ *
+ **/
+void          
+gdk_window_set_startup_id (GdkWindow   *window,
+		     const gchar *startup_id)
+{
+  GdkDisplay *display;
+  
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  display = gdk_drawable_get_display (window);
+
+  if (!GDK_WINDOW_DESTROYED (window))
+    {
+      if (startup_id)
+	XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+			 gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"), 
+			 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
+			 PropModeReplace, startup_id, strlen (startup_id));
+      else
+	XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+			 gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"));
+    }
+}
+
+/**
  * gdk_window_set_transient_for:
  * @window: a toplevel #GdkWindow
  * @parent: another toplevel #GdkWindow
=== modified file 'gdk/x11/gdkx.h'
--- gdk/x11/gdkx.h	
+++ gdk/x11/gdkx.h	
@@ -142,6 +142,8 @@ gpointer      gdk_xid_table_lookup_for_d
 guint32       gdk_x11_get_server_time  (GdkWindow       *window);
 guint32       gdk_x11_display_get_user_time (GdkDisplay *display);
 
+G_CONST_RETURN gchar *gdk_x11_display_get_startup_notification_id (GdkDisplay *display);
+
 void          gdk_x11_display_set_cursor_theme (GdkDisplay  *display,
 						const gchar *theme,
 						const gint   size);
=== modified file 'gtk/gtkwindow.c'
--- gtk/gtkwindow.c	
+++ gtk/gtkwindow.c	
@@ -26,6 +26,8 @@
 
 #include <config.h>
 #include <string.h>
+#include <stdlib.h>
+#include <errno.h>
 #include <limits.h>
 #include "gdk/gdk.h"
 #include "gdk/gdkkeysyms.h"
@@ -93,6 +95,9 @@ enum {
   PROP_IS_ACTIVE,
   PROP_HAS_TOPLEVEL_FOCUS,
   
+  /* Writeonly properties */
+  PROP_STARTUP_ID,
+  
   LAST_ARG
 };
 
@@ -170,6 +175,8 @@ struct _GtkWindowPrivate
   guint urgent : 1;
   guint accept_focus : 1;
   guint focus_on_map : 1;
+  
+  gchar *startup_id;
 };
 
 static void gtk_window_class_init         (GtkWindowClass    *klass);
@@ -358,6 +365,28 @@ add_arrow_bindings (GtkBindingSet    *bi
                                 GTK_TYPE_DIRECTION_TYPE, direction);
 }
 
+static guint32
+extract_time_from_startup_id (const gchar* startup_id)
+{
+  gchar* timestr = g_strrstr (startup_id, "_TIME");
+	
+  if (timestr != NULL)
+    {
+      gchar *end;
+      errno = 0;
+      guint32 timestamp; 
+    
+      /* Skip past the "_TIME" part */
+      timestr += 5;
+    
+      timestamp = strtoul (timestr, &end, 0);
+      if (end != timestr && errno == 0)
+        return timestamp;
+    }
+  
+  return GDK_CURRENT_TIME;
+}
+
 
 static void
 gtk_window_class_init (GtkWindowClass *klass)
@@ -440,6 +469,23 @@ gtk_window_class_init (GtkWindowClass *k
 							P_("Unique identifier for the window to be used when restoring a session"),
 							NULL,
 							GTK_PARAM_READWRITE));
+							
+  /**
+   * GtkWindow:startup-id:
+   *
+   * The :startup-id is a write-only property for setting window's
+   * startup notification identifier. See gtk_window_set_startup_id()
+   * for more details.
+   *
+   * Since: 2.12
+   */							
+  g_object_class_install_property (gobject_class,
+                                   PROP_ROLE,
+                                   g_param_spec_string ("startup-id",
+							P_("Startup ID"),
+							P_("Unique startup identifier for the window used by startup-notification"),
+							NULL,
+							GTK_PARAM_WRITABLE));
 
   g_object_class_install_property (gobject_class,
                                    PROP_ALLOW_SHRINK,
@@ -786,6 +832,7 @@ gtk_window_init (GtkWindow *window)
 
   priv->accept_focus = TRUE;
   priv->focus_on_map = TRUE;
+  priv->startup_id = NULL;
 
   colormap = _gtk_widget_peek_colormap ();
   if (colormap)
@@ -825,6 +872,9 @@ gtk_window_set_property (GObject      *o
     case PROP_ROLE:
       gtk_window_set_role (window, g_value_get_string (value));
       break;
+    case PROP_STARTUP_ID:
+      gtk_window_set_startup_id (window, g_value_get_string (value));
+      break; 
     case PROP_ALLOW_SHRINK:
       window->allow_shrink = g_value_get_boolean (value);
       gtk_widget_queue_resize (GTK_WIDGET (window));
@@ -1167,6 +1217,51 @@ gtk_window_set_role (GtkWindow   *window
 }
 
 /**
+ * gtk_window_set_startup_id:
+ * @window: a #GtkWindow
+ * @startup_id: a string with startup-notification identifier
+ *
+ * Startup notification identifiers are used by desktop environment to 
+ * track application startup, to provide user feedback and other 
+ * features. This function changes the corresponding property on the
+ * underlying GdkWindow. Normally, startup identifier is managed 
+ * automatically and you should only use this function in special cases
+ * like transferring focus from other processes.
+ *
+ * This function is only useful on X11, not with other GTK+ targets.
+ * 
+ * Since: 2.12
+ **/
+void
+gtk_window_set_startup_id (GtkWindow   *window,
+                           const gchar *startup_id)
+{
+  char *new_id;
+  
+  g_return_if_fail (GTK_IS_WINDOW (window));
+  GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
+
+  new_id = g_strdup (startup_id);
+  g_free (private->startup_id);
+  private->startup_id = new_id;
+  
+  if (GTK_WIDGET_REALIZED (window))
+    {
+      /* Here we differentiate real and "fake" startup notification IDs,
+       * constructed on purpose just to pass interaction timestamp
+       */  
+      if (strncmp (new_id, "_TIME", 5) == 0)
+        {
+          guint32 timestamp = extract_time_from_startup_id (new_id);
+          gtk_window_present_with_time (window, timestamp);
+        }
+      else gdk_window_set_startup_id (GTK_WIDGET (window)->window, private->startup_id);
+    }
+
+  g_object_notify (G_OBJECT (window), "startup-id");
+}
+
+/**
  * gtk_window_get_role:
  * @window: a #GtkWindow
  *
@@ -4081,6 +4176,7 @@ gtk_window_realize (GtkWidget *widget)
   gint attributes_mask;
   
   window = GTK_WINDOW (widget);
+  GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
 
   /* ensure widget tree is properly size allocated */
   if (widget->allocation.x == -1 &&
@@ -4225,6 +4321,17 @@ gtk_window_realize (GtkWidget *widget)
     gdk_window_set_modal_hint (widget->window, TRUE);
   else
     gdk_window_set_modal_hint (widget->window, FALSE);
+    
+  if (private->startup_id)
+    {
+#ifdef GDK_WINDOWING_X11
+      guint32 timestamp = extract_time_from_startup_id (private->startup_id);
+      if (timestamp != GDK_CURRENT_TIME)
+        gdk_x11_window_set_user_time (widget->window, timestamp);
+#endif
+
+      gdk_window_set_startup_id (widget->window, private->startup_id);
+    }
 
   /* Icons */
   gtk_window_realize_icon (window);
=== modified file 'gtk/gtkwindow.h'
--- gtk/gtkwindow.h	
+++ gtk/gtkwindow.h	
@@ -177,6 +177,8 @@ void       gtk_window_set_wmclass       
 						const gchar         *wmclass_class);
 void       gtk_window_set_role                 (GtkWindow           *window,
                                                 const gchar         *role);
+void       gtk_window_set_startup_id           (GtkWindow           *window,
+                                                const gchar         *startup_id);
 G_CONST_RETURN gchar *gtk_window_get_role      (GtkWindow           *window);
 void       gtk_window_add_accel_group          (GtkWindow           *window,
 						GtkAccelGroup	    *accel_group);
