diff options
Diffstat (limited to 'embed')
-rw-r--r-- | embed/ephy-embed-event.c | 1 | ||||
-rw-r--r-- | embed/ephy-embed-event.h | 1 | ||||
-rw-r--r-- | embed/ephy-embed-popup-bw.c | 13 | ||||
-rw-r--r-- | embed/ephy-embed.c | 11 | ||||
-rw-r--r-- | embed/ephy-embed.h | 2 | ||||
-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 |
8 files changed, 158 insertions, 2 deletions
diff --git a/embed/ephy-embed-event.c b/embed/ephy-embed-event.c index 5ee7d2781..3df03f3dc 100644 --- a/embed/ephy-embed-event.c +++ b/embed/ephy-embed-event.c @@ -87,6 +87,7 @@ ephy_embed_event_init (EphyEmbedEvent *event) event->priv->props = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_g_value); + event->mouse_button = -1; } static void diff --git a/embed/ephy-embed-event.h b/embed/ephy-embed-event.h index 9291ae6ae..44448cce6 100644 --- a/embed/ephy-embed-event.h +++ b/embed/ephy-embed-event.h @@ -60,6 +60,7 @@ struct EphyEmbedEvent guint mouse_button; guint context; guint x, y; + guint keycode; }; struct EphyEmbedEventClass diff --git a/embed/ephy-embed-popup-bw.c b/embed/ephy-embed-popup-bw.c index 553f73205..f72e44e6e 100644 --- a/embed/ephy-embed-popup-bw.c +++ b/embed/ephy-embed-popup-bw.c @@ -162,6 +162,17 @@ ephy_embed_popup_bw_new (BonoboWindow *window) } static void +popup_menu_at_coords (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, + gpointer user_data) +{ + EphyEmbedEvent *event = user_data; + + *x = event->x; + *y = event->y; + *push_in = FALSE; +} + +static void ephy_embed_popup_bw_show_impl (EphyEmbedPopup *pp, EphyEmbed *embed) { @@ -181,7 +192,7 @@ ephy_embed_popup_bw_show_impl (EphyEmbedPopup *pp, ephy_embed_popup_get_popup_path (EPHY_EMBED_POPUP (p))); gtk_menu_popup (GTK_MENU (p->priv->menu), - NULL, NULL, NULL, NULL, + NULL, NULL, button == 2 ? popup_menu_at_coords : NULL, event, button, gtk_get_current_event_time ()); } diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c index 3360e9e67..ebc33b833 100644 --- a/embed/ephy-embed.c +++ b/embed/ephy-embed.c @@ -29,6 +29,7 @@ enum { NEW_WINDOW, + CONTEXT_MENU, LINK_MESSAGE, FAVICON, JS_STATUS, @@ -108,6 +109,16 @@ ephy_embed_base_init (gpointer g_class) G_TYPE_NONE, 1, G_TYPE_STRING); + ephy_embed_signals[CONTEXT_MENU] = + g_signal_new ("ge_context_menu", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyEmbedClass, context_menu), + NULL, NULL, + ephy_marshal_INT__OBJECT, + G_TYPE_INT, + 1, + G_TYPE_OBJECT); ephy_embed_signals[FAVICON] = g_signal_new ("ge_favicon", EPHY_EMBED_TYPE, diff --git a/embed/ephy-embed.h b/embed/ephy-embed.h index a80d11d80..6371dea98 100644 --- a/embed/ephy-embed.h +++ b/embed/ephy-embed.h @@ -164,6 +164,8 @@ struct EphyEmbedClass { GTypeInterface base_iface; + gint (* context_menu) (EphyEmbed *embed, + EphyEmbedEvent *event); void (* favicon) (EphyEmbed *embed, const char *location); void (* link_message) (EphyEmbed *embed, 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 |