aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Persch <chpe@cvs.gnome.org>2005-08-16 06:22:31 +0800
committerChristian Persch <chpe@src.gnome.org>2005-08-16 06:22:31 +0800
commit0cba580858576aba1d4f2b4480e91dc3570c8d62 (patch)
tree43678464382a6fe9f188a82f58cb5054d479feac
parent02250ba19947aab8a099d2890649768e90ff3009 (diff)
downloadgsoc2013-epiphany-0cba580858576aba1d4f2b4480e91dc3570c8d62.tar
gsoc2013-epiphany-0cba580858576aba1d4f2b4480e91dc3570c8d62.tar.gz
gsoc2013-epiphany-0cba580858576aba1d4f2b4480e91dc3570c8d62.tar.bz2
gsoc2013-epiphany-0cba580858576aba1d4f2b4480e91dc3570c8d62.tar.lz
gsoc2013-epiphany-0cba580858576aba1d4f2b4480e91dc3570c8d62.tar.xz
gsoc2013-epiphany-0cba580858576aba1d4f2b4480e91dc3570c8d62.tar.zst
gsoc2013-epiphany-0cba580858576aba1d4f2b4480e91dc3570c8d62.zip
Activate the found link with a faked keypress event.
2005-08-16 Christian Persch <chpe@cvs.gnome.org> * embed/ephy-embed-find.c: (ephy_embed_find_activate_link): * embed/ephy-embed-find.h: * embed/mozilla/EphyFind.cpp: * embed/mozilla/EphyFind.h: * embed/mozilla/mozilla-embed-find.cpp: Activate the found link with a faked keypress event. * src/ephy-find-toolbar.c: (tab_search_key_press_cb), (entry_key_press_event_cb), (entry_activate_cb), (ephy_find_toolbar_set_embed), (ephy_find_toolbar_open), (ephy_find_toolbar_close): On enter, activate the found link instead of finding the next occurrence. Always really give focus to the find bar, instead of faking keypresses in the find bar entry while focusing the embed. Fixes bug #307216, bug #311985, bug #312419.
-rw-r--r--ChangeLog21
-rw-r--r--embed/ephy-embed-find.c15
-rw-r--r--embed/ephy-embed-find.h6
-rw-r--r--embed/mozilla/EphyFind.cpp86
-rw-r--r--embed/mozilla/EphyFind.h5
-rw-r--r--embed/mozilla/mozilla-embed-find.cpp11
-rw-r--r--src/ephy-find-toolbar.c38
7 files changed, 167 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 33119422e..ddbbe3259 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2005-08-16 Christian Persch <chpe@cvs.gnome.org>
+
+ * embed/ephy-embed-find.c: (ephy_embed_find_activate_link):
+ * embed/ephy-embed-find.h:
+ * embed/mozilla/EphyFind.cpp:
+ * embed/mozilla/EphyFind.h:
+ * embed/mozilla/mozilla-embed-find.cpp:
+
+ Activate the found link with a faked keypress event.
+
+ * src/ephy-find-toolbar.c: (tab_search_key_press_cb),
+ (entry_key_press_event_cb), (entry_activate_cb),
+ (ephy_find_toolbar_set_embed), (ephy_find_toolbar_open),
+ (ephy_find_toolbar_close):
+
+ On enter, activate the found link instead of finding the next
+ occurrence.
+ Always really give focus to the find bar, instead of faking
+ keypresses in the find bar entry while focusing the embed.
+ Fixes bug #307216, bug #311985, bug #312419.
+
2005-08-15 Christian Persch <chpe@cvs.gnome.org>
* data/GNOME_Epiphany_Automation.server.in:
diff --git a/embed/ephy-embed-find.c b/embed/ephy-embed-find.c
index 596c0b8bc..f5ddb664e 100644
--- a/embed/ephy-embed-find.c
+++ b/embed/ephy-embed-find.c
@@ -70,6 +70,21 @@ ephy_embed_find_find_again (EphyEmbedFind *find,
return iface->find_again (find, forward);
}
+/**
+ * ephy_embed_find_activate_link:
+ * @embed: an #EphyEmbedFind
+ * @mask:
+ *
+ * Activates the currently focused link, if there is any.
+ **/
+gboolean
+ephy_embed_find_activate_link (EphyEmbedFind *find,
+ GdkModifierType mask)
+{
+ EphyEmbedFindIface *iface = EPHY_EMBED_FIND_GET_IFACE (find);
+ return iface->activate_link (find, mask);
+}
+
GType
ephy_embed_find_get_type (void)
{
diff --git a/embed/ephy-embed-find.h b/embed/ephy-embed-find.h
index 6dbabe7db..a601c9a4e 100644
--- a/embed/ephy-embed-find.h
+++ b/embed/ephy-embed-find.h
@@ -25,6 +25,7 @@
#include <glib.h>
#include "ephy-embed.h"
+#include <gdk/gdktypes.h>
G_BEGIN_DECLS
@@ -54,6 +55,8 @@ struct _EphyEmbedFindIface
gboolean links_only);
gboolean (* find_again) (EphyEmbedFind *find,
gboolean forward);
+ gboolean (* activate_link) (EphyEmbedFind *find,
+ GdkModifierType mask);
};
GType ephy_embed_find_get_type (void);
@@ -72,6 +75,9 @@ gboolean ephy_embed_find_find (EphyEmbedFind *find,
gboolean ephy_embed_find_find_again (EphyEmbedFind *find,
gboolean forward);
+gboolean ephy_embed_find_activate_link (EphyEmbedFind *find,
+ GdkModifierType mask);
+
G_END_DECLS
#endif
diff --git a/embed/mozilla/EphyFind.cpp b/embed/mozilla/EphyFind.cpp
index ace176b23..224e85081 100644
--- a/embed/mozilla/EphyFind.cpp
+++ b/embed/mozilla/EphyFind.cpp
@@ -37,6 +37,17 @@
#include <nsIInterfaceRequestorUtils.h>
#include <nsIDOMWindow.h>
#include <nsIWebBrowser.h>
+#include <nsIWebBrowserFocus.h>
+#include <nsIDOMNode.h>
+#include <nsIDOMElement.h>
+#include <nsIDOMDocument.h>
+#include <nsIDOMDocumentView.h>
+#include <nsIDOMAbstractView.h>
+#include <nsIDOMDocumentEvent.h>
+#include <nsIDOMEvent.h>
+#include <nsIDOMKeyEvent.h>
+#include <nsIDOMEventTarget.h>
+#include <nsIDOMHTMLAnchorElement.h>
#ifdef HAVE_TYPEAHEADFIND
#include <nsIDocShell.h>
@@ -52,6 +63,9 @@
#define NS_TYPEAHEADFIND_CONTRACTID "@mozilla.org/typeaheadfind;1"
#endif /* HAVE_TYPEAHEADFIND */
+static const PRUnichar kKeyEvents[] = { 'K', 'e', 'y', 'E', 'v', 'e', 'n', 't', 's', '\0' };
+static const PRUnichar kKeyPress[] = { 'k', 'e', 'y', 'p', 'r', 'e', 's', 's', '\0' };
+
EphyFind::EphyFind ()
: mCurrentEmbed(nsnull)
{
@@ -70,15 +84,15 @@ EphyFind::SetEmbed (EphyEmbed *aEmbed)
if (aEmbed == mCurrentEmbed) return rv;
mCurrentEmbed = nsnull;
+ mWebBrowser = nsnull;
rv = NS_ERROR_FAILURE;
- nsCOMPtr<nsIWebBrowser> webBrowser;
gtk_moz_embed_get_nsIWebBrowser (GTK_MOZ_EMBED (aEmbed),
- getter_AddRefs (webBrowser));
- NS_ENSURE_TRUE (webBrowser, rv);
+ getter_AddRefs (mWebBrowser));
+ NS_ENSURE_TRUE (mWebBrowser, rv);
#ifdef HAVE_TYPEAHEADFIND
- nsCOMPtr<nsIDocShell> docShell (do_GetInterface (webBrowser, &rv));
+ nsCOMPtr<nsIDocShell> docShell (do_GetInterface (mWebBrowser, &rv));
NS_ENSURE_SUCCESS (rv, rv);
if (!mFinder) {
@@ -97,7 +111,7 @@ EphyFind::SetEmbed (EphyEmbed *aEmbed)
mFinder->GetSearchString (&string);
}
- mFinder = do_GetInterface (webBrowser, &rv);
+ mFinder = do_GetInterface (mWebBrowser, &rv);
NS_ENSURE_SUCCESS (rv, rv);
mFinder->SetWrapFind (PR_TRUE);
@@ -186,3 +200,65 @@ EphyFind::FindAgain (PRBool aForward)
return NS_SUCCEEDED (rv) && didFind;
#endif /* HAVE_TYPEAHEADFIND */
}
+
+PRBool
+EphyFind::ActivateLink (GdkModifierType aMask)
+{
+ nsresult rv;
+ nsCOMPtr<nsIDOMElement> link;
+#if defined(HAVE_TYPEAHEADFIND) && defined(HAVE_GECKO_1_8)
+ rv = mFinder->GetFoundLink (getter_AddRefs (link));
+ NS_ENSURE_TRUE (NS_SUCCEEDED (rv) && link, FALSE);
+#else
+ nsCOMPtr<nsIWebBrowserFocus> focus (do_QueryInterface (mWebBrowser));
+ NS_ENSURE_TRUE (focus, FALSE);
+
+ rv = focus->GetFocusedElement (getter_AddRefs (link));
+ NS_ENSURE_TRUE (NS_SUCCEEDED (rv) && link, FALSE);
+
+ /* ensure this is really a link so we don't accidentally submit if we're on a button or so! */
+ nsCOMPtr<nsIDOMHTMLAnchorElement> anchor (do_QueryInterface (link));
+ if (!anchor) return FALSE;
+#endif /* HAVE_TYPEAHEADFIND && HAVE_GECKO_1_8 */
+
+ nsCOMPtr<nsIDOMDocument> doc;
+ rv = link->GetOwnerDocument (getter_AddRefs (doc));
+ NS_ENSURE_TRUE (doc, FALSE);
+
+ nsCOMPtr<nsIDOMDocumentView> docView (do_QueryInterface (doc));
+ NS_ENSURE_TRUE (docView, FALSE);
+
+ nsCOMPtr<nsIDOMAbstractView> abstractView;
+ docView->GetDefaultView (getter_AddRefs (abstractView));
+ NS_ENSURE_TRUE (abstractView, FALSE);
+
+ nsCOMPtr<nsIDOMDocumentEvent> docEvent (do_QueryInterface (doc));
+ NS_ENSURE_TRUE (docEvent, FALSE);
+
+ nsCOMPtr<nsIDOMEvent> event;
+ rv = docEvent->CreateEvent (nsEmbedString(kKeyEvents), getter_AddRefs (event));
+ NS_ENSURE_SUCCESS (rv, FALSE);
+
+ nsCOMPtr<nsIDOMKeyEvent> keyEvent (do_QueryInterface (event));
+ NS_ENSURE_TRUE (keyEvent, FALSE);
+
+ rv = keyEvent->InitKeyEvent (nsEmbedString (kKeyPress),
+ PR_TRUE /* bubble */,
+ PR_TRUE /* cancelable */,
+ abstractView,
+ (aMask & GDK_CONTROL_MASK) != 0,
+ (aMask & GDK_MOD1_MASK) != 0 /* Alt */,
+ (aMask & GDK_SHIFT_MASK) != 0,
+ PR_FALSE /* Meta */,
+ nsIDOMKeyEvent::DOM_VK_RETURN,
+ 0);
+ NS_ENSURE_SUCCESS (rv, FALSE);
+
+ nsCOMPtr<nsIDOMEventTarget> target (do_QueryInterface (link));
+ NS_ENSURE_TRUE (target, FALSE);
+
+ PRBool defaultPrevented = PR_FALSE;
+ rv = target->DispatchEvent (event, &defaultPrevented);
+
+ return NS_SUCCEEDED (rv);
+}
diff --git a/embed/mozilla/EphyFind.h b/embed/mozilla/EphyFind.h
index 7188ffb74..8e85356cb 100644
--- a/embed/mozilla/EphyFind.h
+++ b/embed/mozilla/EphyFind.h
@@ -24,8 +24,10 @@
#include "ephy-embed.h"
#include <nsCOMPtr.h>
+#include <gdk/gdktypes.h>
class nsITypeAheadFind;
+class nsIWebBrowser;
class nsIWebBrowserFind;
class EphyFind
@@ -41,10 +43,13 @@ class EphyFind
PRBool Find (const char *aSearchString,
PRBool aLinksOnly);
PRBool FindAgain (PRBool aForward);
+ PRBool ActivateLink (GdkModifierType aMask);
private:
EphyEmbed *mCurrentEmbed;
+ nsCOMPtr<nsIWebBrowser> mWebBrowser;
+
#ifdef HAVE_TYPEAHEADFIND
nsCOMPtr<nsITypeAheadFind> mFinder;
#else
diff --git a/embed/mozilla/mozilla-embed-find.cpp b/embed/mozilla/mozilla-embed-find.cpp
index d039b4d69..f8f4e6c60 100644
--- a/embed/mozilla/mozilla-embed-find.cpp
+++ b/embed/mozilla/mozilla-embed-find.cpp
@@ -83,6 +83,16 @@ impl_find_again (EphyEmbedFind *efind,
return priv->find->FindAgain (forward);
}
+static gboolean
+impl_activate_link (EphyEmbedFind *efind,
+ GdkModifierType mask)
+{
+ MozillaEmbedFind *find = MOZILLA_EMBED_FIND (efind);
+ MozillaEmbedFindPrivate *priv = find->priv;
+
+ return priv->find->ActivateLink (mask);
+}
+
static void
ephy_find_iface_init (EphyEmbedFindIface *iface)
{
@@ -90,6 +100,7 @@ ephy_find_iface_init (EphyEmbedFindIface *iface)
iface->set_properties = impl_set_properties;
iface->find = impl_find;
iface->find_again = impl_find_again;
+ iface->activate_link = impl_activate_link;
}
static void
diff --git a/src/ephy-find-toolbar.c b/src/ephy-find-toolbar.c
index 2ae7d15ed..59eee34c2 100644
--- a/src/ephy-find-toolbar.c
+++ b/src/ephy-find-toolbar.c
@@ -40,6 +40,8 @@
#include <gtk/gtkmain.h>
#include <string.h>
+#undef FIND_WHILE_TYPING_IN_EMBED
+
#define EPHY_FIND_TOOLBAR_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object),EPHY_TYPE_FIND_TOOLBAR, EphyFindToolbarPrivate))
struct _EphyFindToolbarPrivate
@@ -118,6 +120,8 @@ tab_content_changed_cb (EphyEmbed *embed,
#ifdef HAVE_TYPEAHEADFIND
+#ifdef FIND_WHILE_TYPING_IN_EMBED
+
/* Cut and paste from gtkwindow.c */
static void
send_focus_change (GtkWidget *widget,
@@ -150,6 +154,8 @@ send_focus_change (GtkWidget *widget,
gdk_event_free (event);
}
+#endif /* FIND_WHILE_TYPING_IN_EMBED */
+
/* Code adapted from gtktreeview.c:gtk_tree_view_key_press() and
* gtk_tree_view_real_start_interactive_seach()
*/
@@ -160,10 +166,12 @@ tab_search_key_press_cb (EphyEmbed *embed,
{
EphyFindToolbarPrivate *priv = toolbar->priv;
GtkWidget *widget = (GtkWidget *) toolbar;
+#ifdef FIND_WHILE_TYPING_IN_EMBED
GtkEntry *entry = (GtkEntry *) priv->entry;
GdkWindow *event_window;
gboolean retval = FALSE;
guint oldhash, newhash;
+#endif
g_return_val_if_fail (event != NULL, FALSE);
@@ -184,7 +192,10 @@ tab_search_key_press_cb (EphyEmbed *embed,
return TRUE;
}
}
-
+
+ return FALSE;
+
+#ifdef FIND_WHILE_TYPING_IN_EMBED
/* don't do anything if the find toolbar is hidden */
if (GTK_WIDGET_VISIBLE (widget) == FALSE ||
event->keyval == GDK_Return ||
@@ -212,8 +223,11 @@ tab_search_key_press_cb (EphyEmbed *embed,
/* FIXME: is this correct? */
return retval && (oldhash != newhash || priv->preedit_changed) && !priv->activated;
+#endif /* FIND_WHILE_TYPING_IN_EMBED */
}
+#ifdef FIND_WHILE_TYPING_IN_EMBED
+
static gboolean
tab_dom_mouse_click_cb (EphyEmbed *embed,
gpointer event,
@@ -229,6 +243,8 @@ tab_dom_mouse_click_cb (EphyEmbed *embed,
return FALSE;
}
+#endif /* FIND_WHILE_TYPING_IN_EMBED */
+
#endif /* HAVE_TYPEAHEADFIND */
static void
@@ -289,6 +305,11 @@ entry_key_press_event_cb (GtkEntry *entry,
g_signal_emit (toolbar, signals[CLOSE], 0);
handled = TRUE;
}
+ else if ((event->state & mask) == GDK_CONTROL_MASK &&
+ (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter))
+ {
+ handled = ephy_embed_find_activate_link (get_find (toolbar), event->state);
+ }
return handled;
}
@@ -297,12 +318,7 @@ static void
entry_activate_cb (GtkWidget *entry,
EphyFindToolbar *toolbar)
{
- EphyFindToolbarPrivate *priv = toolbar->priv;
-
- priv->activated = TRUE;
- if (priv->prevent_activate) return;
-
- g_signal_emit (toolbar, signals[NEXT], 0);
+ ephy_embed_find_activate_link (get_find (toolbar), 0);
}
static void
@@ -621,10 +637,12 @@ ephy_find_toolbar_set_embed (EphyFindToolbar *toolbar,
g_signal_connect_object (embed, "ge-search-key-press",
G_CALLBACK (tab_search_key_press_cb),
toolbar, 0);
+#ifdef FIND_WHILE_TYPING_IN_EMBED
g_signal_connect_object (embed, "dom-mouse-click",
G_CALLBACK (tab_dom_mouse_click_cb),
toolbar, 0);
-#endif
+#endif /* FIND_WHILE_TYPING_IN_EMBED */
+#endif /* HAVE_TYPEAHEADFIND */
if (priv->find != NULL)
{
@@ -676,7 +694,7 @@ ephy_find_toolbar_open (EphyFindToolbar *toolbar,
gtk_widget_show (GTK_WIDGET (toolbar));
-#ifdef HAVE_TYPEAHEADFIND
+#if defined(HAVE_TYPEAHEADFIND) && defined(FIND_WHILE_TYPING_IN_EMBED)
gtk_widget_grab_focus (GTK_WIDGET (priv->embed));
send_focus_change (priv->entry, TRUE);
@@ -702,7 +720,7 @@ ephy_find_toolbar_close (EphyFindToolbar *toolbar)
/* first unset explicit_focus, else we get infinite recursion */
priv->explicit_focus = FALSE;
-#ifndef HAVE_TYPEAHEADFIND
+#ifndef FIND_WHILE_TYPING_IN_EMBED
gtk_widget_grab_focus (GTK_WIDGET (priv->embed));
#endif
}