aboutsummaryrefslogtreecommitdiffstats
path: root/embed
diff options
context:
space:
mode:
authorChristian Persch <chpe@cvs.gnome.org>2005-07-29 01:52:51 +0800
committerChristian Persch <chpe@src.gnome.org>2005-07-29 01:52:51 +0800
commit90586b820dea7fdb2588b24939ae72514f87c73d (patch)
tree8388e597298991275745bcb53908ad39b740dfbf /embed
parenta6467707fdbf7e67dbea0ba685dd0ba5c0ffbfdb (diff)
downloadgsoc2013-epiphany-90586b820dea7fdb2588b24939ae72514f87c73d.tar.gz
gsoc2013-epiphany-90586b820dea7fdb2588b24939ae72514f87c73d.tar.zst
gsoc2013-epiphany-90586b820dea7fdb2588b24939ae72514f87c73d.zip
Work around gtkmozembed focus bug. Fixes bug #105153.
2005-07-28 Christian Persch <chpe@cvs.gnome.org> * configure.ac: * embed/mozilla/EphyBrowser.cpp: * embed/mozilla/EphyBrowser.h: * embed/mozilla/mozilla-embed.cpp: * src/ephy-shell.c: (url_is_empty), (load_homepage), (ephy_shell_new_tab_full): Work around gtkmozembed focus bug. Fixes bug #105153.
Diffstat (limited to 'embed')
-rw-r--r--embed/mozilla/EphyBrowser.cpp27
-rw-r--r--embed/mozilla/EphyBrowser.h7
-rw-r--r--embed/mozilla/mozilla-embed.cpp77
3 files changed, 103 insertions, 8 deletions
diff --git a/embed/mozilla/EphyBrowser.cpp b/embed/mozilla/EphyBrowser.cpp
index ba295ef7c..231b5c4ac 100644
--- a/embed/mozilla/EphyBrowser.cpp
+++ b/embed/mozilla/EphyBrowser.cpp
@@ -536,6 +536,9 @@ nsresult EphyBrowser::Init (GtkMozEmbed *mozembed)
getter_AddRefs(mWebBrowser));
NS_ENSURE_TRUE (mWebBrowser, NS_ERROR_FAILURE);
+ mWebBrowserFocus = do_QueryInterface (mWebBrowser);
+ NS_ENSURE_TRUE (mWebBrowserFocus, NS_ERROR_FAILURE);
+
mWebBrowser->GetContentDOMWindow (getter_AddRefs (mDOMWindow));
NS_ENSURE_TRUE (mDOMWindow, NS_ERROR_FAILURE);
@@ -861,13 +864,9 @@ nsresult EphyBrowser::GetTargetDocument (nsIDOMDocument **aDOMDocument)
}
/* Use the focused document */
- nsCOMPtr<nsIWebBrowserFocus> webBrowserFocus;
- webBrowserFocus = do_QueryInterface (mWebBrowser);
- NS_ENSURE_TRUE (webBrowserFocus, NS_ERROR_FAILURE);
-
nsresult rv;
nsCOMPtr<nsIDOMWindow> DOMWindow;
- rv = webBrowserFocus->GetFocusedWindow (getter_AddRefs(DOMWindow));
+ rv = mWebBrowserFocus->GetFocusedWindow (getter_AddRefs(DOMWindow));
if (NS_SUCCEEDED (rv) && DOMWindow)
{
return DOMWindow->GetDocument (aDOMDocument);
@@ -1324,3 +1323,21 @@ EphyBrowser::GetDocumentType ()
return type;
}
+
+#ifdef GTKMOZEMBED_BROKEN_FOCUS
+nsresult
+EphyBrowser::FocusActivate ()
+{
+ NS_ENSURE_STATE (mWebBrowserFocus);
+
+ return mWebBrowserFocus->Activate();
+}
+
+nsresult
+EphyBrowser::FocusDeactivate ()
+{
+ NS_ENSURE_STATE (mWebBrowserFocus);
+
+ return mWebBrowserFocus->Deactivate();
+}
+#endif /* GTKMOZEMBED_BROKEN_FOCUS */
diff --git a/embed/mozilla/EphyBrowser.h b/embed/mozilla/EphyBrowser.h
index 279578e02..a4a0de502 100644
--- a/embed/mozilla/EphyBrowser.h
+++ b/embed/mozilla/EphyBrowser.h
@@ -34,6 +34,7 @@
#include <nsIWebNavigation.h>
#include <nsISHistory.h>
#include <nsIWebBrowser.h>
+#include <nsIWebBrowserFocus.h>
#include <nsIDOMDocument.h>
#include <nsIDOMWindow.h>
#include <nsIPrintSettings.h>
@@ -178,10 +179,16 @@ public:
EphyEmbedDocumentType GetDocumentType ();
+#ifdef GTKMOZEMBED_BROKEN_FOCUS
+ nsresult FocusActivate ();
+ nsresult FocusDeactivate ();
+#endif
+
nsCOMPtr<nsIWebBrowser> mWebBrowser;
private:
GtkWidget *mEmbed;
+ nsCOMPtr<nsIWebBrowserFocus> mWebBrowserFocus;
nsCOMPtr<nsIDOMDocument> mTargetDocument;
nsCOMPtr<nsIDOMEventTarget> mEventTarget;
nsCOMPtr<nsIDOMWindow> mDOMWindow;
diff --git a/embed/mozilla/mozilla-embed.cpp b/embed/mozilla/mozilla-embed.cpp
index 1029b5c05..4176821fc 100644
--- a/embed/mozilla/mozilla-embed.cpp
+++ b/embed/mozilla/mozilla-embed.cpp
@@ -91,12 +91,20 @@ struct MozillaEmbedPrivate
{
EphyBrowser *browser;
MozillaEmbedLoadState load_state;
+#ifdef GTKMOZEMBED_BROKEN_FOCUS
+ guint focus_connected : 1;
+#endif /* GTKMOZEMBED_BROKEN_FOCUS */
};
#define WINDOWWATCHER_CONTRACTID "@mozilla.org/embedcomp/window-watcher;1"
static GObjectClass *parent_class = NULL;
+#ifdef GTKMOZEMBED_BROKEN_FOCUS
+static guint fiesid = 0;
+static guint foesid = 0;
+#endif /* GTKMOZEMBED_BROKEN_FOCUS */
+
static void
impl_manager_do_command (EphyCommandManager *manager,
const char *command)
@@ -181,20 +189,78 @@ impl_activate (EphyEmbed *embed)
gtk_widget_grab_focus (GTK_BIN (embed)->child);
}
+#ifdef GTKMOZEMBED_BROKEN_FOCUS
+static gboolean
+child_focus_in_event_cb (GtkWidget *child,
+ GdkEventFocus *event,
+ MozillaEmbed *embed)
+{
+ embed->priv->browser->FocusActivate ();
+
+ return FALSE;
+}
+
+static gboolean
+child_focus_out_event_cb (GtkWidget *child,
+ GdkEventFocus *event,
+ MozillaEmbed *embed)
+{
+ embed->priv->browser->FocusDeactivate ();
+
+ return FALSE;
+}
+#endif /* GTKMOZEMBED_BROKEN_FOCUS */
+
static void
mozilla_embed_realize (GtkWidget *widget)
{
MozillaEmbedPrivate *mpriv = MOZILLA_EMBED (widget)->priv;
+ GtkBin *bin = GTK_BIN (widget);
- (* GTK_WIDGET_CLASS(parent_class)->realize) (widget);
+ GTK_WIDGET_CLASS (parent_class)->realize (widget);
+ /* Initialise our helper class */
nsresult rv;
rv = mpriv->browser->Init (GTK_MOZ_EMBED (widget));
-
if (NS_FAILED (rv))
{
- g_warning ("EphyBrowser initialization failed for %p\n", widget);
+ g_warning ("EphyBrowser initialization failed for %p\n", widget);
+ return;
}
+
+#ifdef GTKMOZEMBED_BROKEN_FOCUS
+ /* HACK ALERT! This depends highly on undocumented interna of
+ * GtkMozEmbed!
+ *
+ * GtkMozEmbed::realize installs focus-[in|out]-event handlers to
+ * toplevel, and, on the first realize only, to the child.
+ * GtkMozEmbed disconnects its focus-[in|out]-event handler
+ * to the toplevel on unrealize, and leaves the ones to the child
+ * in place. So we don't need to unblock the blocked handlers
+ * and therefore need no ::unrealize handler.
+ */
+
+ GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+ gpointer data = ((GtkMozEmbed *) widget)->data;
+
+ g_signal_handlers_block_matched (toplevel,
+ (GSignalMatchType) (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
+ fiesid, 0, NULL, NULL, data);
+ g_signal_handlers_block_matched (toplevel,
+ (GSignalMatchType) (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
+ foesid, 0, NULL, NULL, data);
+
+ if (mpriv->focus_connected) return;
+
+ g_signal_connect_object (bin->child, "focus-in-event",
+ G_CALLBACK (child_focus_in_event_cb), widget,
+ G_CONNECT_AFTER);
+ g_signal_connect_object (bin->child, "focus-out-event",
+ G_CALLBACK (child_focus_out_event_cb), widget,
+ G_CONNECT_AFTER);
+
+ mpriv->focus_connected = TRUE;
+#endif /* GTKMOZEMBED_BROKEN_FOCUS */
}
static GObject *
@@ -226,6 +292,11 @@ mozilla_embed_class_init (MozillaEmbedClass *klass)
widget_class->realize = mozilla_embed_realize;
+#ifdef GTKMOZEMBED_BROKEN_FOCUS
+ fiesid = g_signal_lookup ("focus-in-event", GTK_TYPE_WIDGET);
+ foesid = g_signal_lookup ("focus-out-event", GTK_TYPE_WIDGET);
+#endif /* GTKMOZEMBED_BROKEN_FOCUS */
+
g_type_class_add_private (object_class, sizeof(MozillaEmbedPrivate));
}