[gspell/wip/entry: 6/8] Entry: fix infinite loop



commit a0eaee056b86b92384d793512d232e82ba1a58e7
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sat Oct 29 17:05:06 2016 +0200

    Entry: fix infinite loop
    
    In test-entry, when clicking on the Bold button, there was an infinite
    loop:
    notify_attributes_cb
    recheck_all
    notify_attributes_cb
    recheck_all
    ...

 gspell/gspell-entry.c |   34 ++++++++++++++++++++++++++++++++--
 1 files changed, 32 insertions(+), 2 deletions(-)
---
diff --git a/gspell/gspell-entry.c b/gspell/gspell-entry.c
index 06d3e73..e97654a 100644
--- a/gspell/gspell-entry.c
+++ b/gspell/gspell-entry.c
@@ -41,7 +41,10 @@ struct _GspellEntry
        GObject parent;
 
        GtkEntry *entry;
+
        gulong notify_attributes_handler_id;
+       guint notify_attributes_idle_id;
+
        guint inline_spell_checking : 1;
 };
 
@@ -178,13 +181,34 @@ changed_after_cb (GtkEditable *editable,
        recheck_all (gspell_entry);
 }
 
+static gboolean
+notify_attributes_idle_cb (gpointer user_data)
+{
+       GspellEntry *gspell_entry = GSPELL_ENTRY (user_data);
+
+       /* Re-apply our attributes. Do it in an idle function, to not be inside
+        * a notify::attributes signal emission. If we call recheck_all() during
+        * the signal emission, there is an infinite loop.
+        */
+       recheck_all (gspell_entry);
+
+       gspell_entry->notify_attributes_idle_id = 0;
+       return G_SOURCE_REMOVE;
+}
+
 static void
 notify_attributes_cb (GtkEntry    *gtk_entry,
                      GParamSpec  *pspec,
                      GspellEntry *gspell_entry)
 {
-       /* Re-apply our attributes. */
-       recheck_all (gspell_entry);
+       if (gspell_entry->notify_attributes_idle_id == 0)
+       {
+               gspell_entry->notify_attributes_idle_id =
+                       g_idle_add_full (G_PRIORITY_HIGH_IDLE,
+                                        notify_attributes_idle_cb,
+                                        gspell_entry,
+                                        NULL);
+       }
 }
 
 static void
@@ -271,6 +295,12 @@ gspell_entry_dispose (GObject *object)
 
        gspell_entry->entry = NULL;
 
+       if (gspell_entry->notify_attributes_idle_id != 0)
+       {
+               g_source_remove (gspell_entry->notify_attributes_idle_id);
+               gspell_entry->notify_attributes_idle_id = 0;
+       }
+
        G_OBJECT_CLASS (gspell_entry_parent_class)->dispose (object);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]