aboutsummaryrefslogtreecommitdiffstats
path: root/embed/mozilla
diff options
context:
space:
mode:
Diffstat (limited to 'embed/mozilla')
-rw-r--r--embed/mozilla/EventContext.cpp58
-rw-r--r--embed/mozilla/EventContext.h1
-rw-r--r--embed/mozilla/mozilla-embed.cpp73
3 files changed, 131 insertions, 1 deletions
diff --git a/embed/mozilla/EventContext.cpp b/embed/mozilla/EventContext.cpp
index 7fa44acc0..229f8d3be 100644
--- a/embed/mozilla/EventContext.cpp
+++ b/embed/mozilla/EventContext.cpp
@@ -586,6 +586,64 @@ nsresult EventContext::GetMouseEventInfo (nsIDOMMouseEvent *aMouseEvent, EphyEmb
return NS_OK;
}
+nsresult EventContext::GetKeyEventInfo (nsIDOMKeyEvent *aKeyEvent, EphyEmbedEvent *info)
+{
+ nsresult rv;
+
+ PRUint32 keyCode;
+ rv = aKeyEvent->GetKeyCode(&keyCode);
+ if (NS_FAILED(rv)) return rv;
+ info->keycode = keyCode;
+
+ nsCOMPtr<nsIDOMEventTarget> target;
+ rv = aKeyEvent->GetTarget(getter_AddRefs(target));
+ if (NS_FAILED(rv) || !target) return NS_ERROR_FAILURE;
+
+ /* Calculate the node coordinates relative to the widget origin */
+ nsCOMPtr<nsIDOMNSHTMLElement> elem = do_QueryInterface(target, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ PRInt32 x = 0, y = 0;
+ while (elem)
+ {
+ PRInt32 val;
+ elem->GetOffsetTop(&val); y += val;
+ elem->GetScrollTop(&val); y -= val;
+ elem->GetOffsetLeft(&val); x += val;
+ elem->GetScrollLeft(&val); x -= val;
+
+ nsCOMPtr<nsIDOMElement> parent;
+ elem->GetOffsetParent(getter_AddRefs(parent));
+ elem = do_QueryInterface(parent, &rv);
+ }
+ info->x = x;
+ info->y = y;
+
+ /* Context */
+ rv = GetEventContext (target, info);
+ if (NS_FAILED(rv)) return rv;
+
+ /* Get the modifier */
+
+ PRBool mod_key;
+
+ info->modifier = 0;
+
+ aKeyEvent->GetAltKey(&mod_key);
+ if (mod_key) info->modifier |= GDK_MOD1_MASK;
+
+ aKeyEvent->GetShiftKey(&mod_key);
+ if (mod_key) info->modifier |= GDK_SHIFT_MASK;
+
+ aKeyEvent->GetMetaKey(&mod_key);
+ if (mod_key) info->modifier |= GDK_Meta_L;
+
+ aKeyEvent->GetCtrlKey(&mod_key);
+ if (mod_key) info->modifier |= GDK_CONTROL_MASK;
+
+ return NS_OK;
+}
+
nsresult EventContext::IsPageFramed (nsIDOMNode *node, PRBool *Framed)
{
nsresult result;
diff --git a/embed/mozilla/EventContext.h b/embed/mozilla/EventContext.h
index 8025fb353..54c51b035 100644
--- a/embed/mozilla/EventContext.h
+++ b/embed/mozilla/EventContext.h
@@ -45,6 +45,7 @@ public:
nsresult Init (EphyWrapper *wrapper);
nsresult GetMouseEventInfo (nsIDOMMouseEvent *event, EphyEmbedEvent *info);
+ nsresult GetKeyEventInfo (nsIDOMKeyEvent *event, EphyEmbedEvent *info);
nsresult GetTargetDocument (nsIDOMDocument **domDoc);
private:
diff --git a/embed/mozilla/mozilla-embed.cpp b/embed/mozilla/mozilla-embed.cpp
index f578fb198..95dd0190e 100644
--- a/embed/mozilla/mozilla-embed.cpp
+++ b/embed/mozilla/mozilla-embed.cpp
@@ -206,6 +206,9 @@ mozilla_embed_security_change_cb (GtkMozEmbed *embed,
guint state, MozillaEmbed *membed);
static EmbedSecurityLevel
mozilla_embed_security_level (MozillaEmbed *membed);
+static gint
+mozilla_embed_dom_key_down_cb (GtkMozEmbed *embed, gpointer dom_event,
+ MozillaEmbed *membed);
/* signals to connect on each embed widget */
static const struct
@@ -228,6 +231,7 @@ signal_connections[] =
{ "size_to", (void *) mozilla_embed_size_to_cb },
{ "new_window", (void *) mozilla_embed_new_window_cb },
{ "security_change", (void *) mozilla_embed_security_change_cb },
+ { "dom_key_down", (void *) mozilla_embed_dom_key_down_cb },
/* terminator -- must be last in the list! */
{ NULL, NULL }
@@ -1312,6 +1316,63 @@ mozilla_embed_visibility_cb (GtkMozEmbed *embed, gboolean visibility,
}
}
+static gint
+mozilla_embed_dom_key_down_cb (GtkMozEmbed *embed, gpointer dom_event,
+ MozillaEmbed *membed)
+{
+ nsCOMPtr<nsIDOMKeyEvent> ev = static_cast<nsIDOMKeyEvent*>(dom_event);
+ if (!ev)
+ {
+ return FALSE;
+ }
+
+ EphyWrapper *wrapper = MOZILLA_EMBED(membed)->priv->wrapper;
+ g_return_val_if_fail (wrapper != NULL, G_FAILED);
+
+ EphyEmbedEvent *info;
+ info = ephy_embed_event_new ();
+
+ gboolean ret = FALSE;
+
+ // Just check for Shift-F10 so that we know to popup the context menu.
+ //
+ // The DOM_VK_* keycodes are not compatible with the keycodes defined
+ // in GDK, so making a generic dom_key_down signal is probably not
+ // worth the trouble.
+
+ nsresult rv;
+ EventContext ctx;
+ ctx.Init (wrapper);
+ rv = ctx.GetKeyEventInfo (ev, info);
+ if (NS_SUCCEEDED(rv) &&
+ (info->keycode == nsIDOMKeyEvent::DOM_VK_F10 &&
+ info->modifier == GDK_SHIFT_MASK))
+ {
+ // Translate relative coordinates to absolute values, and try
+ // to avoid covering links by adding a little offset.
+
+ int x, y;
+ gdk_window_get_origin (GTK_WIDGET(membed)->window, &x, &y);
+ info->x += x + 6;
+ info->y += y + 6;
+
+ nsCOMPtr<nsIDOMDocument> doc;
+ rv = ctx.GetTargetDocument (getter_AddRefs(doc));
+ if (NS_SUCCEEDED(rv))
+ {
+ rv = wrapper->PushTargetDocument (doc);
+ if (NS_SUCCEEDED(rv))
+ {
+ g_signal_emit_by_name (membed, "ge_context_menu", info, &ret);
+ wrapper->PopTargetDocument ();
+ }
+ }
+ }
+
+ g_object_unref (info);
+ return ret;
+}
+
static void
mozilla_embed_destroy_brsr_cb (GtkMozEmbed *embed,
MozillaEmbed *membed)
@@ -1371,8 +1432,18 @@ static gint
mozilla_embed_dom_mouse_down_cb (GtkMozEmbed *embed, gpointer dom_event,
MozillaEmbed *membed)
{
- return mozilla_embed_emit_mouse_signal
+ int ret;
+
+ ret = mozilla_embed_emit_mouse_signal
(membed, dom_event, "ge_dom_mouse_down");
+
+ if (!ret)
+ {
+ ret = mozilla_embed_emit_mouse_signal
+ (membed, dom_event, "ge_context_menu");
+ }
+
+ return ret;
}
static void