Index: src/ephy-window.c
===================================================================
--- src/ephy-window.c	(Revision 8630)
+++ src/ephy-window.c	(Arbeitskopie)
@@ -2407,6 +2407,46 @@
 		gtk_widget_hide (GTK_WIDGET (window));
 }
 
+static void
+ephy_window_new_tab_activate_cb (GtkWidget *widget, EphyWindow *window)
+{
+  EphyEmbed *embed = window->priv->active_embed;
+  const char *uri;
+
+  uri = ephy_embed_get_link_message (embed);
+  open_link_in_new (window, uri, 0, embed);
+}
+
+static void
+ephy_window_populate_popup_cb (EphyEmbed *embed, GtkMenu *menu, EphyWindow *window)
+{
+  GdkScreen    *screen;
+  GtkWidget    *icon, *menuitem;
+  GtkIconTheme *icon_theme;
+  /**
+   * We aren't going to modify the menu, if there is no link hovered!
+   */
+  if (ephy_embed_get_link_message (embed) == NULL)
+    return;
+
+  menuitem = gtk_image_menu_item_new_with_mnemonic(
+      _("Open Link in New _Tab"));
+  screen = gtk_widget_get_screen (GTK_WIDGET (window));
+  icon_theme = gtk_icon_theme_get_for_screen (screen);
+
+  if (gtk_icon_theme_has_icon (icon_theme, STOCK_NEW_TAB)) {
+    icon = gtk_image_new_from_stock (STOCK_NEW_TAB, GTK_ICON_SIZE_MENU);
+    gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
+  }
+
+  gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 1);
+
+  g_signal_connect (menuitem, "activate",
+      G_CALLBACK (ephy_window_new_tab_activate_cb), window);
+
+  gtk_widget_show (menuitem);
+}
+
 static gboolean
 web_view_ready_cb (WebKitWebView *web_view,
 		   EphyEmbed *embed)
@@ -2637,6 +2677,9 @@
 		g_signal_connect_object (embed, "notify::visibility",
 					 G_CALLBACK (ephy_window_visibility_cb),
 					 window, 0);
+    g_signal_connect_object (embed, "populate-popup", 
+           G_CALLBACK (ephy_window_populate_popup_cb),
+           window, 0);
 
 		g_object_notify (G_OBJECT (window), "active-child");
 	}
Index: embed/webkit/webkit-embed-event.c
===================================================================
--- embed/webkit/webkit-embed-event.c	(Revision 0)
+++ embed/webkit/webkit-embed-event.c	(Revision 0)
@@ -0,0 +1,276 @@
+#include "webkit-embed-event.h"
+
+static void webkit_embed_event_class_init (WebKitEmbedEventClass *klass);
+static void webkit_embed_event_init       (WebKitEmbedEvent *event);
+static void ephy_embed_event_init         (EphyEmbedEventIface *iface);
+
+enum 
+{
+  PROP_0,
+  PROP_LINK,
+  PROP_IMAGE
+};
+
+
+#define WEBKIT_EMBED_EVENT_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), WEBKIT_TYPE_EMBED_EVENT, WebKitEmbedEventPrivate))
+
+
+G_DEFINE_TYPE_WITH_CODE (WebKitEmbedEvent, webkit_embed_event, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (EPHY_TYPE_EMBED_EVENT,
+                                                ephy_embed_event_init))
+
+struct WebKitEmbedEventPrivate {
+  guint x, y;
+  guint modifier;
+  guint button;
+  EphyEmbedEventContext context;
+  char *link;
+  char *image;
+};
+
+static void
+webkit_embed_event_finalize (GObject *object)
+{
+  WebKitEmbedEvent *event = WEBKIT_EMBED_EVENT (object);
+
+  G_OBJECT_CLASS (webkit_embed_event_parent_class)->finalize (object);
+  g_free (event->priv->link);
+  g_free (event->priv->image);
+}
+
+static void
+webkit_embed_event_get_property (GObject *object,
+                                 guint prop_id,
+                                 GValue *value,
+                                 GParamSpec *pspec)
+{
+  EphyEmbedEvent *event = EPHY_EMBED_EVENT (object);
+  switch (prop_id) {
+    case PROP_LINK:
+      g_value_set_string (value, webkit_embed_event_get_link (event));
+      break;
+    case PROP_IMAGE:
+      g_value_set_string (value, webkit_embed_event_get_image (event));
+      break;
+    default: 
+      break;
+  }
+}
+
+static const GValue* 
+impl_webkit_embed_event_get_property (EphyEmbedEvent *event, const char *prop)
+{
+  char *str;
+  GValue *value = g_new0(GValue, 1);
+
+  g_value_init (value, G_TYPE_STRING);
+  g_object_get (event, prop, &str, NULL);
+  g_value_set_string (value, str);
+
+  return value;
+}
+
+static gboolean
+impl_webkit_embed_event_has_property (EphyEmbedEvent *event, const char *prop)
+{
+  return g_object_class_find_property (G_OBJECT_GET_CLASS (event), prop) 
+      != NULL;
+}
+
+static void
+webkit_embed_event_set_property (GObject *object,
+                                 guint prop_id,
+                                 const GValue *value,
+                                 GParamSpec *pspec)
+{
+  switch (prop_id) {
+    case PROP_LINK:
+      webkit_embed_event_set_link (EPHY_EMBED_EVENT (object), 
+                                   g_value_get_string (value));
+      break;
+    case PROP_IMAGE:
+      webkit_embed_event_set_image (EPHY_EMBED_EVENT (object), 
+                                    g_value_get_string (value));
+      break;
+    default:
+      break;
+  }
+}
+
+static void
+webkit_embed_event_class_init (WebKitEmbedEventClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize     = webkit_embed_event_finalize;
+  object_class->set_property = webkit_embed_event_set_property;
+  object_class->get_property = webkit_embed_event_get_property;
+
+  g_type_class_add_private (object_class, sizeof(WebKitEmbedEventPrivate));
+
+  g_object_class_install_property 
+    (object_class,
+     PROP_LINK,
+     g_param_spec_string ("link",
+                          "Link",
+                          "The link, which was pressed",
+                          NULL,
+                          G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property 
+    (object_class,
+     PROP_LINK,
+     g_param_spec_string ("image",
+                          "Image",
+                          "The image, which was pressed",
+                          NULL,
+                          G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+}
+
+static void
+webkit_embed_event_init (WebKitEmbedEvent *event)
+{
+  event->priv = WEBKIT_EMBED_EVENT_GET_PRIVATE (event);
+
+  event->priv->x        = 0;
+  event->priv->y        = 0;
+  event->priv->modifier = 0;
+  event->priv->button   = 0;
+  event->priv->context  = 0;
+  event->priv->link     = NULL;
+  event->priv->image    = NULL;
+}
+
+static void 
+ephy_embed_event_init (EphyEmbedEventIface *iface)
+{
+  iface->get_button      = webkit_embed_event_get_button;
+  iface->get_modifier    = webkit_embed_event_get_modifier;
+  iface->get_coordinates = webkit_embed_event_get_coords;
+  iface->get_context     = webkit_embed_event_get_context;
+  iface->get_property    = impl_webkit_embed_event_get_property;
+  iface->has_property    = impl_webkit_embed_event_has_property;
+  /*
+   * TODO:
+   * get_dom_event
+   */
+}
+
+WebKitEmbedEvent*
+webkit_embed_event_new (void)
+{
+  return WEBKIT_EMBED_EVENT (g_object_new (WEBKIT_TYPE_EMBED_EVENT, NULL));
+}
+
+WebKitEmbedEvent*
+webkit_embed_event_new_from_gdk_event_button (GdkEventButton *gdk_event)
+{
+  EphyEmbedEvent *event = EPHY_EMBED_EVENT (g_object_new (WEBKIT_TYPE_EMBED_EVENT,
+                                                          NULL));
+
+  webkit_embed_event_set_button (event, gdk_event->button);
+  webkit_embed_event_set_coords (event, (guint) gdk_event->x, (guint) gdk_event->y);
+  webkit_embed_event_set_modifier (event, gdk_event->state);
+
+  return WEBKIT_EMBED_EVENT (event);
+}
+
+void
+webkit_embed_event_set_button (EphyEmbedEvent *ev, guint button)
+{
+  WebKitEmbedEvent *event = WEBKIT_EMBED_EVENT (ev);
+
+  event->priv->button = button;
+}
+
+guint 
+webkit_embed_event_get_button (EphyEmbedEvent *ev)
+{
+  WebKitEmbedEvent *event = WEBKIT_EMBED_EVENT (ev);
+
+  return event->priv->button;
+}
+
+void 
+webkit_embed_event_set_modifier (EphyEmbedEvent *ev, guint modifier)
+{
+  WebKitEmbedEvent *event = WEBKIT_EMBED_EVENT (ev);
+
+  event->priv->modifier = modifier;
+}
+
+guint
+webkit_embed_event_get_modifier (EphyEmbedEvent *ev)
+{
+  WebKitEmbedEvent *event = WEBKIT_EMBED_EVENT (ev);
+
+  return event->priv->modifier;
+}
+
+void 
+webkit_embed_event_set_coords (EphyEmbedEvent *ev, guint x, guint y)
+{
+  WebKitEmbedEvent *event = WEBKIT_EMBED_EVENT (ev);
+
+  event->priv->x = x;
+  event->priv->y = y;
+}
+
+void 
+webkit_embed_event_get_coords (EphyEmbedEvent *ev, guint *x, guint *y)
+{
+  WebKitEmbedEvent *event = WEBKIT_EMBED_EVENT (ev);
+
+  *x = event->priv->x;
+  *y = event->priv->y;
+}
+
+void
+webkit_embed_event_set_context (EphyEmbedEvent *ev, EphyEmbedEventContext ctx)
+{
+  WebKitEmbedEvent *event = WEBKIT_EMBED_EVENT (ev);
+
+  event->priv->context = ctx;
+}
+
+EphyEmbedEventContext
+webkit_embed_event_get_context (EphyEmbedEvent *ev)
+{
+  WebKitEmbedEvent *event = WEBKIT_EMBED_EVENT (ev);
+
+  return event->priv->context;
+}
+
+void 
+webkit_embed_event_set_link (EphyEmbedEvent *ev, const char *link)
+{
+  WebKitEmbedEvent *event = WEBKIT_EMBED_EVENT (ev);
+
+  event->priv->link = g_strdup (link);
+}
+
+const char* 
+webkit_embed_event_get_link (EphyEmbedEvent *ev)
+{
+  WebKitEmbedEvent *event = WEBKIT_EMBED_EVENT (ev);
+
+  return event->priv->link;
+}
+
+void
+webkit_embed_event_set_image (EphyEmbedEvent *ev, const char *image)
+{
+  WebKitEmbedEvent *event = WEBKIT_EMBED_EVENT (ev);
+
+  event->priv->image = g_strdup (image);
+}
+
+const char* 
+webkit_embed_event_get_image (EphyEmbedEvent *ev)
+{
+  WebKitEmbedEvent *event = WEBKIT_EMBED_EVENT (ev);
+
+  return event->priv->image;
+}
+
+
Index: embed/webkit/webkit-embed.c
===================================================================
--- embed/webkit/webkit-embed.c	(Revision 8630)
+++ embed/webkit/webkit-embed.c	(Arbeitskopie)
@@ -34,6 +34,7 @@
 #include <string.h>
 
 #include "webkit-embed.h"
+#include "webkit-embed-event.h"
 #include "webkit-embed-prefs.h"
 #include "ephy-embed.h"
 #include "ephy-base-embed.h"
@@ -281,7 +282,38 @@
   g_free (address);
 }
 
+static gboolean
+webkit_embed_button_press_event_cb (WebKitWebView *web_view,
+                                    GdkEventButton *gdk_event,
+                                    EphyEmbed *embed)
+{
+  gboolean result;
+  WebKitEmbedEvent *event = webkit_embed_event_new_from_gdk_event_button (gdk_event);
+
+  /**
+   * TODO: Different contexts?!
+   */
+  if (ephy_embed_get_link_message (embed) != NULL) {
+    webkit_embed_event_set_context (EPHY_EMBED_EVENT (event),
+                                    EPHY_EMBED_CONTEXT_LINK);
+    webkit_embed_event_set_link (EPHY_EMBED_EVENT (event), 
+                                 ephy_embed_get_link_message (embed));
+  }
+  g_signal_emit_by_name (embed, "ge_dom_mouse_click", event, &result);
+
+  return result;
+}
+
 static void
+webkit_embed_populate_popup_cb (WebKitWebView *web_view,
+                                GtkWidget *menu,
+                                EphyEmbed *embed)
+{
+  /* Just relay the event to the embed object */
+  g_signal_emit_by_name (embed, "populate-popup", menu);
+}
+
+static void
 webkit_embed_finalize (GObject *object)
 {
   WebKitEmbed *wembed = WEBKIT_EMBED (object);
@@ -329,6 +361,8 @@
                     "signal::title-changed", G_CALLBACK (webkit_embed_title_changed_cb), embed,
                     "signal::load-progress-changed", G_CALLBACK (webkit_embed_load_progress_changed_cb), embed,
                     "signal::hovering-over-link", G_CALLBACK (webkit_embed_hovering_over_link_cb), embed,
+		    "signal::button-press-event", G_CALLBACK (webkit_embed_button_press_event_cb), embed, 
+		    "signal::populate-popup", G_CALLBACK (webkit_embed_populate_popup_cb), embed, 
                     NULL);
 
   g_signal_connect (web_view, "notify::zoom-level",
Index: embed/webkit/webkit-embed-event.h
===================================================================
--- embed/webkit/webkit-embed-event.h	(Revision 0)
+++ embed/webkit/webkit-embed-event.h	(Revision 0)
@@ -0,0 +1,86 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/*
+ *  Copyright © 2007 Xan Lopez
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WEBKIT_EMBED_EVENT_H
+#define WEBKIT_EMBED_EVENT_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "ephy-embed-event.h"
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_EMBED_EVENT         (webkit_embed_event_get_type ())
+#define WEBKIT_EMBED_EVENT(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), WEBKIT_TYPE_EMBED_EVENT, WebKitEmbedEvent))
+#define WEBKIT_EMBED_EVENT_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), WEBKIT_TYPE_EMBED_EVENT, WebKitEmbedEventClass))
+#define WEBKIT_IS_EMBED_EVENT(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), WEBKIT_TYPE_EMBED_EVENT))
+#define WEBKIT_IS_EMBED_EVENT_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), WEBKIT_TYPE_EMBED_EVENT))
+#define WEBKIT_EMBED_EVENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), WEBKIT_TYPE_EMBED, WebKitEmbedEventClass))
+
+typedef struct WebKitEmbedEventClass WebKitEmbedEventClass;
+typedef struct WebKitEmbedEvent WebKitEmbedEvent;
+typedef struct WebKitEmbedEventPrivate WebKitEmbedEventPrivate;
+
+
+struct WebKitEmbedEvent {
+  GObject parent_instance;
+
+  WebKitEmbedEventPrivate *priv;
+  /* data */
+};
+
+struct WebKitEmbedEventClass {
+  GObjectClass parent_class;
+};
+
+WebKitEmbedEvent* webkit_embed_event_new (void);
+
+WebKitEmbedEvent* webkit_embed_event_new_from_gdk_event_button (GdkEventButton *button);
+
+
+GType webkit_embed_event_get_type (void);
+
+void  webkit_embed_event_set_button (EphyEmbedEvent *event, guint button);
+
+guint webkit_embed_event_get_button (EphyEmbedEvent *event);
+
+void  webkit_embed_event_set_modifier (EphyEmbedEvent *event, guint modifier);
+
+guint webkit_embed_event_get_modifier (EphyEmbedEvent *event);
+
+void  webkit_embed_event_set_coords (EphyEmbedEvent *event, guint x, guint y);
+
+void  webkit_embed_event_get_coords (EphyEmbedEvent *event, guint *x, guint *y);
+
+void webkit_embed_event_set_context (EphyEmbedEvent *event, EphyEmbedEventContext ctx);
+
+EphyEmbedEventContext  webkit_embed_event_get_context (EphyEmbedEvent *event);
+
+void webkit_embed_event_set_link (EphyEmbedEvent *event, const char *link);
+
+const char* webkit_embed_event_get_link (EphyEmbedEvent *event);
+
+void webkit_embed_event_set_image (EphyEmbedEvent *event, const char *image);
+
+const char* webkit_embed_event_get_image (EphyEmbedEvent *event);
+
+#endif 
Index: embed/webkit/Makefile.am
===================================================================
--- embed/webkit/Makefile.am	(Revision 8630)
+++ embed/webkit/Makefile.am	(Arbeitskopie)
@@ -3,6 +3,8 @@
 libephywebkitembed_la_SOURCES = 	\
 	webkit-embed.c  	        \
 	webkit-embed.h			\
+	webkit-embed-event.c          \
+	webkit-embed-event.h		\
 	webkit-embed-persist.c          \
 	webkit-embed-persist.h		\
 	webkit-embed-prefs.c            \
Index: embed/ephy-embed-event.h
===================================================================
--- embed/ephy-embed-event.h	(Revision 8630)
+++ embed/ephy-embed-event.h	(Arbeitskopie)
@@ -19,10 +19,6 @@
  *  $Id$
  */
 
-#if !defined (__EPHY_EPIPHANY_H_INSIDE__) && !defined (EPIPHANY_COMPILATION)
-#error "Only <epiphany/epiphany.h> can be included directly."
-#endif
-
 #ifndef EPHY_EMBED_EVENT_H
 #define EPHY_EMBED_EVENT_H
 
Index: embed/ephy-embed.c
===================================================================
--- embed/ephy-embed.c	(Revision 8630)
+++ embed/ephy-embed.c	(Arbeitskopie)
@@ -334,20 +334,38 @@
  * related changes, for example to restore the zoom level of a page
  * or to set an user style sheet.
  **/
-	       g_signal_new ("new-document-now",
-			     EPHY_TYPE_EMBED,
-			     G_SIGNAL_RUN_FIRST,
-			     G_STRUCT_OFFSET (EphyEmbedIface, new_document_now),
-			     NULL, NULL,
-			     g_cclosure_marshal_VOID__STRING,
-			     G_TYPE_NONE,
-			     1,
-			     G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
+       g_signal_new ("new-document-now",
+         EPHY_TYPE_EMBED,
+         G_SIGNAL_RUN_FIRST,
+         G_STRUCT_OFFSET (EphyEmbedIface, new_document_now),
+         NULL, NULL,
+         g_cclosure_marshal_VOID__STRING,
+         G_TYPE_NONE,
+         1,
+         G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
 
 
+/**
+ * EphyEmbed::populate-popup:
+ * @embed:
+ * @menu: The GtkMenu which will be displayed on right-click.
+ *
+ * The ::populate-popup signal is emitted when a new right-click menu is going
+ * to be displayed. It allowes the user to modify the GtkMenu before actually
+ * showing the menu.
+ **/
+    g_signal_new ("populate-popup",
+      EPHY_TYPE_EMBED,
+      (G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+      G_STRUCT_OFFSET (EphyEmbedIface, populate_popup),
+      NULL, NULL,
+      g_cclosure_marshal_VOID__OBJECT,
+      G_TYPE_NONE,
+      1,
+      GTK_TYPE_MENU);
+
 		initialized = TRUE;
 	}
-
 }
 
 /**
Index: embed/ephy-embed.h
===================================================================
--- embed/ephy-embed.h	(Revision 8630)
+++ embed/ephy-embed.h	(Arbeitskopie)
@@ -160,6 +160,8 @@
 	void	 (* new_document_now)	(EphyEmbed *embed,
 					 const char *uri);
 
+  void   (* populate_popup) (EphyEmbed *embed, GtkMenu *menu);
+
 	/* Methods  */
 	void		   (* load_url)			  (EphyEmbed *embed,
 							   const char *url);
