From ffe3aa792cd236890a9295b762e1a9d3a01ef2de Mon Sep 17 00:00:00 2001 From: Robert Fewell <14uBobIT@gmail.com> Date: Sat, 11 Jan 2020 14:10:41 +0000 Subject: [PATCH] Bug 797522 - Focus after reconcile jumps to a different account After the use of the reconcile window, the keyboard focus may not be on the current account register. This is due to the call for a gui refresh which refreshes the pages in reverse qofinstance order and as part of this there is a call to grab the keyboard focus on the register sheet so the last one will have the keyboard focus which may not be the current register, just depends on the order of creation. To fix this, as part of the main window page changed callback a flag is set on the current sheet to indicate it can grab the focus on refresh. --- gnucash/gnome/gnc-plugin-page-register.c | 12 ++++++++++++ gnucash/gnome/gnc-split-reg.c | 8 ++++++++ gnucash/gnome/gnc-split-reg.h | 1 + gnucash/register/register-gnome/gnucash-sheet.c | 15 +++++++++++++-- gnucash/register/register-gnome/gnucash-sheet.h | 2 ++ gnucash/register/register-gnome/gnucash-sheetP.h | 2 ++ 6 files changed, 38 insertions(+), 2 deletions(-) diff --git a/gnucash/gnome/gnc-plugin-page-register.c b/gnucash/gnome/gnc-plugin-page-register.c index ace2c379dd..1d19586983 100644 --- a/gnucash/gnome/gnc-plugin-page-register.c +++ b/gnucash/gnome/gnc-plugin-page-register.c @@ -566,6 +566,7 @@ typedef struct GncPluginPageRegisterPrivate gint lines_default; gboolean read_only; + gboolean page_focus; gboolean enable_refresh; // used to reduce ledger display refreshes Query *search_query; // saved search query for comparison Query *filter_query; // saved filter query for comparison @@ -1150,6 +1151,7 @@ gnc_plugin_register_main_window_page_changed (GncMainWindow *window, GncPluginPage *register_plugin_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) || @@ -1157,15 +1159,23 @@ gnc_plugin_register_main_window_page_changed (GncMainWindow *window, return; priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(register_plugin_page); + gsr = gnc_plugin_page_register_get_gsr (GNC_PLUGIN_PAGE(register_plugin_page)); if (current_plugin_page == register_plugin_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)); } + else + priv->page_focus = FALSE; + + // set the sheet focus setting + gnc_split_reg_set_sheet_focus (gsr, priv->page_focus); } static GtkWidget * @@ -1194,6 +1204,8 @@ gnc_plugin_page_register_create_widget (GncPluginPage *plugin_page) LEAVE("existing widget %p", priv->widget); return priv->widget; } + // on create, the page will be the current page so set the focus flag + priv->page_focus = TRUE; priv->widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_box_set_homogeneous (GTK_BOX (priv->widget), FALSE); diff --git a/gnucash/gnome/gnc-split-reg.c b/gnucash/gnome/gnc-split-reg.c index f8c3db9edd..599a167057 100644 --- a/gnucash/gnome/gnc-split-reg.c +++ b/gnucash/gnome/gnc-split-reg.c @@ -1930,6 +1930,14 @@ gnc_split_reg_focus_on_sheet (GNCSplitReg *gsr) gtk_widget_grab_focus (GTK_WIDGET (sheet)); } +void +gnc_split_reg_set_sheet_focus (GNCSplitReg *gsr, gboolean has_focus) +{ + GnucashRegister *reg = gsr->reg; + GnucashSheet *sheet = gnucash_register_get_sheet (reg); + gnucash_sheet_set_has_focus (sheet, has_focus); +} + void gnc_split_reg_balancing_entry(GNCSplitReg *gsr, Account *account, time64 statement_date, gnc_numeric balancing_amount) diff --git a/gnucash/gnome/gnc-split-reg.h b/gnucash/gnome/gnc-split-reg.h index d54372c8e0..8c0f78c24e 100644 --- a/gnucash/gnome/gnc-split-reg.h +++ b/gnucash/gnome/gnc-split-reg.h @@ -248,6 +248,7 @@ void gnc_split_reg_jump_to_split_amount(GNCSplitReg *gsr, Split *split); * Set the focus of the register to the sheet **/ void gnc_split_reg_focus_on_sheet (GNCSplitReg *gsr); +void gnc_split_reg_set_sheet_focus (GNCSplitReg *gsr, gboolean has_focus); /* * Create a transaction entry with given amount and date. One account is diff --git a/gnucash/register/register-gnome/gnucash-sheet.c b/gnucash/register/register-gnome/gnucash-sheet.c index 0494117376..36bd9c6525 100644 --- a/gnucash/register/register-gnome/gnucash-sheet.c +++ b/gnucash/register/register-gnome/gnucash-sheet.c @@ -407,8 +407,10 @@ gnucash_sheet_activate_cursor_cell (GnucashSheet *sheet, sheet->direct_update_cell = gnucash_sheet_check_direct_update_cell (sheet, virt_loc); } - - gtk_widget_grab_focus (GTK_WIDGET(sheet)); + // when a gui refresh is called, we end up here so only grab the focus + // if the sheet is showing on the current plugin_page + if (sheet->sheet_has_focus) + gtk_widget_grab_focus (GTK_WIDGET(sheet)); } @@ -757,6 +759,12 @@ gnucash_sheet_is_read_only (GnucashSheet *sheet) return gnc_table_model_read_only (sheet->table->model); } +void +gnucash_sheet_set_has_focus (GnucashSheet *sheet, gboolean has_focus) +{ + sheet->sheet_has_focus = has_focus; +} + static void gnucash_sheet_finalize (GObject *object) { @@ -2764,6 +2772,9 @@ gnucash_sheet_new (Table *table) sheet = gnucash_sheet_create (table); + /* on create, the sheet can grab the focus */ + sheet->sheet_has_focus = TRUE; + /* The cursor */ sheet->cursor = gnucash_cursor_new (sheet); diff --git a/gnucash/register/register-gnome/gnucash-sheet.h b/gnucash/register/register-gnome/gnucash-sheet.h index 907cd34e9f..c24fe2c199 100644 --- a/gnucash/register/register-gnome/gnucash-sheet.h +++ b/gnucash/register/register-gnome/gnucash-sheet.h @@ -112,5 +112,7 @@ gint gnucash_sheet_get_text_offset (GnucashSheet *sheet, const VirtualLocation v gboolean gnucash_sheet_is_read_only (GnucashSheet *sheet); +void gnucash_sheet_set_has_focus (GnucashSheet *sheet, gboolean has_focus); + /** @} */ #endif diff --git a/gnucash/register/register-gnome/gnucash-sheetP.h b/gnucash/register/register-gnome/gnucash-sheetP.h index 888106832d..1c2d96c1d5 100644 --- a/gnucash/register/register-gnome/gnucash-sheetP.h +++ b/gnucash/register/register-gnome/gnucash-sheetP.h @@ -80,6 +80,8 @@ struct _GnucashSheet gint editing; + gboolean sheet_has_focus; + guint button; /* mouse button being held down */ gboolean grabbed; /* has the grab */ gdouble button_x, button_y;