gnucash maint: Follow up to previous commit 94cb965

Robert Fewell bobit at code.gnucash.org
Thu Feb 13 06:02:06 EST 2020


Updated	 via  https://github.com/Gnucash/gnucash/commit/f66b7ed2 (commit)
	from  https://github.com/Gnucash/gnucash/commit/58ddb47f (commit)



commit f66b7ed275eba56bd8fee1fee9f9e3457351cacb
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Wed Feb 5 14:41:01 2020 +0000

    Follow up to previous commit 94cb965
    
    This commit moves the setting up of the page changed signal callback to
    when the plugin page is inserted and also records the id used. This is
    used to disconnect this callback when the page is moved to a different
    window and also when the page is destroyed.

diff --git a/gnucash/gnome-utils/gnc-main-window.c b/gnucash/gnome-utils/gnc-main-window.c
index f7e62c3c4..f6ebdc762 100644
--- a/gnucash/gnome-utils/gnc-main-window.c
+++ b/gnucash/gnome-utils/gnc-main-window.c
@@ -2795,6 +2795,9 @@ gnc_main_window_disconnect (GncMainWindow *window,
     g_signal_handlers_disconnect_by_func(G_OBJECT(page->notebook_page),
                                          G_CALLBACK(gnc_main_window_button_press_cb), page);
 
+    // Remove the page_changed signal callback
+    gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(page));
+
     /* Disconnect the page and summarybar from the window */
     priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
     if (priv->current_page == page)
@@ -3712,7 +3715,7 @@ gnc_quartz_shutdown (GtkosxApplication *theApp, gpointer data)
     /* Do Nothing. It's too late. */
 }
 /* Should quit responds to NSApplicationBlockTermination; returning
- * TRUE means "don't terminate", FALSE means "do terminate". 
+ * TRUE means "don't terminate", FALSE means "do terminate".
  */
 static gboolean
 gnc_quartz_should_quit (GtkosxApplication *theApp, GncMainWindow *window)
@@ -4325,6 +4328,9 @@ gnc_main_window_cmd_window_move_page (GtkAction *action, GncMainWindow *window)
     tab_widget = gtk_notebook_get_tab_label (notebook, page->notebook_page);
     menu_widget = gtk_notebook_get_menu_label (notebook, page->notebook_page);
 
+    // Remove the page_changed signal callback
+    gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(page));
+
     /* Ref the page components, then remove it from its old window */
     g_object_ref(page);
     g_object_ref(tab_widget);
diff --git a/gnucash/gnome-utils/gnc-plugin-page.c b/gnucash/gnome-utils/gnc-plugin-page.c
index d757f3a53..0298d59a0 100644
--- a/gnucash/gnome-utils/gnc-plugin-page.c
+++ b/gnucash/gnome-utils/gnc-plugin-page.c
@@ -58,6 +58,9 @@ static void gnc_plugin_page_get_property (GObject         *object,
         GValue          *value,
         GParamSpec      *pspec);
 
+static void gnc_plugin_page_default_focus (GncPluginPage *plugin_page,
+                                           gboolean on_current_page);
+
 enum
 {
     INSERTED,
@@ -102,6 +105,9 @@ typedef struct _GncPluginPagePrivate
     gchar *page_color;
     gchar *uri;
     gchar *statusbar_text;
+
+    gulong page_changed_id;
+
 } GncPluginPagePrivate;
 
 GNC_DEFINE_TYPE_WITH_CODE(GncPluginPage, gnc_plugin_page, G_TYPE_OBJECT,
@@ -371,6 +377,7 @@ gnc_plugin_page_class_init (GncPluginPageClass *klass)
 
     klass->tab_icon    = NULL;
     klass->plugin_name = NULL;
+    klass->focus_page = gnc_plugin_page_default_focus;
 
     g_object_class_install_property
     (gobject_class,
@@ -506,18 +513,19 @@ static void
 gnc_plugin_page_init (GncPluginPage *page, void *data)
 {
     GncPluginPagePrivate *priv;
-    
+
     GncPluginPageClass *klass = (GncPluginPageClass*)data;
 
     priv = GNC_PLUGIN_PAGE_GET_PRIVATE(page);
     priv->page_name   = NULL;
     priv->page_color  = NULL;
     priv->uri         = NULL;
+    priv->page_changed_id = 0;
 
     page->window      = NULL;
     page->summarybar  = NULL;
 
-    gnc_gobject_tracking_remember(G_OBJECT(page), 
+    gnc_gobject_tracking_remember(G_OBJECT(page),
 		                  G_OBJECT_CLASS(klass));
 }
 
@@ -848,6 +856,96 @@ gnc_plugin_page_set_page_color (GncPluginPage *page, const gchar *color)
 }
 
 
+static void
+gnc_plugin_page_default_focus (GncPluginPage *plugin_page,
+                               gboolean on_current_page)
+{
+    GncPluginPagePrivate *priv;
+
+    if (!on_current_page)
+        return;
+
+    g_return_if_fail (GNC_IS_PLUGIN_PAGE(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_GET_PRIVATE(plugin_page);
+
+    if (G_LIKELY(GNC_PLUGIN_PAGE_GET_CLASS(plugin_page)->focus_page_function))
+    {
+        // The page changed signal is emitted multiple times so we need
+        // to use an idle_add to change the focus
+        g_idle_remove_by_data (GNC_PLUGIN_PAGE(plugin_page));
+        g_idle_add ((GSourceFunc)(GNC_PLUGIN_PAGE_GET_CLASS(plugin_page)->focus_page_function),
+                     GNC_PLUGIN_PAGE(plugin_page));
+    }
+}
+
+
+/* this is the callback for the plugin "page_changed" signal */
+static void
+gnc_plugin_page_main_window_changed (GtkWindow *window,
+                                     GObject *object,
+                                     gpointer user_data)
+{
+    GncPluginPage *current_plugin_page = GNC_PLUGIN_PAGE(object);
+    GncPluginPage *plugin_page = GNC_PLUGIN_PAGE(user_data);
+    GncPluginPagePrivate *priv;
+    gboolean on_current_page = FALSE;
+
+    // Continue if current_plugin_page is valid
+    if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE(current_plugin_page))
+        return;
+
+    // Continue only if the plugin_page is valid
+    if (!plugin_page || !GNC_IS_PLUGIN_PAGE(plugin_page))
+        return;
+
+    priv = GNC_PLUGIN_PAGE_GET_PRIVATE(plugin_page);
+
+    if (current_plugin_page == plugin_page)
+        on_current_page = TRUE;
+
+    (GNC_PLUGIN_PAGE_GET_CLASS(plugin_page)->focus_page)(plugin_page, on_current_page);
+}
+
+/* this is the callback for the plugin "inserted" signal which will setup
+ * the callback for the "page_changed" signal and save a pointer to the
+ * page focus function. */
+void
+gnc_plugin_page_inserted_cb (GncPluginPage *page, gpointer user_data)
+{
+    GncPluginPagePrivate *priv;
+
+    g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
+
+    priv = GNC_PLUGIN_PAGE_GET_PRIVATE(page);
+
+    priv->page_changed_id = g_signal_connect (G_OBJECT(page->window), "page_changed",
+                                              G_CALLBACK(gnc_plugin_page_main_window_changed),
+                                              page);
+
+    // on initial load try and set the page focus
+    (GNC_PLUGIN_PAGE_GET_CLASS(page)->focus_page)(page, TRUE);
+}
+
+
+/* disconnect the page_changed callback */
+void
+gnc_plugin_page_disconnect_page_changed (GncPluginPage *page)
+{
+    GncPluginPagePrivate *priv;
+
+    g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
+
+    priv = GNC_PLUGIN_PAGE_GET_PRIVATE(page);
+
+    if (priv->page_changed_id > 0)
+    {
+        g_signal_handler_disconnect (G_OBJECT(page->window), priv->page_changed_id);
+        priv->page_changed_id = 0;
+    }
+}
+
+
 /*  Retrieve the Uniform Resource Identifier for this page. */
 const gchar *
 gnc_plugin_page_get_uri (GncPluginPage *page)
diff --git a/gnucash/gnome-utils/gnc-plugin-page.h b/gnucash/gnome-utils/gnc-plugin-page.h
index fa09f9b24..82416acfe 100644
--- a/gnucash/gnome-utils/gnc-plugin-page.h
+++ b/gnucash/gnome-utils/gnc-plugin-page.h
@@ -156,6 +156,21 @@ typedef struct
      *  @param window The window where the page was added. */
     void (* window_changed) (GncPluginPage *plugin_page, GtkWidget *window);
 
+    /** Perform plugin specific actions to set the focus.
+     *
+     *  @param page The page that was added to a window.
+     *
+     *  @param on_current_pgae Whether this page is the currentone. */
+    void (* focus_page) (GncPluginPage *plugin_page, gboolean on_current_page);
+
+    /** This function performs specific actions to set the focus on a specific
+     *  widget.
+     *
+     *  @param page The page that was added to a window.
+     *
+     *  @param on_current_pgae Whether this page is the currentone. */
+    gboolean (* focus_page_function) (GncPluginPage *plugin_page);
+
     /** This function vector allows page specific actions to occur
      *  when the page name is changed.
      *
@@ -393,12 +408,30 @@ const gchar *gnc_plugin_page_get_page_color (GncPluginPage *page);
  *
  *  @param page The page whose name should be retrieved.
  *
- *  @return The color for this page.  This string is owned by the page and
+ *  @param The color for this page.  This string is owned by the page and
  *  should not be freed by the caller.
  */
 void gnc_plugin_page_set_page_color (GncPluginPage *page, const char *color);
 
 
+/** Set up the page_changed callback for when the current page is changed.
+ *  This will store a pointer to the page focus funtion passed as a parameter
+ *  so that it can be used in setting up the g_idle_add
+ *
+ *  @param page The page the callback is setup for.
+ *
+ *  @param user_data The page focus function
+ */
+void gnc_plugin_page_inserted_cb (GncPluginPage *page, gpointer user_data);
+
+
+/** Disconnect the page_changed_id signal callback.
+ *
+ *  @param page The page whose name should be retrieved.
+ */
+void gnc_plugin_page_disconnect_page_changed (GncPluginPage *page);
+
+
 /** Retrieve the Uniform Resource Identifier for this page.
  *
  *  @param page The page whose URI should be retrieved.
diff --git a/gnucash/gnome/gnc-plugin-page-account-tree.c b/gnucash/gnome/gnc-plugin-page-account-tree.c
index 1f70ad94a..c1d3396bd 100644
--- a/gnucash/gnome/gnc-plugin-page-account-tree.c
+++ b/gnucash/gnome/gnc-plugin-page-account-tree.c
@@ -114,6 +114,7 @@ static void gnc_plugin_page_account_tree_init (GncPluginPageAccountTree *plugin_
 static void gnc_plugin_page_account_tree_finalize (GObject *object);
 static void gnc_plugin_page_account_tree_selected (GObject *object, gpointer user_data);
 
+static gboolean gnc_plugin_page_account_tree_focus_widget (GncPluginPage *plugin_page);
 static GtkWidget *gnc_plugin_page_account_tree_create_widget (GncPluginPage *plugin_page);
 static void gnc_plugin_page_account_tree_destroy_widget (GncPluginPage *plugin_page);
 static void gnc_plugin_page_account_tree_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
@@ -405,6 +406,7 @@ gnc_plugin_page_account_tree_class_init (GncPluginPageAccountTreeClass *klass)
     gnc_plugin_class->destroy_widget  = gnc_plugin_page_account_tree_destroy_widget;
     gnc_plugin_class->save_page       = gnc_plugin_page_account_tree_save_page;
     gnc_plugin_class->recreate_page   = gnc_plugin_page_account_tree_recreate_page;
+    gnc_plugin_class->focus_page_function = gnc_plugin_page_account_tree_focus_widget;
 
     plugin_page_signals[ACCOUNT_SELECTED] =
         g_signal_new ("account_selected",
@@ -573,12 +575,16 @@ gnc_plugin_page_account_tree_get_current_account (GncPluginPageAccountTree *page
     return account;
 }
 
-gboolean
-gnc_plugin_page_account_tree_focus (GncPluginPageAccountTree *page)
+/**
+ * Whenever the current page is changed, if an account page is
+ * the current page, set focus on the tree view.
+ */
+static gboolean
+gnc_plugin_page_account_tree_focus_widget (GncPluginPage *account_plugin_page)
 {
-    if (GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE(page))
+    if (GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE(account_plugin_page))
     {
-        GncPluginPageAccountTreePrivate *priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(page);
+        GncPluginPageAccountTreePrivate *priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(account_plugin_page);
         GtkTreeView *view = GTK_TREE_VIEW(priv->tree_view);
 
         if (!gtk_widget_is_focus (GTK_WIDGET(view)))
@@ -636,32 +642,11 @@ gnc_plugin_page_account_editing_finished_cb (gpointer various, GncPluginPageRegi
         gtk_action_set_sensitive (action, TRUE);
 }
 
-static void
-gnc_plugin_account_tree_main_window_page_changed (GncMainWindow *window,
-                                                  GncPluginPage *current_plugin_page,
-                                                  GncPluginPage *account_plugin_page)
-{
-    // We continue only if the plugin_page is a valid
-    if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE(current_plugin_page)||
-        !account_plugin_page || !GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE(account_plugin_page))
-        return;
-
-    if (current_plugin_page == account_plugin_page)
-    {
-        // The page changed signal is emitted multiple times so we need
-        // to use an idle_add to change the focus to the tree view
-        g_idle_remove_by_data (GNC_PLUGIN_PAGE_ACCOUNT_TREE (account_plugin_page));
-        g_idle_add ((GSourceFunc)gnc_plugin_page_account_tree_focus,
-                      GNC_PLUGIN_PAGE_ACCOUNT_TREE (account_plugin_page));
-    }
-}
-
 static GtkWidget *
 gnc_plugin_page_account_tree_create_widget (GncPluginPage *plugin_page)
 {
     GncPluginPageAccountTree *page;
     GncPluginPageAccountTreePrivate *priv;
-    GncMainWindow *window;
     GtkTreeSelection *selection;
     GtkTreeView *tree_view;
     GtkWidget *scrolled_window;
@@ -759,10 +744,9 @@ gnc_plugin_page_account_tree_create_widget (GncPluginPage *plugin_page)
                            gnc_plugin_page_account_tree_summarybar_position_changed,
                            page);
 
-    window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(page)->window);
-    g_signal_connect (window, "page_changed",
-                      G_CALLBACK(gnc_plugin_account_tree_main_window_page_changed),
-                      plugin_page);
+    g_signal_connect (G_OBJECT(plugin_page), "inserted",
+                      G_CALLBACK(gnc_plugin_page_inserted_cb),
+                      NULL);
 
     // Read account filter state information from account section
     gnc_tree_view_account_restore_filter (GNC_TREE_VIEW_ACCOUNT(priv->tree_view), &priv->fd,
@@ -798,8 +782,11 @@ gnc_plugin_page_account_tree_destroy_widget (GncPluginPage *plugin_page)
     // Destroy the filter override hash table
     g_hash_table_destroy(priv->fd.filter_override);
 
+    // Remove the page_changed signal callback
+    gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
+
     // Remove the page focus idle function if present
-    g_idle_remove_by_data (GNC_PLUGIN_PAGE_ACCOUNT_TREE (plugin_page));
+    g_idle_remove_by_data (plugin_page);
 
     if (priv->widget)
     {
diff --git a/gnucash/gnome/gnc-plugin-page-account-tree.h b/gnucash/gnome/gnc-plugin-page-account-tree.h
index 2dad1e7e4..57b862987 100644
--- a/gnucash/gnome/gnc-plugin-page-account-tree.h
+++ b/gnucash/gnome/gnc-plugin-page-account-tree.h
@@ -95,15 +95,6 @@ GncPluginPage *gnc_plugin_page_account_tree_new  (void);
 Account * gnc_plugin_page_account_tree_get_current_account (GncPluginPageAccountTree *page);
 
 
-/** Given a pointer to an account tree plugin page, set the focus to
- *  the GtkTreeView. This is used in a g_idle_add so return FALSE.
- *
- *  @param page The "account tree" page.
- * 
- *  @return FALSE;
- */
-gboolean gnc_plugin_page_account_tree_focus (GncPluginPageAccountTree *page);
-
 /** Given a pointer to an account, the account tree will open
  *  and the account will be selected (if any).
  *
diff --git a/gnucash/gnome/gnc-plugin-page-budget.c b/gnucash/gnome/gnc-plugin-page-budget.c
index 3449f289d..cd845c23e 100644
--- a/gnucash/gnome/gnc-plugin-page-budget.c
+++ b/gnucash/gnome/gnc-plugin-page-budget.c
@@ -58,6 +58,7 @@
 #include "gnc-tree-view-account.h"
 #include "gnc-ui.h"
 #include "gnc-ui-util.h"
+#include "gnc-window.h"
 #include "option-util.h"
 #include "gnc-main-window.h"
 #include "gnc-component-manager.h"
@@ -85,6 +86,7 @@ static void gnc_plugin_page_budget_finalize (GObject *object);
 
 static GtkWidget *
 gnc_plugin_page_budget_create_widget (GncPluginPage *plugin_page);
+static gboolean gnc_plugin_page_budget_focus_widget (GncPluginPage *plugin_page);
 static void gnc_plugin_page_budget_destroy_widget (GncPluginPage *plugin_page);
 static void gnc_plugin_page_budget_save_page (GncPluginPage *plugin_page,
                                               GKeyFile *file,
@@ -299,6 +301,7 @@ gnc_plugin_page_budget_class_init (GncPluginPageBudgetClass *klass)
     gnc_plugin_class->destroy_widget  = gnc_plugin_page_budget_destroy_widget;
     gnc_plugin_class->save_page       = gnc_plugin_page_budget_save_page;
     gnc_plugin_class->recreate_page   = gnc_plugin_page_budget_recreate_page;
+    gnc_plugin_class->focus_page_function = gnc_plugin_page_budget_focus_widget;
 }
 
 
@@ -372,12 +375,16 @@ gnc_plugin_page_budget_close_cb (gpointer user_data)
 }
 
 
-gboolean
-gnc_plugin_page_budget_focus (GncPluginPageBudget *page)
+/**
+ * Whenever the current page is changed, if a budget page is
+ * the current page, set focus on the budget tree view.
+ */
+static gboolean
+gnc_plugin_page_budget_focus_widget (GncPluginPage *budget_plugin_page)
 {
-    if (GNC_IS_PLUGIN_PAGE_BUDGET(page))
+    if (GNC_IS_PLUGIN_PAGE_BUDGET(budget_plugin_page))
     {
-        GncPluginPageBudgetPrivate *priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
+        GncPluginPageBudgetPrivate *priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(budget_plugin_page);
         GncBudgetView *budget_view = priv->budget_view;
         GtkWidget *account_view = gnc_budget_view_get_account_tree_view (budget_view);
 
@@ -423,27 +430,6 @@ gnc_plugin_page_budget_refresh_cb (GHashTable *changes, gpointer user_data)
 }
 
 
-static void
-gnc_plugin_budget_main_window_page_changed (GncMainWindow *window,
-                                            GncPluginPage *current_plugin_page,
-                                            GncPluginPage *budget_plugin_page)
-{
-    // We continue only if the plugin_page is a valid
-    if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_BUDGET(current_plugin_page) ||
-        !budget_plugin_page || !GNC_IS_PLUGIN_PAGE_BUDGET(budget_plugin_page))
-        return;
-
-    if (current_plugin_page == budget_plugin_page)
-    {
-        // The page changed signal is emitted multiple times so we need
-        // to use an idle_add to change the focus to the tree view
-        g_idle_remove_by_data (GNC_PLUGIN_PAGE_BUDGET(budget_plugin_page));
-        g_idle_add ((GSourceFunc)gnc_plugin_page_budget_focus,
-                      GNC_PLUGIN_PAGE_BUDGET(budget_plugin_page));
-    }
-}
-
-
 /****************************
  * GncPluginPage Functions  *
  ***************************/
@@ -452,7 +438,6 @@ gnc_plugin_page_budget_create_widget (GncPluginPage *plugin_page)
 {
     GncPluginPageBudget *page;
     GncPluginPageBudgetPrivate *priv;
-    GncMainWindow *window;
 
     ENTER("page %p", plugin_page);
     page = GNC_PLUGIN_PAGE_BUDGET(plugin_page);
@@ -487,10 +472,9 @@ gnc_plugin_page_budget_create_widget (GncPluginPage *plugin_page)
                                     gnc_budget_get_guid (priv->budget),
                                     QOF_EVENT_DESTROY | QOF_EVENT_MODIFY);
 
-    window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(page)->window);
-    g_signal_connect (window, "page_changed",
-                      G_CALLBACK(gnc_plugin_budget_main_window_page_changed),
-                      plugin_page);
+    g_signal_connect (G_OBJECT(plugin_page), "inserted",
+                      G_CALLBACK(gnc_plugin_page_inserted_cb),
+                      NULL);
 
     LEAVE("widget = %p", priv->budget_view);
     return GTK_WIDGET(priv->budget_view);
@@ -505,8 +489,11 @@ gnc_plugin_page_budget_destroy_widget (GncPluginPage *plugin_page)
     ENTER("page %p", plugin_page);
     priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(plugin_page);
 
+    // Remove the page_changed signal callback
+    gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
+
     // Remove the page focus idle function if present
-    g_idle_remove_by_data (GNC_PLUGIN_PAGE_BUDGET(plugin_page));
+    g_idle_remove_by_data (plugin_page);
 
     if (priv->budget_view)
     {
diff --git a/gnucash/gnome/gnc-plugin-page-budget.h b/gnucash/gnome/gnc-plugin-page-budget.h
index 9efe5203b..ffec5883f 100644
--- a/gnucash/gnome/gnc-plugin-page-budget.h
+++ b/gnucash/gnome/gnc-plugin-page-budget.h
@@ -70,16 +70,6 @@ GncPluginPage *gnc_plugin_page_budget_new (GncBudget *budget);
 
 void gnc_budget_gui_delete_budget (GncBudget *budget);
 
-/** Given a pointer to a budget plugin page, set the focus to
- *  the Account GtkTreeView. This is used in a g_idle_add so
- *  return FALSE.
- *
- *  @param page The "budget" page.
- *
- *  @return FALSE
- */
-gboolean gnc_plugin_page_budget_focus (GncPluginPageBudget *page);
-
 G_END_DECLS
 
 #endif /* __GNC_PLUGIN_PAGE_BUDGET_H */
diff --git a/gnucash/gnome/gnc-plugin-page-invoice.c b/gnucash/gnome/gnc-plugin-page-invoice.c
index f4fa4c4a7..c0143f370 100644
--- a/gnucash/gnome/gnc-plugin-page-invoice.c
+++ b/gnucash/gnome/gnc-plugin-page-invoice.c
@@ -52,6 +52,7 @@ static void gnc_plugin_page_invoice_init (GncPluginPageInvoice *plugin_page);
 static void gnc_plugin_page_invoice_finalize (GObject *object);
 
 static GtkWidget *gnc_plugin_page_invoice_create_widget (GncPluginPage *plugin_page);
+static gboolean gnc_plugin_page_invoice_focus_widget (GncPluginPage *plugin_page);
 static void gnc_plugin_page_invoice_destroy_widget (GncPluginPage *plugin_page);
 static void gnc_plugin_page_invoice_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
 static GncPluginPage *gnc_plugin_page_invoice_recreate_page (GtkWidget *window, GKeyFile *file, const gchar *group);
@@ -448,6 +449,7 @@ gnc_plugin_page_invoice_class_init (GncPluginPageInvoiceClass *klass)
     gnc_plugin_class->save_page       = gnc_plugin_page_invoice_save_page;
     gnc_plugin_class->recreate_page   = gnc_plugin_page_invoice_recreate_page;
     gnc_plugin_class->window_changed  = gnc_plugin_page_invoice_window_changed;
+    gnc_plugin_class->focus_page_function = gnc_plugin_page_invoice_focus_widget;
 }
 
 static void
@@ -572,56 +574,39 @@ gnc_plugin_page_invoice_update_menus (GncPluginPage *page, gboolean is_posted, g
 }
 
 
-static gboolean
-gnc_plugin_page_invoice_focus (InvoiceWindow *iw)
-{
-    GtkWidget *regWidget = gnc_invoice_get_register(iw);
-    GtkWidget *notes = gnc_invoice_get_notes(iw);
-    GnucashSheet *sheet;
-
-    if (!GNUCASH_IS_REGISTER(regWidget))
-        return FALSE;
-
-    sheet = gnucash_register_get_sheet (GNUCASH_REGISTER(regWidget));
-
-    // Test for the sheet being read only
-    if (!gnucash_sheet_is_read_only (sheet))
-    {
-        if (!gtk_widget_is_focus (GTK_WIDGET(sheet)))
-            gtk_widget_grab_focus (GTK_WIDGET(sheet));
-    }
-    else // set focus to the notes field
-    {
-        if (!gtk_widget_is_focus (GTK_WIDGET(notes)))
-            gtk_widget_grab_focus (GTK_WIDGET(notes));
-    }
-    return FALSE;
-}
-
-
 /**
  * Whenever the current page is changed, if an invoice page is
  * the current page, set focus on the sheet or notes field.
  */
-static void
-gnc_plugin_page_invoice_main_window_page_changed (GncMainWindow *window,
-                                                  GncPluginPage *current_plugin_page,
-                                                  GncPluginPage *invoice_plugin_page)
+static gboolean
+gnc_plugin_page_invoice_focus_widget (GncPluginPage *invoice_plugin_page)
 {
-    // We continue only if the plugin_page is a valid
-    if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_INVOICE(current_plugin_page) ||
-        !invoice_plugin_page || !GNC_IS_PLUGIN_PAGE_INVOICE(invoice_plugin_page))
-        return;
-
-    if (current_plugin_page == invoice_plugin_page)
+    if (GNC_IS_PLUGIN_PAGE_INVOICE(invoice_plugin_page))
     {
         GncPluginPageInvoicePrivate *priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(invoice_plugin_page);
 
-        // The page changed signal is emitted multiple times so we need
-        // to use an idle_add to change the focus to the sheet
-        g_idle_remove_by_data (priv->iw);
-        g_idle_add ((GSourceFunc)gnc_plugin_page_invoice_focus, priv->iw);
+        GtkWidget *regWidget = gnc_invoice_get_register(priv->iw);
+        GtkWidget *notes = gnc_invoice_get_notes(priv->iw);
+        GnucashSheet *sheet;
+
+        if (!GNUCASH_IS_REGISTER(regWidget))
+            return FALSE;
+
+        sheet = gnucash_register_get_sheet (GNUCASH_REGISTER(regWidget));
+
+        // Test for the sheet being read only
+        if (!gnucash_sheet_is_read_only (sheet))
+        {
+            if (!gtk_widget_is_focus (GTK_WIDGET(sheet)))
+                gtk_widget_grab_focus (GTK_WIDGET(sheet));
+        }
+        else // set focus to the notes field
+        {
+            if (!gtk_widget_is_focus (GTK_WIDGET(notes)))
+                gtk_widget_grab_focus (GTK_WIDGET(notes));
+        }
     }
+    return FALSE;
 }
 
 
@@ -633,7 +618,6 @@ gnc_plugin_page_invoice_create_widget (GncPluginPage *plugin_page)
     GncPluginPageInvoice *page;
     GncPluginPageInvoicePrivate *priv;
     GtkWidget *regWidget, *widget;
-    GncMainWindow  *window;
 
     ENTER("page %p", plugin_page);
     page = GNC_PLUGIN_PAGE_INVOICE (plugin_page);
@@ -680,10 +664,9 @@ gnc_plugin_page_invoice_create_widget (GncPluginPage *plugin_page)
                                    gnc_plugin_page_invoice_refresh_cb,
                                    NULL, page);
 
-    window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
-    g_signal_connect(window, "page_changed",
-                     G_CALLBACK(gnc_plugin_page_invoice_main_window_page_changed),
-                     plugin_page);
+    g_signal_connect (G_OBJECT(plugin_page), "inserted",
+                      G_CALLBACK(gnc_plugin_page_inserted_cb),
+                      NULL);
 
     LEAVE("");
     return priv->widget;
@@ -708,8 +691,11 @@ gnc_plugin_page_invoice_destroy_widget (GncPluginPage *plugin_page)
                                  gnc_plugin_page_invoice_summarybar_position_changed,
                                  page);
 
+    // Remove the page_changed signal callback
+    gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
+
     // Remove the page focus idle function if present
-    g_idle_remove_by_data (priv->iw);
+    g_idle_remove_by_data (plugin_page);
 
     if (priv->widget == NULL)
     {
diff --git a/gnucash/gnome/gnc-plugin-page-owner-tree.c b/gnucash/gnome/gnc-plugin-page-owner-tree.c
index 1b54a06f6..83c87186b 100644
--- a/gnucash/gnome/gnc-plugin-page-owner-tree.c
+++ b/gnucash/gnome/gnc-plugin-page-owner-tree.c
@@ -58,6 +58,7 @@
 #include "gnc-tree-view-owner.h"
 #include "gnc-ui.h"
 #include "gnc-ui-util.h"
+#include "gnc-window.h"
 #include "guile-mappings.h"
 #include "dialog-lot-viewer.h"
 #include "dialog-object-references.h"
@@ -365,43 +366,25 @@ gnc_plugin_page_owner_tree_new (GncOwnerType owner_type)
     return GNC_PLUGIN_PAGE(plugin_page);
 }
 
-
-static gboolean
-gnc_plugin_page_owner_focus (GtkTreeView *tree_view)
-{
-    if (GTK_IS_TREE_VIEW(tree_view))
-    {
-        if (!gtk_widget_is_focus (GTK_WIDGET(tree_view)))
-            gtk_widget_grab_focus (GTK_WIDGET(tree_view));
-    }
-    return FALSE;
-}
-
-
 /**
  * Whenever the current page is changed, if an owner page is
- * the current page, set focus on the treeview.
+ * the current page, set focus on the tree view.
  */
-static void
-gnc_plugin_page_owner_main_window_page_changed (GncMainWindow *window,
-                                                GncPluginPage *current_plugin_page,
-                                                GncPluginPage *owner_plugin_page)
+static gboolean
+gnc_plugin_page_owner_focus_widget (GncPluginPage *owner_plugin_page)
 {
-    // We continue only if the plugin_page is a valid
-    if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_OWNER_TREE(current_plugin_page) ||
-        !owner_plugin_page || !GNC_IS_PLUGIN_PAGE_OWNER_TREE(owner_plugin_page))
-        return;
-
-    if (current_plugin_page == owner_plugin_page)
+    if (GNC_IS_PLUGIN_PAGE_OWNER_TREE(owner_plugin_page))
     {
         GncPluginPageOwnerTreePrivate *priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(owner_plugin_page);
+        GtkTreeView *tree_view = priv->tree_view;
 
-        // The page changed signal is emitted multiple times so we need
-        // to use an idle_add to change the focus to the tree view
-        g_idle_remove_by_data (GTK_TREE_VIEW (priv->tree_view));
-        g_idle_add ((GSourceFunc)gnc_plugin_page_owner_focus,
-                      GTK_TREE_VIEW (priv->tree_view));
+        if (GTK_IS_TREE_VIEW(tree_view))
+        {
+            if (!gtk_widget_is_focus (GTK_WIDGET(tree_view)))
+                gtk_widget_grab_focus (GTK_WIDGET(tree_view));
+        }
     }
+    return FALSE;
 }
 
 G_DEFINE_TYPE_WITH_PRIVATE(GncPluginPageOwnerTree, gnc_plugin_page_owner_tree, GNC_TYPE_PLUGIN_PAGE)
@@ -422,6 +405,7 @@ gnc_plugin_page_owner_tree_class_init (GncPluginPageOwnerTreeClass *klass)
     gnc_plugin_class->destroy_widget  = gnc_plugin_page_owner_tree_destroy_widget;
     gnc_plugin_class->save_page       = gnc_plugin_page_owner_tree_save_page;
     gnc_plugin_class->recreate_page   = gnc_plugin_page_owner_tree_recreate_page;
+    gnc_plugin_class->focus_page_function = gnc_plugin_page_owner_focus_widget;
 
     plugin_page_signals[OWNER_SELECTED] =
         g_signal_new ("owner_selected",
@@ -571,7 +555,6 @@ gnc_plugin_page_owner_tree_create_widget (GncPluginPage *plugin_page)
 {
     GncPluginPageOwnerTree *page;
     GncPluginPageOwnerTreePrivate *priv;
-    GncMainWindow  *window;
     GtkTreeSelection *selection;
     GtkTreeView *tree_view;
     GtkWidget *scrolled_window;
@@ -686,10 +669,9 @@ gnc_plugin_page_owner_tree_create_widget (GncPluginPage *plugin_page)
     gnc_gui_component_set_session (priv->component_id,
                                    gnc_get_current_session());
 
-    window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
-    g_signal_connect(window, "page_changed",
-                     G_CALLBACK(gnc_plugin_page_owner_main_window_page_changed),
-                     plugin_page);
+    g_signal_connect (G_OBJECT(plugin_page), "inserted",
+                      G_CALLBACK(gnc_plugin_page_inserted_cb),
+                      NULL);
 
     LEAVE("widget = %p", priv->widget);
     return priv->widget;
@@ -705,8 +687,11 @@ gnc_plugin_page_owner_tree_destroy_widget (GncPluginPage *plugin_page)
     page = GNC_PLUGIN_PAGE_OWNER_TREE (plugin_page);
     priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
 
+    // Remove the page_changed signal callback
+    gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
+
     // Remove the page focus idle function if present
-    g_idle_remove_by_data (GTK_TREE_VIEW (priv->tree_view));
+    g_idle_remove_by_data (plugin_page);
 
     if (priv->widget)
     {
diff --git a/gnucash/gnome/gnc-plugin-page-register.c b/gnucash/gnome/gnc-plugin-page-register.c
index 1d1958698..0c311aea4 100644
--- a/gnucash/gnome/gnc-plugin-page-register.c
+++ b/gnucash/gnome/gnc-plugin-page-register.c
@@ -102,6 +102,8 @@ static void gnc_plugin_page_register_finalize (GObject *object);
 static GtkWidget *gnc_plugin_page_register_create_widget (GncPluginPage *plugin_page);
 static void gnc_plugin_page_register_destroy_widget (GncPluginPage *plugin_page);
 static void gnc_plugin_page_register_window_changed (GncPluginPage *plugin_page, GtkWidget *window);
+static gboolean gnc_plugin_page_register_focus_widget (GncPluginPage *plugin_page);
+static void gnc_plugin_page_register_focus (GncPluginPage *plugin_page, gboolean current_page);
 static void gnc_plugin_page_register_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
 static GncPluginPage *gnc_plugin_page_register_recreate_page (GtkWidget *window, GKeyFile *file, const gchar *group);
 static void gnc_plugin_page_register_update_edit_menu (GncPluginPage *page, gboolean hide);
@@ -750,10 +752,12 @@ gnc_plugin_page_register_class_init (GncPluginPageRegisterClass *klass)
     gnc_plugin_class->create_widget   = gnc_plugin_page_register_create_widget;
     gnc_plugin_class->destroy_widget  = gnc_plugin_page_register_destroy_widget;
     gnc_plugin_class->window_changed  = gnc_plugin_page_register_window_changed;
+    gnc_plugin_class->focus_page      = gnc_plugin_page_register_focus;
     gnc_plugin_class->save_page       = gnc_plugin_page_register_save_page;
     gnc_plugin_class->recreate_page   = gnc_plugin_page_register_recreate_page;
     gnc_plugin_class->update_edit_menu_actions = gnc_plugin_page_register_update_edit_menu;
     gnc_plugin_class->finish_pending  = gnc_plugin_page_register_finish_pending;
+    gnc_plugin_class->focus_page_function = gnc_plugin_page_register_focus_widget;
 
     gnc_ui_register_account_destroy_callback (gppr_account_destroy_cb);
 }
@@ -843,12 +847,16 @@ gnc_plugin_page_register_get_current_txn (GncPluginPageRegister *page)
     return gnc_split_register_get_current_trans(reg);
 }
 
-gboolean
-gnc_plugin_page_register_focus (GncPluginPageRegister *page)
+/**
+ * Whenever the current page is changed, if a register page is
+ * the current page, set focus on the sheet.
+ */
+static gboolean
+gnc_plugin_page_register_focus_widget (GncPluginPage *register_plugin_page)
 {
-    if (GNC_IS_PLUGIN_PAGE_REGISTER(page))
+    if (GNC_IS_PLUGIN_PAGE_REGISTER(register_plugin_page))
     {
-        GNCSplitReg *gsr = gnc_plugin_page_register_get_gsr(GNC_PLUGIN_PAGE(page));
+        GNCSplitReg *gsr = gnc_plugin_page_register_get_gsr(GNC_PLUGIN_PAGE(register_plugin_page));
         gnc_split_reg_focus_on_sheet (gsr);
     }
     return FALSE;
@@ -1145,31 +1153,33 @@ get_filter_default_num_of_days (GNCLedgerDisplayType ledger_type)
         return "0";
 }
 
+/* For setting the focus on a register page, the default gnc_plugin
+ * function for 'focus_page' is overridden so that the page focus
+ * can be condionally set. This is to allow for enabling the setting
+ * of the sheet focus only when the page is the current one.
+ */
 static void
-gnc_plugin_register_main_window_page_changed (GncMainWindow *window,
-                                              GncPluginPage *current_plugin_page,
-                                              GncPluginPage *register_plugin_page)
+gnc_plugin_page_register_focus (GncPluginPage *plugin_page,
+                                gboolean on_current_page)
 {
+    GncPluginPageRegister *page;
     GncPluginPageRegisterPrivate *priv;
     GNCSplitReg *gsr;
 
-    // We continue only if the plugin_page is a valid
-    if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_REGISTER(current_plugin_page) ||
-        !register_plugin_page || !GNC_IS_PLUGIN_PAGE_REGISTER(register_plugin_page))
-        return;
+    g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER (plugin_page));
 
-    priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(register_plugin_page);
-    gsr = gnc_plugin_page_register_get_gsr (GNC_PLUGIN_PAGE(register_plugin_page));
+    page = GNC_PLUGIN_PAGE_REGISTER(plugin_page);
+    priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
+
+    gsr = gnc_plugin_page_register_get_gsr (GNC_PLUGIN_PAGE(plugin_page));
 
-    if (current_plugin_page == register_plugin_page)
+    if (on_current_page)
     {
         priv->page_focus = TRUE;
 
-        // The page changed signal is emitted multiple times so we need
-        // to use an idle_add to change the focus to the register
-        g_idle_remove_by_data (GNC_PLUGIN_PAGE_REGISTER (register_plugin_page));
-        g_idle_add ((GSourceFunc)gnc_plugin_page_register_focus,
-                      GNC_PLUGIN_PAGE_REGISTER (register_plugin_page));
+       // Chain up to use parent version of 'focus_page' which will
+       // use an idle_add as the page changed signal is emitted multiple times.
+       GNC_PLUGIN_PAGE_CLASS(parent_class)->focus_page (plugin_page, TRUE);
     }
     else
         priv->page_focus = FALSE;
@@ -1183,7 +1193,6 @@ gnc_plugin_page_register_create_widget (GncPluginPage *plugin_page)
 {
     GncPluginPageRegister *page;
     GncPluginPageRegisterPrivate *priv;
-    GncMainWindow *window;
     GNCLedgerDisplayType ledger_type;
     GncWindow *gnc_window;
     guint numRows;
@@ -1398,10 +1407,9 @@ gnc_plugin_page_register_create_widget (GncPluginPage *plugin_page)
     gnc_split_reg_set_moved_cb
     (priv->gsr, (GFunc)gnc_plugin_page_register_ui_update, page);
 
-    window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
-    g_signal_connect (window, "page_changed",
-                      G_CALLBACK(gnc_plugin_register_main_window_page_changed),
-                      plugin_page);
+    g_signal_connect (G_OBJECT(plugin_page), "inserted",
+                      G_CALLBACK(gnc_plugin_page_inserted_cb),
+                      NULL);
 
     /* DRH - Probably lots of other stuff from regWindowLedger should end up here. */
     LEAVE(" ");
@@ -1427,6 +1435,9 @@ gnc_plugin_page_register_destroy_widget (GncPluginPage *plugin_page)
                                  gnc_plugin_page_register_summarybar_position_changed,
                                  page);
 
+    // Remove the page_changed signal callback
+    gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
+
     // Remove the page focus idle function if present
     g_idle_remove_by_data (GNC_PLUGIN_PAGE_REGISTER (plugin_page));
 
@@ -1468,7 +1479,7 @@ gnc_plugin_page_register_destroy_widget (GncPluginPage *plugin_page)
 
 static void
 gnc_plugin_page_register_window_changed (GncPluginPage *plugin_page,
-        GtkWidget *window)
+                                         GtkWidget *window)
 {
     GncPluginPageRegister *page;
     GncPluginPageRegisterPrivate *priv;
diff --git a/gnucash/gnome/gnc-plugin-page-register.h b/gnucash/gnome/gnc-plugin-page-register.h
index 604836f40..43b2b2e2f 100644
--- a/gnucash/gnome/gnc-plugin-page-register.h
+++ b/gnucash/gnome/gnc-plugin-page-register.h
@@ -163,16 +163,6 @@ gnc_plugin_page_register_get_account (GncPluginPageRegister *page);
 Transaction *
 gnc_plugin_page_register_get_current_txn (GncPluginPageRegister *page);
 
-/** Given a pointer to a register plugin page, set the focus to
- *  the sheet. This is used in a g_idle_add so return FALSE.
- *
- *  @param page The "register" page.
- *
- *  @return FALSE
- */
-gboolean
-gnc_plugin_page_register_focus (GncPluginPageRegister *page);
-
 G_END_DECLS
 /** @} */
 /** @} */
diff --git a/gnucash/gnome/gnc-plugin-page-sx-list.c b/gnucash/gnome/gnc-plugin-page-sx-list.c
index 2f6ab431f..7fa88a38f 100644
--- a/gnucash/gnome/gnc-plugin-page-sx-list.c
+++ b/gnucash/gnome/gnc-plugin-page-sx-list.c
@@ -73,6 +73,7 @@
 #include "gnc-tree-view-sx-list.h"
 #include "gnc-ui-util.h"
 #include "gnc-ui.h"
+#include "gnc-window.h"
 
 #undef G_LOG_DOMAIN
 #define G_LOG_DOMAIN "gnc.gui.plugin-page.sx-list"
@@ -187,42 +188,25 @@ gnc_plugin_page_sx_list_new (void)
 }
 
 
-static gboolean
-gnc_plugin_page_sx_list_focus (GtkTreeView *tree_view)
-{
-    if (GTK_IS_TREE_VIEW(tree_view))
-    {
-        if (!gtk_widget_is_focus (GTK_WIDGET(tree_view)))
-            gtk_widget_grab_focus (GTK_WIDGET(tree_view));
-    }
-    return FALSE;
-}
-
-
 /**
- * Whenever the current page is changed, if a schedule editor page is
- * the current page, set focus on the treeview.
+ * Whenever the current page is changed, if a sx page is
+ * the current page, set focus on the tree view.
  */
-static void
-gnc_plugin_page_sx_list_main_window_page_changed (GncMainWindow *window,
-                                                  GncPluginPage *current_plugin_page,
-                                                  GncPluginPage *sx_plugin_page)
+static gboolean
+gnc_plugin_page_sx_list_focus_widget (GncPluginPage *sx_plugin_page)
 {
-    // We continue only if the plugin_page is a valid
-    if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_SX_LIST(current_plugin_page) ||
-        !sx_plugin_page || !GNC_IS_PLUGIN_PAGE_SX_LIST(sx_plugin_page))
-        return;
-
-    if (current_plugin_page == sx_plugin_page)
+    if (GNC_IS_PLUGIN_PAGE_SX_LIST(sx_plugin_page))
     {
         GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(sx_plugin_page);
+        GtkTreeView *tree_view = priv->tree_view;
 
-        // The page changed signal is emitted multiple times so we need
-        // to use an idle_add to change the focus to the tree view
-        g_idle_remove_by_data (GTK_TREE_VIEW (priv->tree_view));
-        g_idle_add ((GSourceFunc)gnc_plugin_page_sx_list_focus,
-                      GTK_TREE_VIEW (priv->tree_view));
+        if (GTK_IS_TREE_VIEW(tree_view))
+        {
+            if (!gtk_widget_is_focus (GTK_WIDGET(tree_view)))
+                gtk_widget_grab_focus (GTK_WIDGET(tree_view));
+        }
     }
+    return FALSE;
 }
 
 G_DEFINE_TYPE_WITH_PRIVATE(GncPluginPageSxList, gnc_plugin_page_sx_list, GNC_TYPE_PLUGIN_PAGE)
@@ -244,6 +228,7 @@ gnc_plugin_page_sx_list_class_init (GncPluginPageSxListClass *klass)
     gnc_plugin_class->destroy_widget  = gnc_plugin_page_sx_list_destroy_widget;
     gnc_plugin_class->save_page       = gnc_plugin_page_sx_list_save_page;
     gnc_plugin_class->recreate_page   = gnc_plugin_page_sx_list_recreate_page;
+    gnc_plugin_class->focus_page_function = gnc_plugin_page_sx_list_focus_widget;
 }
 
 
@@ -371,7 +356,6 @@ gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page)
 {
     GncPluginPageSxList *page;
     GncPluginPageSxListPrivate *priv;
-    GncMainWindow  *window;
     GtkWidget *widget;
     GtkWidget *vbox;
     GtkWidget *label;
@@ -498,10 +482,9 @@ gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page)
     gnc_gui_component_set_session (priv->gnc_component_id,
                                    gnc_get_current_session());
 
-    window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
-    g_signal_connect(window, "page_changed",
-                     G_CALLBACK(gnc_plugin_page_sx_list_main_window_page_changed),
-                     plugin_page);
+    g_signal_connect (G_OBJECT(plugin_page), "inserted",
+                      G_CALLBACK(gnc_plugin_page_inserted_cb),
+                      NULL);
 
     return priv->widget;
 }
@@ -516,8 +499,11 @@ gnc_plugin_page_sx_list_destroy_widget (GncPluginPage *plugin_page)
     page = GNC_PLUGIN_PAGE_SX_LIST (plugin_page);
     priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
 
+    // Remove the page_changed signal callback
+    gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
+
     // Remove the page focus idle function if present
-    g_idle_remove_by_data (GTK_TREE_VIEW (priv->tree_view));
+    g_idle_remove_by_data (plugin_page);
 
     if (priv->widget)
     {
diff --git a/gnucash/report/report-gnome/gnc-plugin-page-report.c b/gnucash/report/report-gnome/gnc-plugin-page-report.c
index 19272f77e..a46d968d4 100644
--- a/gnucash/report/report-gnome/gnc-plugin-page-report.c
+++ b/gnucash/report/report-gnome/gnc-plugin-page-report.c
@@ -233,41 +233,25 @@ gnc_plugin_page_report_set_property( GObject *obj,
 
 }
 
-static gboolean
-gnc_plugin_page_report_focus (GtkWidget *widget)
-{
-    if (GTK_IS_WIDGET(widget))
-    {
-        if (!gtk_widget_is_focus (GTK_WIDGET(widget)))
-            gtk_widget_grab_focus (GTK_WIDGET(widget));
-    }
-    return FALSE;
-}
-
 /**
  * Whenever the current page is changed, if a report page is
  * the current page, set focus on the report.
  */
-static void
-gnc_plugin_page_report_main_window_page_changed (GncMainWindow *window,
-                                                 GncPluginPage *current_plugin_page,
-                                                 GncPluginPage *report_plugin_page)
+static gboolean
+gnc_plugin_page_report_focus_widget (GncPluginPage *report_plugin_page)
 {
-    // We continue only if the plugin_page is a valid
-    if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_REPORT(current_plugin_page) ||
-        !report_plugin_page || !GNC_IS_PLUGIN_PAGE_REPORT(report_plugin_page))
-        return;
-
-    if (current_plugin_page == report_plugin_page)
+    if (GNC_IS_PLUGIN_PAGE_REPORT(report_plugin_page))
     {
         GncPluginPageReportPrivate *priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report_plugin_page);
         GtkWidget *widget = gnc_html_get_widget (priv->html);
 
-        // The page changed signal is emitted multiple times so we need
-        // to use an idle_add to change the focus to the webkit widget
-        g_idle_remove_by_data (widget);
-        g_idle_add ((GSourceFunc)gnc_plugin_page_report_focus, widget);
+        if (GTK_IS_WIDGET(widget))
+        {
+            if (!gtk_widget_is_focus (GTK_WIDGET(widget)))
+                gtk_widget_grab_focus (GTK_WIDGET(widget));
+        }
     }
+    return FALSE;
 }
 
 static void
@@ -294,6 +278,7 @@ gnc_plugin_page_report_class_init (GncPluginPageReportClass *klass)
     gnc_plugin_page_class->page_name_changed = gnc_plugin_page_report_name_changed;
     gnc_plugin_page_class->update_edit_menu_actions = gnc_plugin_page_report_update_edit_menu;
     gnc_plugin_page_class->finish_pending   = gnc_plugin_page_report_finish_pending;
+    gnc_plugin_page_class->focus_page_function = gnc_plugin_page_report_focus_widget;
 
     // create the "reportId" property
     g_object_class_install_property( object_class,
@@ -412,7 +397,6 @@ gnc_plugin_page_report_create_widget( GncPluginPage *page )
 {
     GncPluginPageReport *report;
     GncPluginPageReportPrivate *priv;
-    GncMainWindow  *window;
     GtkWindow *topLvl;
     GtkAction *action;
     URLType type;
@@ -477,10 +461,9 @@ gnc_plugin_page_report_create_widget( GncPluginPage *page )
     g_signal_connect (G_OBJECT(GTK_WIDGET(priv->container)), "realize",
                       G_CALLBACK(gnc_plugin_page_report_realize_uri), page);
 
-    window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(page)->window);
-    g_signal_connect(window, "page_changed",
-                     G_CALLBACK(gnc_plugin_page_report_main_window_page_changed),
-                     page);
+    g_signal_connect (G_OBJECT(page), "inserted",
+                      G_CALLBACK(gnc_plugin_page_inserted_cb),
+                      NULL);
 
     gtk_widget_show_all( GTK_WIDGET(priv->container) );
     LEAVE("container %p", priv->container);
@@ -783,8 +766,11 @@ gnc_plugin_page_report_destroy_widget(GncPluginPage *plugin_page)
 
     widget = gnc_html_get_widget(priv->html);
 
+    // Remove the page_changed signal callback
+    gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
+
     // Remove the page focus idle function if present
-    g_idle_remove_by_data (widget);
+    g_idle_remove_by_data (plugin_page);
 
     if (priv->component_manager_id)
     {



Summary of changes:
 gnucash/gnome-utils/gnc-main-window.c              |   8 +-
 gnucash/gnome-utils/gnc-plugin-page.c              | 102 ++++++++++++++++++++-
 gnucash/gnome-utils/gnc-plugin-page.h              |  35 ++++++-
 gnucash/gnome/gnc-plugin-page-account-tree.c       |  47 ++++------
 gnucash/gnome/gnc-plugin-page-account-tree.h       |   9 --
 gnucash/gnome/gnc-plugin-page-budget.c             |  49 ++++------
 gnucash/gnome/gnc-plugin-page-budget.h             |  10 --
 gnucash/gnome/gnc-plugin-page-invoice.c            |  80 +++++++---------
 gnucash/gnome/gnc-plugin-page-owner-tree.c         |  55 ++++-------
 gnucash/gnome/gnc-plugin-page-register.c           |  61 +++++++-----
 gnucash/gnome/gnc-plugin-page-register.h           |  10 --
 gnucash/gnome/gnc-plugin-page-sx-list.c            |  56 +++++------
 .../report/report-gnome/gnc-plugin-page-report.c   |  48 ++++------
 13 files changed, 303 insertions(+), 267 deletions(-)



More information about the gnucash-changes mailing list