diff options
author | Christian Persch <chpe@cvs.gnome.org> | 2005-07-29 01:52:51 +0800 |
---|---|---|
committer | Christian Persch <chpe@src.gnome.org> | 2005-07-29 01:52:51 +0800 |
commit | 90586b820dea7fdb2588b24939ae72514f87c73d (patch) | |
tree | 8388e597298991275745bcb53908ad39b740dfbf /embed | |
parent | a6467707fdbf7e67dbea0ba685dd0ba5c0ffbfdb (diff) | |
download | gsoc2013-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.cpp | 27 | ||||
-rw-r--r-- | embed/mozilla/EphyBrowser.h | 7 | ||||
-rw-r--r-- | embed/mozilla/mozilla-embed.cpp | 77 |
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)); } |