[gimp] app: update a GimpMessageBox repeated in a idle function.
- From: Jehan Pagès <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: update a GimpMessageBox repeated in a idle function.
- Date: Sat, 3 Feb 2018 21:55:15 +0000 (UTC)
commit 110779eba3cc24e09d9e4d369bbec705230a1477
Author: Jehan <jehan girinstud io>
Date: Sat Feb 3 22:37:47 2018 +0100
app: update a GimpMessageBox repeated in a idle function.
I was directed by Massimo to some bug which was repeatedly generating
dozens of thousands of GEGL WARNINGs and that was completely taking over
the GUI if redirected to GimpErrorDialog. Currently GEGL warnings are
not redirected there, but the problem is still there, and we don't want
GIMP warnings to freeze the whole GUI either.
So only increment the repeat variable upon gimp_message_box_repeat() and
delay actual GUI update to a later low-priority idle function.
app/widgets/gimpmessagebox.c | 72 +++++++++++++++++++++++++++++-------------
app/widgets/gimpmessagebox.h | 2 +
2 files changed, 52 insertions(+), 22 deletions(-)
---
diff --git a/app/widgets/gimpmessagebox.c b/app/widgets/gimpmessagebox.c
index f67205e..249b151 100644
--- a/app/widgets/gimpmessagebox.c
+++ b/app/widgets/gimpmessagebox.c
@@ -73,6 +73,7 @@ static void gimp_message_box_set_label_markup (GimpMessageBox *box,
const gchar *format,
va_list args) G_GNUC_PRINTF (3, 0);
+static gboolean gimp_message_box_update (gpointer data);
G_DEFINE_TYPE (GimpMessageBox, gimp_message_box, GTK_TYPE_BOX)
@@ -144,6 +145,7 @@ gimp_message_box_init (GimpMessageBox *box)
box->repeat = 0;
box->label[2] = NULL;
+ box->idle_id = 0;
}
static void
@@ -185,6 +187,10 @@ gimp_message_box_finalize (GObject *object)
{
GimpMessageBox *box = GIMP_MESSAGE_BOX (object);
+ if (box->idle_id)
+ g_source_remove (box->idle_id);
+ box->idle_id = 0;
+
if (box->icon_name)
{
g_free (box->icon_name);
@@ -378,6 +384,40 @@ gimp_message_box_set_label_markup (GimpMessageBox *box,
}
}
+static gboolean
+gimp_message_box_update (gpointer data)
+{
+ GimpMessageBox *box = data;
+ gchar *message;
+
+ box->idle_id = 0;
+
+ message = g_strdup_printf (ngettext ("Message repeated once.",
+ "Message repeated %d times.",
+ box->repeat),
+ box->repeat);
+
+ if (box->label[2])
+ {
+ gtk_label_set_text (GTK_LABEL (box->label[2]), message);
+ }
+ else
+ {
+ GtkWidget *label = box->label[2] = gtk_label_new (message);
+
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+ gimp_label_set_attributes (GTK_LABEL (label),
+ PANGO_ATTR_STYLE, PANGO_STYLE_OBLIQUE,
+ -1);
+ gtk_box_pack_end (GTK_BOX (box), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+ }
+
+ g_free (message);
+
+ return G_SOURCE_REMOVE;
+}
+
/* public functions */
GtkWidget *
@@ -433,34 +473,22 @@ gimp_message_box_set_markup (GimpMessageBox *box,
gint
gimp_message_box_repeat (GimpMessageBox *box)
{
- gchar *message;
-
g_return_val_if_fail (GIMP_IS_MESSAGE_BOX (box), 0);
box->repeat++;
- message = g_strdup_printf (ngettext ("Message repeated once.",
- "Message repeated %d times.",
- box->repeat),
- box->repeat);
-
- if (box->label[2])
+ if (box->idle_id == 0)
{
- gtk_label_set_text (GTK_LABEL (box->label[2]), message);
+ /* When a same message is repeated dozens of thousands of times in
+ * a short span of time, updating the GUI at each increment is
+ * extremely slow (like really really slow, your GUI gets stuck
+ * for 10 minutes). So let's just delay GUI update as a low
+ * priority idle task.
+ */
+ box->idle_id = g_idle_add_full (G_PRIORITY_LOW,
+ gimp_message_box_update,
+ box, NULL);
}
- else
- {
- GtkWidget *label = box->label[2] = gtk_label_new (message);
-
- gtk_label_set_xalign (GTK_LABEL (label), 0.0);
- gimp_label_set_attributes (GTK_LABEL (label),
- PANGO_ATTR_STYLE, PANGO_STYLE_OBLIQUE,
- -1);
- gtk_box_pack_end (GTK_BOX (box), label, FALSE, FALSE, 0);
- gtk_widget_show (label);
- }
-
- g_free (message);
return box->repeat;
}
diff --git a/app/widgets/gimpmessagebox.h b/app/widgets/gimpmessagebox.h
index 7ebd413..5a3a49d 100644
--- a/app/widgets/gimpmessagebox.h
+++ b/app/widgets/gimpmessagebox.h
@@ -42,6 +42,8 @@ struct _GimpMessageBox
gint repeat;
GtkWidget *label[3];
GtkWidget *image;
+
+ guint idle_id;
};
struct _GimpMessageBoxClass
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]