tags 294152 + fixed-upstream upstream
retitle 294152 focus problem with new tabs
thanks
Hi,
Sanjoy Mahajan <[EMAIL PROTECTED]> - Mon, Feb 07, 2005:
> After loading a link in a new tab with ctrl-left button (but not
> switching to the new page), I need to click on a non-active area in
> the creating page before PageUp and PageDown will scroll up and down.
> I'd prefer that galeon preserve the user-interface context of the
> creating page, so that ctrl-left button does not affect the user's
> interaction with the creating page.
The bug you reported should be fixed in upstream source code. The fix
will be available with next release. I could not easily backport a
patch for 1.3.19, I attach the upstream patch though.
Regards,
--
Lo�c Minier <[EMAIL PROTECTED]>
"Neutral President: I have no strong feelings one way or the other."
--- orig/mozilla/GaleonWrapper.cpp
+++ mod/mozilla/GaleonWrapper.cpp
@@ -383,6 +383,27 @@ nsresult GaleonWrapper::GetZoom (float *
return mdv->GetTextZoom (aZoom);
}
+nsresult GaleonWrapper::FocusActivate ()
+{
+ g_return_val_if_fail (mWebBrowser, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIWebBrowserFocus> focus = do_GetInterface(mWebBrowser);
+ NS_ENSURE_TRUE (focus, NS_ERROR_FAILURE);
+
+ return focus->Activate();
+}
+
+nsresult GaleonWrapper::FocusDeactivate ()
+{
+ g_return_val_if_fail (mWebBrowser, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIWebBrowserFocus> focus = do_GetInterface(mWebBrowser);
+ NS_ENSURE_TRUE (focus, NS_ERROR_FAILURE);
+
+ return focus->Deactivate();
+}
+
+
nsresult GaleonWrapper::GetFocusedDOMWindow (nsIDOMWindow **aDOMWindow)
{
nsresult rv;
--- orig/mozilla/GaleonWrapper.h
+++ mod/mozilla/GaleonWrapper.h
@@ -117,6 +117,8 @@ class GaleonWrapper
nsresult GetMainDocumentUrl (nsACString &url);
nsresult GetDocumentUrl (nsACString &url);
+ nsresult FocusActivate ();
+ nsresult FocusDeactivate ();
#ifdef HAVE_GTKMOZEMBED_BROKEN_RELOAD
nsresult ReloadPage (GtkMozEmbedReloadFlags reloadFlags);
--- orig/mozilla/mozilla-embed.cpp
+++ mod/mozilla/mozilla-embed.cpp
@@ -76,7 +76,8 @@ struct MozillaEmbedPrivate
{
MozillaEmbedPrivate() : wrapper(NULL), security_state(-1),
load_state (MOZILLA_EMBED_LOAD_STARTED),
- loaded_url (FALSE), loading_url(0)
+ loaded_url (FALSE), loading_url(0),
+ focus_timeout(0)
{ /* nothing */ }
GaleonWrapper *wrapper;
@@ -94,6 +95,10 @@ struct MozillaEmbedPrivate
*/
gboolean loaded_url; //!< Has a web page been loaded
gchar *loading_url; //!< The URL we are trying to load
+
+
+ // Timeout for the focus hack
+ guint focus_timeout;
};
static GObjectClass *parent_class = NULL;
@@ -151,6 +156,44 @@ mozilla_embed_child_event_after_cb (GtkW
return FALSE;
}
+
+/**
+ * Timeout so that the focus is set correctly for the Mozilla Embed
+ * this needs to be in a timeout, otherwise for some reason it doesn't seem
+ * to work correctly
+ */
+static gboolean
+activate_focus_timeout_cb (gpointer pointer)
+{
+ MozillaEmbed *embed = MOZILLA_EMBED (pointer);
+
+ embed->priv->focus_timeout = 0;
+
+ if (embed->priv->wrapper)
+ {
+ embed->priv->wrapper->FocusActivate();
+ }
+
+ return FALSE;
+}
+
+
+static gboolean
+deactivate_focus_timeout_cb (gpointer pointer)
+{
+ MozillaEmbed *embed = MOZILLA_EMBED (pointer);
+
+ embed->priv->focus_timeout = 0;
+
+ if (embed->priv->wrapper)
+ {
+ embed->priv->wrapper->FocusDeactivate();
+ }
+
+ return FALSE;
+}
+
+
/**
* Hack: Whenever the *user* wants the focus on the embed there's always going
* to be an associated GdkEvent (click on embed, enter on location entry,
etc...)
@@ -165,16 +208,54 @@ static void
mozilla_embed_child_grab_focus_cb (GtkWidget *widget, MozillaEmbed *embed)
{
GdkEvent *event;
+ GtkWidget *focused, *toplevel;
event = gtk_get_current_event ();
- if (!event)
+ if (event)
{
- g_signal_stop_emission_by_name (widget, "grab-focus");
+ gdk_event_free (event);
+ return;
}
- else
+
+ /* Find the GtkWidget that currently has focus, and if it
+ * is the MozContainer, find the corresponding MozillaEmbed */
+ toplevel = gtk_widget_get_toplevel (widget);
+ focused = gtk_window_get_focus (GTK_WINDOW (toplevel));
+
+ if (focused && !strcmp ("MozContainer", G_OBJECT_TYPE_NAME (focused)))
{
- gdk_event_free (event);
+ focused = gtk_widget_get_parent (focused);
+ }
+
+ if (focused && GTK_WIDGET (embed) != focused)
+ {
+ g_signal_stop_emission_by_name (widget, "grab-focus");
+
+ /* Focus was trying to move, so deactivate embed which
+ * attempted to grab it */
+ if (embed->priv->focus_timeout)
+ {
+ g_source_remove (embed->priv->focus_timeout);
+ }
+ embed->priv->focus_timeout =
+ g_timeout_add (0, deactivate_focus_timeout_cb, embed);
+
+
+ if (MOZILLA_IS_EMBED (focused))
+ {
+ MozillaEmbed *membed = MOZILLA_EMBED (focused);
+
+ if (membed->priv->focus_timeout)
+ {
+ g_source_remove (membed->priv->focus_timeout);
+ }
+
+ /* And if the old widget was a mozille embed,
+ * let it grab the focus back again */
+ membed->priv->focus_timeout =
+ g_timeout_add (0, activate_focus_timeout_cb,
membed);
+ }
}
}
@@ -278,6 +359,11 @@ mozilla_embed_finalize (GObject *object)
embed->priv->wrapper = NULL;
}
+ if (embed->priv->focus_timeout)
+ {
+ g_source_remove (embed->priv->focus_timeout);
+ }
+
g_free (embed->priv->loading_url);
delete embed->priv;
--- orig/src/galeon-shell.c
+++ mod/src/galeon-shell.c
@@ -714,17 +714,21 @@ galeon_shell_new_tab_from_embed_full (Ga
/* Make sure the initial focus is somewhere sensible and not, for
* example, on the reload button.
*/
- if (galeon_tab_is_empty (tab))
+ if (in_new_window || jump_to)
{
- /* empty page, focus location entry */
- galeon_window_edit_location (window);
- }
- else if (in_new_window || jump_to)
- {
- /* non-empty page, focus the page (using bin->child directly as
- * I'm too lazy to implement grab_focus in GaleonTab)
- */
- gtk_widget_grab_focus (GTK_BIN(tab)->child);
+ /* If the location entry is blank, focus that, except if the
+ * page was a copy */
+ if (galeon_tab_is_empty (tab) &&
+ !(flags & GALEON_NEW_TAB_IS_A_COPY))
+ {
+ /* empty page, focus location entry */
+ galeon_window_edit_location (window);
+ }
+ else
+ {
+ /* non-empty page, focus the page */
+ gtk_widget_grab_focus (GTK_WIDGET (embed));
+ }
}
return tab;
--- orig/src/galeon-tab.c
+++ mod/src/galeon-tab.c
@@ -1953,12 +1953,23 @@ galeon_tab_gesture_performed_cb (GulGest
gboolean
galeon_tab_is_empty (GaleonTab *tab)
{
- const char *location;
-
+ char *location;
+ gboolean is_empty = FALSE;
+ GaleonEmbed *embed;
+
g_return_val_if_fail (GALEON_IS_TAB (tab), FALSE);
- location = galeon_tab_get_location (tab);
- return location == NULL ||
- location[0] == '\0' ||
- strcmp (location, "about:blank") == 0;
+ embed = galeon_tab_get_embed (GALEON_TAB (tab));
+ location = galeon_embed_get_location (embed, TRUE, TRUE);
+
+ if (location == NULL ||
+ location[0] == '\0' ||
+ strcmp (location, "about:blank") == 0)
+ {
+ is_empty = TRUE;
+ }
+
+ g_free (location);
+
+ return is_empty;
}
--- orig/src/window-commands.c
+++ mod/src/window-commands.c
@@ -259,11 +259,7 @@ open_new_tab (GaleonWindow *window, Gale
tab = galeon_window_get_active_tab (window);
- tab = galeon_shell_new_tab (galeon_shell, window, tab, NULL, flags);
-
- window = galeon_tab_get_window (tab);
- galeon_window_set_location_entry_location (window, "");
- galeon_window_edit_location (window);
+ galeon_shell_new_tab (galeon_shell, window, tab, NULL, flags);
}
void