Index: configure.in
===================================================================
RCS file: /cvs/gnome/epiphany/configure.in,v
retrieving revision 1.180
diff -u -p -r1.180 configure.in
--- configure.in	12 Aug 2004 10:30:50 -0000	1.180
+++ configure.in	16 Aug 2004 10:06:06 -0000
@@ -64,9 +64,13 @@ PKG_CHECK_MODULES(EPIPHANY_DEPENDENCY, \
 		  gnome-vfs-2.0 >= $LIBGNOMEVFS_REQUIRED \
 		  gnome-vfs-module-2.0 \
 		  gconf-2.0 \
+		  libstartup-notification-1.0 \
 		 )
 AC_SUBST(EPIPHANY_DEPENDENCY_CFLAGS)
 AC_SUBST(EPIPHANY_DEPENDENCY_LIBS)
+
+dnl we need to define this to use libstartup-notification
+AC_DEFINE_UNQUOTED([SN_API_NOT_YET_FROZEN],[1],[This sucks])
 
 ORBIT_IDL="`$PKG_CONFIG --variable=orbit_idl ORBit-2.0`"
 AC_SUBST(ORBIT_IDL)
Index: idl/EphyAutomation.idl
===================================================================
RCS file: /cvs/gnome/epiphany/idl/EphyAutomation.idl,v
retrieving revision 1.8
diff -u -p -r1.8 EphyAutomation.idl
--- idl/EphyAutomation.idl	13 Nov 2003 14:02:03 -0000	1.8
+++ idl/EphyAutomation.idl	16 Aug 2004 10:06:07 -0000
@@ -6,15 +6,16 @@ module GNOME {
 		void loadurl  (in string  url, 
 		               in boolean fullscreen,
 			       in boolean open_in_existing_tab,
-			       in boolean open_in_new_tab);
+			       in boolean open_in_new_tab,
+			       in string startup_id);
 
 		void addBookmark (in string url);
 
 		void importBookmarks (in string filename);
 
-		void loadSession (in string filename);
+		void loadSession (in string filename,
+				  in string startup_id);
 
-		void openBookmarksEditor ();
+		void openBookmarksEditor (in string startup_id);
 	};
 };
-
Index: src/.cvsignore
===================================================================
RCS file: /cvs/gnome/epiphany/src/.cvsignore,v
retrieving revision 1.4
diff -u -p -r1.4 .cvsignore
--- src/.cvsignore	28 Jun 2003 14:56:47 -0000	1.4
+++ src/.cvsignore	16 Aug 2004 10:06:07 -0000
@@ -8,5 +8,4 @@ EphyAutomation-common.c
 EphyAutomation-skels.c
 EphyAutomation-stubs.c
 EphyAutomation.h
-epiphany-bin
 ephy_automation_interface_idl_stamp
Index: src/ephy-automation.c
===================================================================
RCS file: /cvs/gnome/epiphany/src/ephy-automation.c,v
retrieving revision 1.21
diff -u -p -r1.21 ephy-automation.c
--- src/ephy-automation.c	8 May 2004 20:13:13 -0000	1.21
+++ src/ephy-automation.c	16 Aug 2004 10:06:07 -0000
@@ -49,6 +49,7 @@ impl_ephy_automation_loadurl (PortableSe
 			      const CORBA_boolean fullscreen,
 			      const CORBA_boolean open_in_existing_tab,
 			      const CORBA_boolean open_in_new_tab,
+			      const CORBA_char *startup_id,
                               CORBA_Environment *ev)
 {
 	EphyNewTabFlags flags = 0;
@@ -63,7 +64,7 @@ impl_ephy_automation_loadurl (PortableSe
 		url = "";
 	}
 
-	if (ephy_session_autoresume (session) && *url == '\0')
+	if (ephy_session_autoresume (session, startup_id) && *url == '\0')
 	{
 		/* no need to open the homepage,
 		* we did already open session windows */
@@ -74,6 +75,7 @@ impl_ephy_automation_loadurl (PortableSe
 
 	if (open_in_existing_tab && window != NULL)
 	{
+		/* FIXME: need to pass new startup ID ? */
 		ephy_window_load_url (window, url);
 		return;
 	}
@@ -102,7 +104,7 @@ impl_ephy_automation_loadurl (PortableSe
 		flags |= EPHY_NEW_TAB_FULLSCREEN_MODE;
 	}
 
-	ephy_shell_new_tab (ephy_shell, window, NULL, url, flags);
+	ephy_shell_new_tab (ephy_shell, window, NULL, url, flags, startup_id);
 }
 
 static void
@@ -126,16 +128,18 @@ impl_ephy_automation_import_bookmarks (P
 static void
 impl_ephy_automation_load_session (PortableServer_Servant _servant,
 				   const CORBA_char * filename,
+				   const CORBA_char * startup_id,
 				   CORBA_Environment * ev)
 {
 	EphySession *session;
 
 	session = EPHY_SESSION (ephy_shell_get_session (ephy_shell));
-	ephy_session_load (session, filename);
+	ephy_session_load (session, filename, startup_id);
 }
 
 static void
 impl_ephy_automation_open_bookmarks_editor (PortableServer_Servant _servant,
+					    const CORBA_char * startup_id,
 					    CORBA_Environment * ev)
 {
 	GtkWidget *editor;
@@ -143,6 +147,7 @@ impl_ephy_automation_open_bookmarks_edit
 	if (eel_gconf_get_boolean (CONF_LOCKDOWN_DISABLE_BOOKMARK_EDITING)) return;
 	editor = ephy_shell_get_bookmarks_editor (ephy_shell);
 
+	g_object_set (editor, "startup-id", startup_id, NULL);
 	gtk_window_present (GTK_WINDOW (editor));
 }
 
Index: src/ephy-history-window.c
===================================================================
RCS file: /cvs/gnome/epiphany/src/ephy-history-window.c,v
retrieving revision 1.70
diff -u -p -r1.70 ephy-history-window.c
--- src/ephy-history-window.c	14 Jul 2004 16:44:35 -0000	1.70
+++ src/ephy-history-window.c	16 Aug 2004 10:06:08 -0000
@@ -388,7 +388,8 @@ cmd_open_bookmarks_in_tabs (GtkAction *a
 						EPHY_NODE_PAGE_PROP_LOCATION);
 
 		ephy_shell_new_tab (ephy_shell, window, NULL, location,
-			EPHY_NEW_TAB_OPEN_PAGE | EPHY_NEW_TAB_IN_EXISTING_WINDOW);
+			EPHY_NEW_TAB_OPEN_PAGE | EPHY_NEW_TAB_IN_EXISTING_WINDOW,
+			NULL);
 	}
 
 	g_list_free (selection);
@@ -415,7 +416,8 @@ cmd_open_bookmarks_in_browser (GtkAction
 
 		ephy_shell_new_tab (ephy_shell, window, NULL, location,
 				    EPHY_NEW_TAB_OPEN_PAGE |
-				    EPHY_NEW_TAB_IN_NEW_WINDOW);
+				    EPHY_NEW_TAB_IN_NEW_WINDOW,
+				    NULL);
 	}
 
 	g_list_free (selection);
@@ -693,7 +695,8 @@ ephy_history_window_node_activated_cb (G
 	g_return_if_fail (location != NULL);
 
 	ephy_shell_new_tab (ephy_shell, NULL, NULL, location,
-			    EPHY_NEW_TAB_OPEN_PAGE);
+			    EPHY_NEW_TAB_OPEN_PAGE,
+			    NULL);
 }
 
 static void
@@ -1505,4 +1508,3 @@ ephy_history_window_dispose (GObject *ob
 
 	G_OBJECT_CLASS (parent_class)->dispose (object);
 }
-
Index: src/ephy-main.c
===================================================================
RCS file: /cvs/gnome/epiphany/src/ephy-main.c,v
retrieving revision 1.25
diff -u -p -r1.25 ephy-main.c
--- src/ephy-main.c	1 Aug 2004 22:16:23 -0000	1.25
+++ src/ephy-main.c	16 Aug 2004 10:06:08 -0000
@@ -49,6 +49,7 @@ static gboolean server_mode = FALSE;
 static const char *session_filename = NULL;
 static const char *bookmark_url = NULL;
 static const char *bookmarks_file = NULL;
+static const char *startup_id = NULL;
 
 static struct poptOption popt_options[] =
 {
@@ -73,6 +74,9 @@ static struct poptOption popt_options[] 
 	{ "server", 's', POPT_ARG_NONE, &server_mode, 0,
 	  N_("Used internally by the bonobo interface"),
 	  NULL },
+	{ "startup-id", '\0', POPT_ARG_STRING, &startup_id, 0,
+	  "Start notification ID", /* FIXME translate after string freeze */
+	  NULL },
 	{ NULL, 0, 0, NULL, 0, NULL, NULL }
 };
 
@@ -172,7 +176,7 @@ main (int argc, char *argv[])
 
 	ephy_shell = ephy_shell_new ();
 	new_instance = ephy_shell_startup (ephy_shell, startup_flags,
-					   args, string_arg, &err);
+					   args, string_arg, startup_id, &err);
 
 	if (err != NULL)
 	{
Index: src/ephy-session.c
===================================================================
RCS file: /cvs/gnome/epiphany/src/ephy-session.c,v
retrieving revision 1.20
diff -u -p -r1.20 ephy-session.c
--- src/ephy-session.c	6 Aug 2004 14:34:07 -0000	1.20
+++ src/ephy-session.c	16 Aug 2004 10:06:08 -0000
@@ -430,6 +430,7 @@ offer_to_resume (EphySession *session)
 /**
  * ephy_session_autoresume:
  * @session: a #EphySession
+ * @startup_id: the ID for the startup notification protocol
  *
  * Resume a crashed session when necessary (interactive)
  *
@@ -438,7 +439,8 @@ offer_to_resume (EphySession *session)
  * has been re-presented to the user.
  **/
 gboolean
-ephy_session_autoresume (EphySession *session)
+ephy_session_autoresume (EphySession *session,
+			 const char *startup_id)
 {
 	char *saved_session;
 	gboolean retval = FALSE;
@@ -449,17 +451,21 @@ ephy_session_autoresume (EphySession *se
 
 	if (session->priv->resume_dialog)
 	{
+		/* FIXME: set startup ID on this dialogue? */
 		gtk_window_present (GTK_WINDOW (session->priv->resume_dialog));
 		return TRUE;
 	}
 
 	saved_session = get_session_filename (SESSION_CRASHED);
 
+	/* FIXME: need to pass startup_id to offer_to_resume, to set on the
+ 	 * resume dialogue ?
+	 */
 	if (g_file_test (saved_session, G_FILE_TEST_EXISTS)
 	    && offer_to_resume (session))
 	{
 		session->priv->resuming = TRUE;
-		retval = ephy_session_load (session, saved_session);
+		retval = ephy_session_load (session, saved_session, startup_id);
 		session->priv->resuming = FALSE;
 		ephy_session_save (session, SESSION_CRASHED);
 	}
@@ -685,7 +691,7 @@ out:
 }
 
 static void
-parse_embed (xmlNodePtr child, EphyWindow *window)
+parse_embed (xmlNodePtr child, EphyWindow *window, const char *startup_id)
 {
 	while (child != NULL)
 	{
@@ -700,7 +706,8 @@ parse_embed (xmlNodePtr child, EphyWindo
 			ephy_shell_new_tab (ephy_shell, window, NULL, (char *) url,
 					    EPHY_NEW_TAB_IN_EXISTING_WINDOW |
 					    EPHY_NEW_TAB_OPEN_PAGE |
-					    EPHY_NEW_TAB_APPEND_LAST);
+					    EPHY_NEW_TAB_APPEND_LAST,
+					    startup_id);
 
 			xmlFree (url);
 		}
@@ -713,6 +720,7 @@ parse_embed (xmlNodePtr child, EphyWindo
  * ephy_session_load:
  * @session: a #EphySession
  * @filename: the path of the source file
+ * @startup_id: the ID for the startup notification protocol
  *
  * Load a session from disk, restoring the windows and their state
  *
@@ -720,7 +728,8 @@ parse_embed (xmlNodePtr child, EphyWindo
  **/
 gboolean
 ephy_session_load (EphySession *session,
-		   const char *filename)
+		   const char *filename,
+		   const char *startup_id)
 {
 	xmlDocPtr doc;
         xmlNodePtr child;
@@ -748,8 +757,8 @@ ephy_session_load (EphySession *session,
 	{
 		if (xmlStrEqual (child->name, (const xmlChar *) "window"))
 		{
-			widget = GTK_WIDGET (ephy_window_new ());
-			parse_embed (child->children, EPHY_WINDOW (widget));
+			widget = GTK_WIDGET (ephy_window_new (startup_id));
+			parse_embed (child->children, EPHY_WINDOW (widget), startup_id);
 		}
 		else if (xmlStrEqual (child->name, (const xmlChar *) "toolwindow"))
 		{
Index: src/ephy-session.h
===================================================================
RCS file: /cvs/gnome/epiphany/src/ephy-session.h,v
retrieving revision 1.2
diff -u -p -r1.2 ephy-session.h
--- src/ephy-session.h	19 Nov 2003 19:19:57 -0000	1.2
+++ src/ephy-session.h	16 Aug 2004 10:06:08 -0000
@@ -63,9 +63,11 @@ gboolean	 ephy_session_save		(EphySessio
 						 const char *filename);
 
 gboolean	 ephy_session_load		(EphySession *session,
-						 const char *filename);
+						 const char *filename,
+						 const char *startup_id);
 
-gboolean	 ephy_session_autoresume	(EphySession *session);
+gboolean	 ephy_session_autoresume	(EphySession *session,
+						 const char *startup_id);
 
 void		 ephy_session_close		(EphySession *session);
 
Index: src/ephy-shell.c
===================================================================
RCS file: /cvs/gnome/epiphany/src/ephy-shell.c,v
retrieving revision 1.90
diff -u -p -r1.90 ephy-shell.c
--- src/ephy-shell.c	6 Aug 2004 14:34:07 -0000	1.90
+++ src/ephy-shell.c	16 Aug 2004 10:06:08 -0000
@@ -217,7 +217,8 @@ static void
 open_urls (GNOME_EphyAutomation automation,
 	   const char **args, CORBA_Environment *ev,
 	   gboolean new_tab, gboolean existing_window,
-	   gboolean fullscreen)
+	   gboolean fullscreen,
+	   const char *startup_id)
 {
 	int i;
 
@@ -226,7 +227,7 @@ open_urls (GNOME_EphyAutomation automati
 		/* Homepage or resume */
 		GNOME_EphyAutomation_loadurl
 			(automation, "", fullscreen,
-			 existing_window, new_tab, ev);
+			 existing_window, new_tab, startup_id, ev);
 	}
 	else
 	{
@@ -238,7 +239,7 @@ open_urls (GNOME_EphyAutomation automati
 
 			GNOME_EphyAutomation_loadurl
 				(automation, path, fullscreen,
-				 existing_window, new_tab, ev);
+				 existing_window, new_tab, startup_id, ev);
 
 			g_free (path);
 		}
@@ -322,6 +323,7 @@ ephy_shell_startup (EphyShell *shell,
 		    EphyShellStartupFlags flags,
 		    const char **args,
 		    const char *string_arg,
+		    const char *startup_id,
 		    GError **error)
 {
 	CORBA_Environment ev;
@@ -338,7 +340,6 @@ ephy_shell_startup (EphyShell *shell,
 	switch (result)
 	{
 		case Bonobo_ACTIVATION_REG_SUCCESS:
-			break;
 		case Bonobo_ACTIVATION_REG_ALREADY_ACTIVE:
 			break;
 		case Bonobo_ACTIVATION_REG_NOT_LISTED:
@@ -382,12 +383,12 @@ ephy_shell_startup (EphyShell *shell,
 		else if (flags & EPHY_SHELL_STARTUP_BOOKMARKS_EDITOR)
 		{
 			GNOME_EphyAutomation_openBookmarksEditor
-				(automation, &ev);
+				(automation, startup_id, &ev);
 		}
 		else if (flags & EPHY_SHELL_STARTUP_SESSION)
 		{
 			GNOME_EphyAutomation_loadSession
-				(automation, string_arg, &ev);
+				(automation, string_arg, startup_id, &ev);
 		}
 		else if (flags & EPHY_SHELL_STARTUP_IMPORT_BOOKMARKS)
 		{
@@ -404,7 +405,8 @@ ephy_shell_startup (EphyShell *shell,
 			open_urls (automation, args, &ev,
 				   flags & EPHY_SHELL_STARTUP_TABS,
 				   flags & EPHY_SHELL_STARTUP_EXISTING_WINDOW,
-				   flags & EPHY_SHELL_STARTUP_FULLSCREEN);
+				   flags & EPHY_SHELL_STARTUP_FULLSCREEN,
+				   startup_id);
 		}
 
 		if (automation)
@@ -540,7 +542,8 @@ ephy_shell_new_tab (EphyShell *shell,
 		    EphyWindow *parent_window,
 		    EphyTab *previous_tab,
 		    const char *url,
-		    EphyNewTabFlags flags)
+		    EphyNewTabFlags flags,
+		    const char *startup_id)
 {
 	EphyWindow *window;
 	EphyTab *tab;
@@ -561,11 +564,12 @@ ephy_shell_new_tab (EphyShell *shell,
 
 	if (!in_new_window && parent_window != NULL)
 	{
+		/* FIXME: set new startup ID in window? */
 		window = parent_window;
 	}
 	else
 	{
-		window = ephy_window_new ();
+		window = ephy_window_new (startup_id);
 	}
 
 	toolbar = EPHY_TOOLBAR (ephy_window_get_toolbar (window));
Index: src/ephy-shell.h
===================================================================
RCS file: /cvs/gnome/epiphany/src/ephy-shell.h,v
retrieving revision 1.27
diff -u -p -r1.27 ephy-shell.h
--- src/ephy-shell.h	19 Jun 2004 17:21:19 -0000	1.27
+++ src/ephy-shell.h	16 Aug 2004 10:06:08 -0000
@@ -107,6 +107,7 @@ gboolean	ephy_shell_startup			(EphyShell
 							 EphyShellStartupFlags flags,
 							 const char **args,
 							 const char *string_arg,
+							 const char *startup_id,
 							 GError **error);
 
 EphyWindow     *ephy_shell_get_active_window		(EphyShell *shell);
@@ -115,7 +116,8 @@ EphyTab	       *ephy_shell_new_tab			(Ep
 							 EphyWindow *parent_window,
 							 EphyTab *previous_tab,
 							 const char *url,
-							 EphyNewTabFlags flags);
+							 EphyNewTabFlags flags,
+							 const char *startup_id);
 
 GObject	       *ephy_shell_get_session			(EphyShell *shell);
 
Index: src/ephy-statusbar.c
===================================================================
RCS file: /cvs/gnome/epiphany/src/ephy-statusbar.c,v
retrieving revision 1.7
diff -u -p -r1.7 ephy-statusbar.c
--- src/ephy-statusbar.c	1 Jul 2004 01:47:17 -0000	1.7
+++ src/ephy-statusbar.c	16 Aug 2004 10:06:10 -0000
@@ -198,7 +198,7 @@ ephy_statusbar_init (EphyStatusbar *t)
 	gtk_widget_show (t->priv->icon_container);
 
 	/* FIXME: enable this when gtk+ bug 73359 is fixed */
-	gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (t), FALSE);
+	gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (t), TRUE);
 
 	create_statusbar_progress (t);
 	create_statusbar_security_icon (t);
Index: src/ephy-tab.c
===================================================================
RCS file: /cvs/gnome/epiphany/src/ephy-tab.c,v
retrieving revision 1.112
diff -u -p -r1.112 ephy-tab.c
--- src/ephy-tab.c	8 Aug 2004 11:32:18 -0000	1.112
+++ src/ephy-tab.c	16 Aug 2004 10:06:10 -0000
@@ -1245,18 +1245,23 @@ ephy_tab_new_window_cb (EphyEmbed *embed
 			EphyEmbedChrome chromemask, EphyTab *tab)
 {
 	EphyTab *new_tab;
+	GtkWidget *toplevel;
 	EphyWindow *window;
+	char *startup_id = NULL;
 
 	LOG ("ephy_tab_new_window_cb tab %p with parent %p chrome %d",
 	     tab, ((GtkWidget *) tab)->parent, chromemask)
 
+	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (embed));
+	g_object_get (toplevel, "startup-id", &startup_id, NULL);
+
 	if (eel_gconf_get_boolean (CONF_LOCKDOWN_DISABLE_JAVASCRIPT_CHROME))
 	{
-		window = ephy_window_new ();
+		window = ephy_window_new (startup_id);
 	}
 	else
 	{
-		window = ephy_window_new_with_chrome (chromemask);
+		window = ephy_window_new_with_chrome (startup_id, chromemask);
 	}
 
 	new_tab = ephy_tab_new ();
@@ -1377,7 +1382,8 @@ open_link_in_new_tab (EphyTab *tab,
 		ephy_shell_new_tab (ephy_shell, window, tab,
 				    link_address,
 				    EPHY_NEW_TAB_OPEN_PAGE |
-				    EPHY_NEW_TAB_IN_EXISTING_WINDOW);
+				    EPHY_NEW_TAB_IN_EXISTING_WINDOW,
+				    NULL);
 	}
 
 	return new_tab;
Index: src/ephy-window.c
===================================================================
RCS file: /cvs/gnome/epiphany/src/ephy-window.c,v
retrieving revision 1.203
diff -u -p -r1.203 ephy-window.c
--- src/ephy-window.c	6 Aug 2004 14:34:07 -0000	1.203
+++ src/ephy-window.c	16 Aug 2004 10:06:11 -0000
@@ -65,6 +65,8 @@
 #include <gtk/gtktoggleaction.h>
 #include <gtk/gtkdialog.h>
 #include <gtk/gtkmessagedialog.h>
+#include <gdk/gdkx.h>
+#include <libsn/sn-launchee.h>
 
 static void ephy_window_class_init		(EphyWindowClass *klass);
 static void ephy_window_init			(EphyWindow *gs);
@@ -365,13 +367,16 @@ struct EphyWindowPrivate
 	guint disable_command_line_notifier_id;
 	guint browse_with_caret_notifier_id;
 	guint allow_popups_notifier_id;
+
+	char *startup_id;
 };
 
 enum
 {
 	PROP_0,
 	PROP_ACTIVE_TAB,
-	PROP_CHROME
+	PROP_CHROME,
+	PROP_STARTUP_ID
 };
 
 static GObjectClass *parent_class = NULL;
@@ -1849,7 +1854,7 @@ tab_removed_cb (EphyNotebook *notebook,
 static void
 tab_detached_cb (EphyNotebook *notebook,
 		 EphyTab *tab,
-		 gpointer data)
+		 EphyWindow *origin_window)
 {
 	EphyWindow *window;
 
@@ -1860,7 +1865,7 @@ tab_detached_cb (EphyNotebook *notebook,
 		return;
 	}
 
-	window = ephy_window_new ();
+	window = ephy_window_new (origin_window->priv->startup_id);
 	ephy_notebook_move_tab (notebook,
 				EPHY_NOTEBOOK (ephy_window_get_notebook (window)),
 				tab, 0);
@@ -1910,7 +1915,7 @@ setup_notebook (EphyWindow *window)
 	g_signal_connect (G_OBJECT (notebook), "tab_removed",
 			  G_CALLBACK (tab_removed_cb), window);
 	g_signal_connect (G_OBJECT (notebook), "tab_detached",
-			  G_CALLBACK (tab_detached_cb), NULL);
+			  G_CALLBACK (tab_detached_cb), window);
 	g_signal_connect (G_OBJECT (notebook), "tabs_reordered",
 			  G_CALLBACK (tabs_reordered_cb), window);
 	g_signal_connect (G_OBJECT (notebook), "tab_delete",
@@ -1971,6 +1976,10 @@ ephy_window_set_property (GObject *objec
 		case PROP_CHROME:
 			ephy_window_set_chrome (window, g_value_get_flags (value));
 			break;
+		case PROP_STARTUP_ID:
+			g_free (window->priv->startup_id);
+			window->priv->startup_id = g_value_dup_string (value);
+			break;
 	}
 }
 
@@ -1990,6 +1999,9 @@ ephy_window_get_property (GObject *objec
 		case PROP_CHROME:
 			g_value_set_flags (value, window->priv->chrome);
 			break;
+		case PROP_STARTUP_ID:
+			g_value_set_string (value, window->priv->startup_id);
+			break;
 	}
 }
 
@@ -2029,6 +2041,14 @@ ephy_window_class_init (EphyWindowClass 
 							     G_PARAM_CONSTRUCT_ONLY |
 							     G_PARAM_READWRITE));
 
+	g_object_class_install_property (object_class,
+					 PROP_STARTUP_ID,
+					 g_param_spec_string ("startup-id",
+					 		      "Startup ID",
+							      "Startup ID",
+							      NULL,
+							      G_PARAM_READWRITE));
+
 	g_type_class_add_private (object_class, sizeof(EphyWindowPrivate));
 }
 
@@ -2328,6 +2348,8 @@ ephy_window_finalize (GObject *object)
 	g_object_unref (window->priv->action_group);
 	g_object_unref (window->ui_merge);
 
+	g_free (window->priv->startup_id);
+
         G_OBJECT_CLASS (parent_class)->finalize (object);
 
 	LOG ("Ephy Window finalized %p", window)
@@ -2337,6 +2359,7 @@ ephy_window_finalize (GObject *object)
 
 /**
  * ephy_window_new:
+ * @startup_id: the startup ID for the startup notification protocol
  *
  * Equivalent to g_object_new() but returns an #EphyWindow so you don't have
  * to cast it.
@@ -2344,13 +2367,16 @@ ephy_window_finalize (GObject *object)
  * Return value: a new #EphyWindow
  **/
 EphyWindow *
-ephy_window_new (void)
+ephy_window_new (const char *startup_id)
 {
-	return EPHY_WINDOW (g_object_new (EPHY_TYPE_WINDOW, NULL));
+	return EPHY_WINDOW (g_object_new (EPHY_TYPE_WINDOW,
+					  "startup-id", startup_id,
+					  NULL));
 }
 
 /**
  * ephy_window_new_with_chrome:
+ * @startup_id: the startup ID for the startup notification protocol
  * @chrome: an #EphyEmbedChrome
  *
  * Identical to ephy_window_new(), but allows you to specify a chrome.
@@ -2358,9 +2384,11 @@ ephy_window_new (void)
  * Return value: a new #EphyWindow
  **/
 EphyWindow *
-ephy_window_new_with_chrome (EphyEmbedChrome chrome)
+ephy_window_new_with_chrome (const char *startup_id,
+			     EphyEmbedChrome chrome)
 {
 	return EPHY_WINDOW (g_object_new (EPHY_TYPE_WINDOW,
+					  "startup_id", startup_id,
 					  "chrome", chrome,
 					  NULL));
 }
@@ -2610,6 +2638,10 @@ void
 ephy_window_show (GtkWidget *widget)
 {
 	EphyWindow *window = EPHY_WINDOW(widget);
+	GdkScreen *screen;
+	GdkDisplay *display;
+	SnDisplay *sn_display = NULL;
+	SnLauncheeContext *context = NULL;
 
 	if (!window->priv->has_size)
 	{
@@ -2629,7 +2661,37 @@ ephy_window_show (GtkWidget *widget)
 		window->priv->has_size = TRUE;
 	}
 
+	/* copied from gnome-terminal's terminal-window.c */
+	if (window->priv->startup_id != NULL)
+	{
+		/* Set up window for launch notification */
+		/* FIXME In principle all transient children of this
+		* window should get the same startup_id
+		*/
+		
+		screen = gtk_window_get_screen (GTK_WINDOW (window));
+		display = gdk_screen_get_display (screen);
+		
+		sn_display = sn_display_new (gdk_x11_display_get_xdisplay (display),
+					     (SnDisplayErrorTrapPush) gdk_error_trap_push,
+					     (SnDisplayErrorTrapPop) gdk_error_trap_pop);
+		
+		context = sn_launchee_context_new (sn_display,
+						   gdk_screen_get_number (screen),
+						   window->priv->startup_id);
+		sn_launchee_context_setup_window
+			(context, GDK_WINDOW_XWINDOW (widget->window));
+	
+	}
+	
 	GTK_WIDGET_CLASS (parent_class)->show (widget);
+
+	if (context != NULL)
+	{
+		sn_launchee_context_complete (context);
+		sn_launchee_context_unref (context);
+		sn_display_unref (sn_display);
+	}
 }
 
 /**
@@ -2827,7 +2889,8 @@ ephy_window_load_in_tabs (EphyWindow *wi
 						  EPHY_NEW_TAB_OPEN_PAGE |
 						  EPHY_NEW_TAB_IN_EXISTING_WINDOW |
 						  (tab ? EPHY_NEW_TAB_APPEND_AFTER :
-							 EPHY_NEW_TAB_APPEND_LAST));
+							 EPHY_NEW_TAB_APPEND_LAST),
+						  window->priv->startup_id);
 		}
 
 		l = l->next;
Index: src/ephy-window.h
===================================================================
RCS file: /cvs/gnome/epiphany/src/ephy-window.h,v
retrieving revision 1.28
diff -u -p -r1.28 ephy-window.h
--- src/ephy-window.h	23 Jun 2004 18:28:31 -0000	1.28
+++ src/ephy-window.h	16 Aug 2004 10:06:11 -0000
@@ -62,9 +62,10 @@ struct EphyWindowClass
 
 GType		  ephy_window_get_type		  (void);
 
-EphyWindow	 *ephy_window_new		  (void);
+EphyWindow	 *ephy_window_new		  (const char *startup_id);
 
-EphyWindow	 *ephy_window_new_with_chrome	  (EphyEmbedChrome chrome);
+EphyWindow	 *ephy_window_new_with_chrome	  (const char *startup_id,
+						   EphyEmbedChrome chrome);
 
 void		  ephy_window_set_print_preview	  (EphyWindow *window,
 						   gboolean enabled);
Index: src/popup-commands.c
===================================================================
RCS file: /cvs/gnome/epiphany/src/popup-commands.c,v
retrieving revision 1.42
diff -u -p -r1.42 popup-commands.c
--- src/popup-commands.c	25 Jul 2004 12:49:06 -0000	1.42
+++ src/popup-commands.c	16 Aug 2004 10:06:11 -0000
@@ -64,7 +64,8 @@ popup_cmd_link_in_new_window (GtkAction 
 	ephy_shell_new_tab (ephy_shell, NULL, tab,
 			    g_value_get_string (value),
 			    EPHY_NEW_TAB_OPEN_PAGE |
-			    EPHY_NEW_TAB_IN_NEW_WINDOW);
+			    EPHY_NEW_TAB_IN_NEW_WINDOW,
+			    NULL /* FIXME need to pass real ID? */);
 }
 
 void
@@ -84,7 +85,8 @@ popup_cmd_link_in_new_tab (GtkAction *ac
 	ephy_shell_new_tab (ephy_shell, window, tab,
 			    g_value_get_string (value),
 			    EPHY_NEW_TAB_OPEN_PAGE |
-			    EPHY_NEW_TAB_IN_EXISTING_WINDOW);
+			    EPHY_NEW_TAB_IN_EXISTING_WINDOW,
+			    NULL /* FIXME need to pass real ID? */);
 }
 
 void
Index: src/window-commands.c
===================================================================
RCS file: /cvs/gnome/epiphany/src/window-commands.c,v
retrieving revision 1.131
diff -u -p -r1.131 window-commands.c
--- src/window-commands.c	4 Aug 2004 13:52:46 -0000	1.131
+++ src/window-commands.c	16 Aug 2004 10:06:12 -0000
@@ -288,7 +288,8 @@ window_cmd_file_new_window (GtkAction *a
 
 	ephy_shell_new_tab (ephy_shell, window, tab, NULL,
 			    EPHY_NEW_TAB_NEW_PAGE |
-			    EPHY_NEW_TAB_IN_NEW_WINDOW);
+			    EPHY_NEW_TAB_IN_NEW_WINDOW,
+			    NULL /* FIXME need to pass real ID? */);
 }
 
 void
@@ -303,7 +304,8 @@ window_cmd_file_new_tab (GtkAction *acti
 	ephy_shell_new_tab (ephy_shell, window, tab, NULL,
 			    EPHY_NEW_TAB_NEW_PAGE |
 			    EPHY_NEW_TAB_IN_EXISTING_WINDOW |
-			    EPHY_NEW_TAB_JUMP);
+			    EPHY_NEW_TAB_JUMP,
+			    NULL /* FIXME need to pass real ID? */);
 }
 
 void
@@ -1093,7 +1095,7 @@ window_cmd_tabs_detach  (GtkAction *acti
 
 	tab = ephy_window_get_active_tab (window);
 
-	new_win = ephy_window_new ();
+	new_win = ephy_window_new (NULL /* FIXME need to pass real ID? */);
 	ephy_notebook_move_tab (EPHY_NOTEBOOK (ephy_window_get_notebook (window)),
 				EPHY_NOTEBOOK (ephy_window_get_notebook (new_win)),
 				tab, 0);
Index: src/bookmarks/ephy-bookmarks-editor.c
===================================================================
RCS file: /cvs/gnome/epiphany/src/bookmarks/ephy-bookmarks-editor.c,v
retrieving revision 1.141
diff -u -p -r1.141 ephy-bookmarks-editor.c
--- src/bookmarks/ephy-bookmarks-editor.c	6 Aug 2004 14:34:07 -0000	1.141
+++ src/bookmarks/ephy-bookmarks-editor.c	16 Aug 2004 10:06:12 -0000
@@ -45,6 +45,8 @@
 #include <glib/gi18n.h>
 #include <libgnomeui/gnome-stock-icons.h>
 #include <string.h>
+#include <gdk/gdkx.h>
+#include <libsn/sn-launchee.h>
 
 #include "ephy-bookmarks-editor.h"
 #include "ephy-bookmark-properties.h"
@@ -153,12 +155,15 @@ struct EphyBookmarksEditorPrivate
 
 	GtkTreeViewColumn *title_col;
 	GtkTreeViewColumn *address_col;
+
+	char *startup_id;
 };
 
 enum
 {
 	PROP_0,
-	PROP_BOOKMARKS
+	PROP_BOOKMARKS,
+	PROP_STARTUP_ID
 };
 
 static GObjectClass *parent_class = NULL;
@@ -409,7 +414,8 @@ cmd_open_bookmarks_in_tabs (GtkAction *a
 
 		new_tab = ephy_shell_new_tab (ephy_shell, window, NULL, location,
 					      EPHY_NEW_TAB_OPEN_PAGE |
-					      EPHY_NEW_TAB_IN_EXISTING_WINDOW);
+					      EPHY_NEW_TAB_IN_EXISTING_WINDOW,
+					      editor->priv->startup_id);
 		/* if there was no target window, a new one was opened. Get it
 		 * from the new tab so we open the remaining links in the
 		 * same window. See bug 138343.
@@ -444,7 +450,8 @@ cmd_open_bookmarks_in_browser (GtkAction
 						EPHY_NODE_BMK_PROP_LOCATION);
 
 		ephy_shell_new_tab (ephy_shell, window, NULL, location,
-				    EPHY_NEW_TAB_OPEN_PAGE | EPHY_NEW_TAB_IN_NEW_WINDOW);
+				    EPHY_NEW_TAB_OPEN_PAGE | EPHY_NEW_TAB_IN_NEW_WINDOW,
+				    editor->priv->startup_id);
 	}
 
 	g_list_free (selection);
@@ -875,10 +882,44 @@ static void
 ephy_bookmarks_editor_show (GtkWidget *widget)
 {
 	EphyBookmarksEditor *editor = EPHY_BOOKMARKS_EDITOR (widget);
+	GdkScreen *screen;
+	GdkDisplay *display;
+	SnDisplay *sn_display = NULL;
+	SnLauncheeContext *context = NULL;
 
 	gtk_widget_grab_focus (editor->priv->search_entry);
 
+	/* copied from gnome-terminal's terminal-window.c */
+	if (editor->priv->startup_id != NULL)
+	{
+		/* Set up window for launch notification */
+		/* FIXME In principle all transient children of this
+		* window should get the same startup_id
+		*/
+		
+		screen = gtk_window_get_screen (GTK_WINDOW (widget));
+		display = gdk_screen_get_display (screen);
+
+		sn_display = sn_display_new (gdk_x11_display_get_xdisplay (display),
+					     (SnDisplayErrorTrapPush) gdk_error_trap_push,
+					     (SnDisplayErrorTrapPop) gdk_error_trap_pop);
+
+		context = sn_launchee_context_new (sn_display,
+						   gdk_screen_get_number (screen),
+						   editor->priv->startup_id);
+		sn_launchee_context_setup_window
+			(context, GDK_WINDOW_XWINDOW (widget->window));
+	
+	}
+
 	GTK_WIDGET_CLASS (parent_class)->show (widget);
+
+	if (context != NULL)
+	{
+		sn_launchee_context_complete (context);
+		sn_launchee_context_unref (context);
+		sn_display_unref (sn_display);
+	}
 }
 
 static void
@@ -905,6 +946,14 @@ ephy_bookmarks_editor_class_init (EphyBo
 							      EPHY_TYPE_BOOKMARKS,
 							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
+	g_object_class_install_property (object_class,
+					 PROP_STARTUP_ID,
+					 g_param_spec_string ("startup-id",
+					 		      "Startup ID",
+							      "Startup ID",
+							      NULL,
+							      G_PARAM_READWRITE));
+
 	g_type_class_add_private (object_class, sizeof(EphyBookmarksEditorPrivate));
 }
 
@@ -927,6 +976,8 @@ ephy_bookmarks_editor_finalize (GObject 
 
 	g_hash_table_destroy (editor->priv->props_dialogs);
 
+	g_free (editor->priv->startup_id);
+
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -942,7 +993,8 @@ ephy_bookmarks_editor_node_activated_cb 
 	g_return_if_fail (location != NULL);
 
 	ephy_shell_new_tab (ephy_shell, NULL, NULL, location,
-			    EPHY_NEW_TAB_OPEN_PAGE);
+			    EPHY_NEW_TAB_OPEN_PAGE,
+			    editor->priv->startup_id);
 }
 
 static void
@@ -1653,6 +1705,10 @@ ephy_bookmarks_editor_set_property (GObj
 	case PROP_BOOKMARKS:
 		editor->priv->bookmarks = g_value_get_object (value);
 		break;
+	case PROP_STARTUP_ID:
+		g_free (editor->priv->startup_id);
+		editor->priv->startup_id = g_value_dup_string (value);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -1671,6 +1727,9 @@ ephy_bookmarks_editor_get_property (GObj
 	{
 	case PROP_BOOKMARKS:
 		g_value_set_object (value, editor->priv->bookmarks);
+		break;
+	case PROP_STARTUP_ID:
+		g_value_set_string (value, editor->priv->startup_id);
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Index: src/bookmarks/ephy-bookmarksbar.c
===================================================================
RCS file: /cvs/gnome/epiphany/src/bookmarks/ephy-bookmarksbar.c,v
retrieving revision 1.9
diff -u -p -r1.9 ephy-bookmarksbar.c
--- src/bookmarks/ephy-bookmarksbar.c	9 Aug 2004 18:41:49 -0000	1.9
+++ src/bookmarks/ephy-bookmarksbar.c	16 Aug 2004 10:06:12 -0000
@@ -107,7 +107,7 @@ open_in_tabs_cb (GtkAction *action, GLis
 	g_return_if_fail (l != NULL);
 
 	tab = ephy_shell_new_tab (ephy_shell, NULL, NULL, l->data,
-				  EPHY_NEW_TAB_OPEN_PAGE);
+				  EPHY_NEW_TAB_OPEN_PAGE, NULL);
 	g_return_if_fail (tab != NULL);
 
 	window = EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab)));
@@ -118,7 +118,7 @@ open_in_tabs_cb (GtkAction *action, GLis
 		ephy_shell_new_tab (ephy_shell, window, NULL, l->data,
 				    EPHY_NEW_TAB_IN_EXISTING_WINDOW |
 				    EPHY_NEW_TAB_OPEN_PAGE |
-				    EPHY_NEW_TAB_APPEND_LAST);
+				    EPHY_NEW_TAB_APPEND_LAST, NULL);
 	}
 }
 
@@ -135,7 +135,7 @@ bookmark_open_in_tab_cb (GtkAction *acti
 	}
 
 	ephy_shell_new_tab (ephy_shell, toolbar->priv->window, NULL,
-			    location, flags);
+			    location, flags, NULL);
 }
 
 static void
