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



Reply via email to