diff options
Diffstat (limited to 'embed/mozilla')
-rw-r--r-- | embed/mozilla/EventContext.cpp | 58 | ||||
-rw-r--r-- | embed/mozilla/EventContext.h | 1 | ||||
-rw-r--r-- | embed/mozilla/mozilla-embed.cpp | 73 |
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 |