aboutsummaryrefslogtreecommitdiffstats
path: root/e-util
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2014-06-05 01:46:25 +0800
committerMilan Crha <mcrha@redhat.com>2014-06-05 01:46:25 +0800
commit2f3fbdd6c6ff42a6c71ebe1d1d78108affe59d0f (patch)
treefd60a103158c3cfdbbce197feca07d7fea008a3d /e-util
parent668745ff49d8f312c7d419a691cdab3e128ded06 (diff)
downloadgsoc2013-evolution-2f3fbdd6c6ff42a6c71ebe1d1d78108affe59d0f.tar
gsoc2013-evolution-2f3fbdd6c6ff42a6c71ebe1d1d78108affe59d0f.tar.gz
gsoc2013-evolution-2f3fbdd6c6ff42a6c71ebe1d1d78108affe59d0f.tar.bz2
gsoc2013-evolution-2f3fbdd6c6ff42a6c71ebe1d1d78108affe59d0f.tar.lz
gsoc2013-evolution-2f3fbdd6c6ff42a6c71ebe1d1d78108affe59d0f.tar.xz
gsoc2013-evolution-2f3fbdd6c6ff42a6c71ebe1d1d78108affe59d0f.tar.zst
gsoc2013-evolution-2f3fbdd6c6ff42a6c71ebe1d1d78108affe59d0f.zip
Ignore false GObject property change notifications
This is related to bug 698275, which did not cover all cases. The problem here is that the dconf can in certain situation claim that everything changed (path "/" changed), which GSettingsBinding propagates to a GObject property unconditionally and GObject's property setter (g_object_set_property()) also notifies about the property change unconditionally, despite the real descendant property setter properly checks for the value change. After all these false notifications a callback on "notify" signal is called and possibly an expensive operation is run. Checking whether the value really changed helps in performance, for which were added new e-util functions: e_signal_connect_notify() e_signal_connect_notify_after() e_signal_connect_notify_swapped() e_signal_connect_notify_object() which have the same prototype as their GLib counterparts, but they allow only "notify::..." signals and they test whether the value really changed before they call the registered callback.
Diffstat (limited to 'e-util')
-rw-r--r--e-util/e-action-combo-box.c5
-rw-r--r--e-util/e-activity-bar.c3
-rw-r--r--e-util/e-activity-proxy.c3
-rw-r--r--e-util/e-attachment-bar.c5
-rw-r--r--e-util/e-attachment-button.c3
-rw-r--r--e-util/e-attachment-paned.c7
-rw-r--r--e-util/e-attachment.c25
-rw-r--r--e-util/e-buffer-tagger.c2
-rw-r--r--e-util/e-category-completion.c6
-rw-r--r--e-util/e-charset-combo-box.c2
-rw-r--r--e-util/e-filter-rule.c5
-rw-r--r--e-util/e-interval-chooser.c5
-rw-r--r--e-util/e-menu-tool-button.c3
-rw-r--r--e-util/e-misc-utils.c236
-rw-r--r--e-util/e-misc-utils.h18
-rw-r--r--e-util/e-online-button.c6
-rw-r--r--e-util/e-paned.c9
-rw-r--r--e-util/e-picture-gallery.c3
-rw-r--r--e-util/e-search-bar.c3
-rw-r--r--e-util/e-source-config-dialog.c3
-rw-r--r--e-util/e-spell-entry.c3
-rw-r--r--e-util/e-table-click-to-add.c4
-rw-r--r--e-util/e-table-group-leaf.c2
-rw-r--r--e-util/e-table.c6
-rw-r--r--e-util/e-tree-view-frame.c12
-rw-r--r--e-util/e-tree.c6
-rw-r--r--e-util/e-web-view-gtkhtml.c39
-rw-r--r--e-util/e-web-view.c2
28 files changed, 374 insertions, 52 deletions
diff --git a/e-util/e-action-combo-box.c b/e-util/e-action-combo-box.c
index 14731a7983..1b784b8ee8 100644
--- a/e-util/e-action-combo-box.c
+++ b/e-util/e-action-combo-box.c
@@ -21,6 +21,7 @@
#endif
#include "e-action-combo-box.h"
+#include "e-misc-utils.h"
#include <glib/gi18n.h>
@@ -513,13 +514,13 @@ e_action_combo_box_set_action (EActionComboBox *combo_box,
if (combo_box->priv->action_group != NULL) {
combo_box->priv->group_sensitive_handler_id =
- g_signal_connect (
+ e_signal_connect_notify (
combo_box->priv->action_group,
"notify::sensitive", G_CALLBACK (
action_combo_box_action_group_notify_cb),
combo_box);
combo_box->priv->group_visible_handler_id =
- g_signal_connect (
+ e_signal_connect_notify (
combo_box->priv->action_group,
"notify::visible", G_CALLBACK (
action_combo_box_action_group_notify_cb),
diff --git a/e-util/e-activity-bar.c b/e-util/e-activity-bar.c
index 0edf019878..f90e51df94 100644
--- a/e-util/e-activity-bar.c
+++ b/e-util/e-activity-bar.c
@@ -16,6 +16,7 @@
*/
#include "e-activity-bar.h"
+#include "e-misc-utils.h"
#include <config.h>
@@ -388,7 +389,7 @@ e_activity_bar_set_activity (EActivityBar *bar,
G_OBJECT (activity), (GWeakNotify)
activity_bar_weak_notify_cb, bar);
- g_signal_connect_swapped (
+ e_signal_connect_notify_swapped (
activity, "notify::state",
G_CALLBACK (activity_bar_feedback), bar);
diff --git a/e-util/e-activity-proxy.c b/e-util/e-activity-proxy.c
index bf8ab6778b..bb21a5bc8a 100644
--- a/e-util/e-activity-proxy.c
+++ b/e-util/e-activity-proxy.c
@@ -19,6 +19,7 @@
*/
#include "e-activity-proxy.h"
+#include "e-misc-utils.h"
#include <config.h>
#include <glib/gi18n.h>
@@ -361,7 +362,7 @@ e_activity_proxy_set_activity (EActivityProxy *proxy,
G_OBJECT (activity), (GWeakNotify)
activity_proxy_weak_notify_cb, proxy);
- g_signal_connect_swapped (
+ e_signal_connect_notify_swapped (
activity, "notify::state",
G_CALLBACK (activity_proxy_feedback), proxy);
diff --git a/e-util/e-attachment-bar.c b/e-util/e-attachment-bar.c
index 3a14ba76b8..83c3c69430 100644
--- a/e-util/e-attachment-bar.c
+++ b/e-util/e-attachment-bar.c
@@ -29,6 +29,7 @@
#include "e-attachment-store.h"
#include "e-attachment-icon-view.h"
#include "e-attachment-tree-view.h"
+#include "e-misc-utils.h"
#define E_ATTACHMENT_BAR_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -132,12 +133,12 @@ attachment_bar_set_store (EAttachmentBar *bar,
GTK_TREE_VIEW (bar->priv->tree_view),
bar->priv->model);
- g_signal_connect_object (
+ e_signal_connect_notify_object (
bar->priv->model, "notify::num-attachments",
G_CALLBACK (attachment_bar_update_status), bar,
G_CONNECT_SWAPPED);
- g_signal_connect_object (
+ e_signal_connect_notify_object (
bar->priv->model, "notify::total-size",
G_CALLBACK (attachment_bar_update_status), bar,
G_CONNECT_SWAPPED);
diff --git a/e-util/e-attachment-button.c b/e-util/e-attachment-button.c
index 5d38a213d8..016e293f72 100644
--- a/e-util/e-attachment-button.c
+++ b/e-util/e-attachment-button.c
@@ -25,6 +25,7 @@
#endif
#include "e-attachment-button.h"
+#include "e-misc-utils.h"
#define E_ATTACHMENT_BUTTON_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -776,7 +777,7 @@ e_attachment_button_set_attachment (EAttachmentButton *button,
G_BINDING_SYNC_CREATE);
button->priv->shown_binding = binding;
- handler_id = g_signal_connect_swapped (
+ handler_id = e_signal_connect_notify_swapped (
attachment, "notify::reference",
G_CALLBACK (attachment_button_update_cell_view),
button);
diff --git a/e-util/e-attachment-paned.c b/e-util/e-attachment-paned.c
index 98772db873..34f0a2e5b9 100644
--- a/e-util/e-attachment-paned.c
+++ b/e-util/e-attachment-paned.c
@@ -26,6 +26,7 @@
#include <glib/gi18n.h>
+#include "e-misc-utils.h"
#include "e-attachment-view.h"
#include "e-attachment-store.h"
#include "e-attachment-icon-view.h"
@@ -744,15 +745,15 @@ e_attachment_paned_init (EAttachmentPaned *paned)
paned->priv->status_label = g_object_ref (widget);
gtk_widget_hide (widget);
- g_signal_connect_swapped (
+ e_signal_connect_notify_swapped (
paned->priv->expander, "notify::expanded",
G_CALLBACK (attachment_paned_notify_cb), paned);
- g_signal_connect_swapped (
+ e_signal_connect_notify_swapped (
paned->priv->model, "notify::num-attachments",
G_CALLBACK (attachment_paned_update_status), paned);
- g_signal_connect_swapped (
+ e_signal_connect_notify_swapped (
paned->priv->model, "notify::total-size",
G_CALLBACK (attachment_paned_update_status), paned);
diff --git a/e-util/e-attachment.c b/e-util/e-attachment.c
index 06018e8130..1ce400767d 100644
--- a/e-util/e-attachment.c
+++ b/e-util/e-attachment.c
@@ -33,6 +33,7 @@
#include "e-attachment-store.h"
#include "e-icon-factory.h"
#include "e-mktemp.h"
+#include "e-misc-utils.h"
#define E_ATTACHMENT_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -997,51 +998,51 @@ e_attachment_init (EAttachment *attachment)
g_mutex_init (&attachment->priv->property_lock);
g_mutex_init (&attachment->priv->idle_lock);
- g_signal_connect (
+ e_signal_connect_notify (
attachment, "notify::encrypted",
G_CALLBACK (attachment_update_icon_column), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
attachment, "notify::file-info",
G_CALLBACK (attachment_update_file_info_columns), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
attachment, "notify::file-info",
G_CALLBACK (attachment_update_icon_column), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
attachment, "notify::loading",
G_CALLBACK (attachment_update_icon_column), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
attachment, "notify::loading",
G_CALLBACK (attachment_update_progress_columns), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
attachment, "notify::percent",
G_CALLBACK (attachment_update_progress_columns), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
attachment, "notify::reference",
G_CALLBACK (attachment_update_file_info_columns), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
attachment, "notify::reference",
G_CALLBACK (attachment_update_icon_column), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
attachment, "notify::reference",
G_CALLBACK (attachment_update_progress_columns), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
attachment, "notify::saving",
G_CALLBACK (attachment_update_icon_column), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
attachment, "notify::saving",
G_CALLBACK (attachment_update_progress_columns), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
attachment, "notify::signed",
G_CALLBACK (attachment_update_icon_column), NULL);
diff --git a/e-util/e-buffer-tagger.c b/e-util/e-buffer-tagger.c
index c3c923aa7b..ccd23dc158 100644
--- a/e-util/e-buffer-tagger.c
+++ b/e-util/e-buffer-tagger.c
@@ -609,7 +609,7 @@ e_buffer_tagger_connect (GtkTextView *textview)
g_signal_connect (
buffer, "delete-range",
G_CALLBACK (buffer_delete_range), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
buffer, "notify::cursor-position",
G_CALLBACK (buffer_cursor_position), NULL);
diff --git a/e-util/e-category-completion.c b/e-util/e-category-completion.c
index cc8ed8936e..39e26e2edf 100644
--- a/e-util/e-category-completion.c
+++ b/e-util/e-category-completion.c
@@ -25,6 +25,8 @@
#include <libedataserver/libedataserver.h>
+#include "e-misc-utils.h"
+
#define E_CATEGORY_COMPLETION_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_CATEGORY_COMPLETION, ECategoryCompletionPrivate))
@@ -356,11 +358,11 @@ category_completion_track_entry (GtkEntryCompletion *completion)
g_object_ref (priv->last_known_entry);
- g_signal_connect_swapped (
+ e_signal_connect_notify_swapped (
priv->last_known_entry, "notify::cursor-position",
G_CALLBACK (category_completion_update_prefix), completion);
- g_signal_connect_swapped (
+ e_signal_connect_notify_swapped (
priv->last_known_entry, "notify::text",
G_CALLBACK (category_completion_update_prefix), completion);
diff --git a/e-util/e-charset-combo-box.c b/e-util/e-charset-combo-box.c
index 240c28582f..2d67ceb749 100644
--- a/e-util/e-charset-combo-box.c
+++ b/e-util/e-charset-combo-box.c
@@ -276,7 +276,7 @@ charset_combo_box_constructed (GObject *object)
e_action_combo_box_add_separator_after (
E_ACTION_COMBO_BOX (object), g_slist_length (group));
- g_signal_connect (
+ e_signal_connect_notify (
object, "notify::charset",
G_CALLBACK (charset_combo_box_notify_charset_cb), NULL);
}
diff --git a/e-util/e-filter-rule.c b/e-util/e-filter-rule.c
index 721ed748a7..3211e166fe 100644
--- a/e-util/e-filter-rule.c
+++ b/e-util/e-filter-rule.c
@@ -33,6 +33,7 @@
#include "e-dialog-widgets.h"
#include "e-filter-rule.h"
#include "e-rule-context.h"
+#include "e-misc-utils.h"
#define E_FILTER_RULE_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -903,10 +904,10 @@ filter_rule_get_widget (EFilterRule *rule,
vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1.0, 1.0, 1.0, 1.0));
scrolledwindow = gtk_scrolled_window_new (hadj, vadj);
- g_signal_connect (
+ e_signal_connect_notify (
hadj, "notify::upper",
G_CALLBACK (ensure_scrolled_width_cb), scrolledwindow);
- g_signal_connect (
+ e_signal_connect_notify (
vadj, "notify::upper",
G_CALLBACK (ensure_scrolled_height_cb), scrolledwindow);
diff --git a/e-util/e-interval-chooser.c b/e-util/e-interval-chooser.c
index 5e27471942..df6805cd3d 100644
--- a/e-util/e-interval-chooser.c
+++ b/e-util/e-interval-chooser.c
@@ -21,6 +21,7 @@
#include <glib/gi18n-lib.h>
#include "e-util-enums.h"
+#include "e-misc-utils.h"
#define E_INTERVAL_CHOOSER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -129,7 +130,7 @@ e_interval_chooser_init (EIntervalChooser *chooser)
chooser->priv->spin_button = GTK_SPIN_BUTTON (widget);
gtk_widget_show (widget);
- g_signal_connect_swapped (
+ e_signal_connect_notify_swapped (
widget, "notify::value",
G_CALLBACK (interval_chooser_notify_interval), chooser);
@@ -144,7 +145,7 @@ e_interval_chooser_init (EIntervalChooser *chooser)
chooser->priv->combo_box = GTK_COMBO_BOX (widget);
gtk_widget_show (widget);
- g_signal_connect_swapped (
+ e_signal_connect_notify_swapped (
widget, "notify::active",
G_CALLBACK (interval_chooser_notify_interval), chooser);
}
diff --git a/e-util/e-menu-tool-button.c b/e-util/e-menu-tool-button.c
index d181d5ee36..cffadd0f08 100644
--- a/e-util/e-menu-tool-button.c
+++ b/e-util/e-menu-tool-button.c
@@ -23,6 +23,7 @@
#endif
#include "e-menu-tool-button.h"
+#include "e-misc-utils.h"
#define E_MENU_TOOL_BUTTON_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -241,7 +242,7 @@ e_menu_tool_button_init (EMenuToolButton *button)
button->priv->prefer_item = NULL;
- g_signal_connect (
+ e_signal_connect_notify (
button, "notify::menu",
G_CALLBACK (menu_tool_button_update_button), NULL);
}
diff --git a/e-util/e-misc-utils.c b/e-util/e-misc-utils.c
index 3a52292af4..f7be7af5ac 100644
--- a/e-util/e-misc-utils.c
+++ b/e-util/e-misc-utils.c
@@ -2256,3 +2256,239 @@ e_binding_bind_object_text_property (gpointer source,
e_binding_transform_text_non_null,
NULL, NULL);
}
+
+typedef struct _EConnectNotifyData {
+ GConnectFlags flags;
+ GValue *old_value;
+
+ GCallback c_handler;
+ gpointer user_data;
+} EConnectNotifyData;
+
+static EConnectNotifyData *
+e_connect_notify_data_new (GCallback c_handler,
+ gpointer user_data,
+ guint32 connect_flags)
+{
+ EConnectNotifyData *connect_data;
+
+ connect_data = g_new0 (EConnectNotifyData, 1);
+ connect_data->flags = connect_flags;
+ connect_data->c_handler = c_handler;
+ connect_data->user_data = user_data;
+
+ return connect_data;
+}
+
+static void
+e_connect_notify_data_free (EConnectNotifyData *data)
+{
+ if (!data)
+ return;
+
+ if (data->old_value) {
+ g_value_unset (data->old_value);
+ g_free (data->old_value);
+ }
+ g_free (data);
+}
+
+static gboolean
+e_value_equal (GValue *value1,
+ GValue *value2)
+{
+ if (value1 == value2)
+ return TRUE;
+
+ if (!value1 || !value2)
+ return FALSE;
+
+ #define testType(_uc,_lc) G_STMT_START { \
+ if (G_VALUE_HOLDS_ ## _uc (value1)) \
+ return g_value_get_ ## _lc (value1) == g_value_get_ ## _lc (value2); \
+ } G_STMT_END
+
+ testType (BOOLEAN, boolean);
+ testType (BOXED, boxed);
+ testType (CHAR, schar);
+ testType (DOUBLE, double);
+ testType (ENUM, enum);
+ testType (FLAGS, flags);
+ testType (FLOAT, float);
+ testType (GTYPE, gtype);
+ testType (INT, int);
+ testType (INT64, int64);
+ testType (LONG, long);
+ testType (OBJECT, object);
+ testType (POINTER, pointer);
+ testType (UCHAR, uchar);
+ testType (UINT, uint);
+ testType (UINT64, uint64);
+ testType (ULONG, ulong);
+
+ #undef testType
+
+ if (G_VALUE_HOLDS_PARAM (value1)) {
+ GParamSpec *param1, *param2;
+
+ param1 = g_value_get_param (value1);
+ param2 = g_value_get_param (value2);
+
+ return param1 && param2 &&
+ g_strcmp0 (param1->name, param2->name) == 0 &&
+ param1->flags == param2->flags &&
+ param1->value_type == param2->value_type &&
+ param1->owner_type == param2->owner_type;
+ } else if (G_VALUE_HOLDS_STRING (value1)) {
+ const gchar *string1, *string2;
+
+ string1 = g_value_get_string (value1);
+ string2 = g_value_get_string (value2);
+
+ return g_strcmp0 (string1, string2) == 0;
+ } else if (G_VALUE_HOLDS_VARIANT (value1)) {
+ GVariant *variant1, *variant2;
+
+ variant1 = g_value_get_variant (value1);
+ variant2 = g_value_get_variant (value2);
+
+ return variant1 == variant2 ||
+ (variant1 && variant2 && g_variant_equal (variant1, variant2));
+ }
+
+ return FALSE;
+}
+
+static void
+e_signal_connect_notify_cb (gpointer instance,
+ GParamSpec *param,
+ gpointer user_data)
+{
+ EConnectNotifyData *connect_data = user_data;
+ GValue *value;
+
+ g_return_if_fail (connect_data != NULL);
+
+ value = g_new0 (GValue, 1);
+ g_value_init (value, param->value_type);
+ g_object_get_property (instance, param->name, value);
+
+ if (!e_value_equal (connect_data->old_value, value)) {
+ typedef void (* NotifyCBType) (gpointer instance, GParamSpec *param, gpointer user_data);
+ NotifyCBType c_handler = (NotifyCBType) connect_data->c_handler;
+
+ if (connect_data->old_value) {
+ g_value_unset (connect_data->old_value);
+ g_free (connect_data->old_value);
+ }
+ connect_data->old_value = value;
+
+ if (connect_data->flags == G_CONNECT_SWAPPED) {
+ c_handler (connect_data->user_data, param, instance);
+ } else {
+ c_handler (instance, param, connect_data->user_data);
+ }
+ } else {
+ g_value_unset (value);
+ g_free (value);
+ }
+}
+
+gulong
+e_signal_connect_notify (gpointer instance,
+ const gchar *notify_name,
+ GCallback c_handler,
+ gpointer user_data)
+{
+ EConnectNotifyData *connect_data;
+
+ g_return_val_if_fail (g_str_has_prefix (notify_name, "notify::"), 0);
+
+ connect_data = e_connect_notify_data_new (c_handler, user_data, 0);
+
+ return g_signal_connect_data (instance,
+ notify_name,
+ G_CALLBACK (e_signal_connect_notify_cb),
+ connect_data,
+ (GClosureNotify) e_connect_notify_data_free,
+ 0);
+}
+
+gulong
+e_signal_connect_notify_after (gpointer instance,
+ const gchar *notify_name,
+ GCallback c_handler,
+ gpointer user_data)
+{
+ EConnectNotifyData *connect_data;
+
+ g_return_val_if_fail (g_str_has_prefix (notify_name, "notify::"), 0);
+
+ connect_data = e_connect_notify_data_new (c_handler, user_data, G_CONNECT_AFTER);
+
+ return g_signal_connect_data (instance,
+ notify_name,
+ G_CALLBACK (e_signal_connect_notify_cb),
+ connect_data,
+ (GClosureNotify) e_connect_notify_data_free,
+ G_CONNECT_AFTER);
+}
+
+gulong
+e_signal_connect_notify_swapped (gpointer instance,
+ const gchar *notify_name,
+ GCallback c_handler,
+ gpointer user_data)
+{
+ EConnectNotifyData *connect_data;
+
+ g_return_val_if_fail (g_str_has_prefix (notify_name, "notify::"), 0);
+
+ connect_data = e_connect_notify_data_new (c_handler, user_data, G_CONNECT_SWAPPED);
+
+ return g_signal_connect_data (instance,
+ notify_name,
+ G_CALLBACK (e_signal_connect_notify_cb),
+ connect_data,
+ (GClosureNotify) e_connect_notify_data_free,
+ 0);
+}
+
+gulong
+e_signal_connect_notify_object (gpointer instance,
+ const gchar *notify_name,
+ GCallback c_handler,
+ gpointer gobject,
+ GConnectFlags connect_flags)
+{
+ EConnectNotifyData *connect_data;
+ GClosure *closure;
+
+ g_return_val_if_fail (g_str_has_prefix (notify_name, "notify::"), 0);
+
+ if (!gobject) {
+ if ((connect_flags & G_CONNECT_SWAPPED) != 0)
+ return e_signal_connect_notify_swapped (instance, notify_name, c_handler, gobject);
+ else if ((connect_flags & G_CONNECT_AFTER) != 0)
+ e_signal_connect_notify_after (instance, notify_name, c_handler, gobject);
+ else
+ g_warn_if_fail (connect_flags == 0);
+
+ return e_signal_connect_notify (instance, notify_name, c_handler, gobject);
+ }
+
+ g_return_val_if_fail (G_IS_OBJECT (gobject), 0);
+
+ connect_data = e_connect_notify_data_new (c_handler, gobject, connect_flags & G_CONNECT_SWAPPED);
+ closure = g_cclosure_new (
+ G_CALLBACK (e_signal_connect_notify_cb),
+ connect_data,
+ (GClosureNotify) e_connect_notify_data_free);
+
+ g_object_watch_closure (G_OBJECT (gobject), closure);
+
+ return g_signal_connect_closure (instance,
+ notify_name,
+ closure,
+ connect_flags & G_CONNECT_AFTER);
+}
diff --git a/e-util/e-misc-utils.h b/e-util/e-misc-utils.h
index 33d8978a31..06de228899 100644
--- a/e-util/e-misc-utils.h
+++ b/e-util/e-misc-utils.h
@@ -211,6 +211,24 @@ GBinding * e_binding_bind_object_text_property
const gchar *target_property,
GBindingFlags flags);
+gulong e_signal_connect_notify (gpointer instance,
+ const gchar *notify_name,
+ GCallback c_handler,
+ gpointer user_data);
+gulong e_signal_connect_notify_after (gpointer instance,
+ const gchar *notify_name,
+ GCallback c_handler,
+ gpointer user_data);
+gulong e_signal_connect_notify_swapped (gpointer instance,
+ const gchar *notify_name,
+ GCallback c_handler,
+ gpointer user_data);
+gulong e_signal_connect_notify_object (gpointer instance,
+ const gchar *notify_name,
+ GCallback c_handler,
+ gpointer gobject,
+ GConnectFlags connect_flags);
+
G_END_DECLS
#endif /* E_MISC_UTILS_H */
diff --git a/e-util/e-online-button.c b/e-util/e-online-button.c
index 0589c197f4..b2bd68792e 100644
--- a/e-util/e-online-button.c
+++ b/e-util/e-online-button.c
@@ -22,6 +22,8 @@
#include <glib/gi18n.h>
+#include "e-misc-utils.h"
+
#define E_ONLINE_BUTTON_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_ONLINE_BUTTON, EOnlineButtonPrivate))
@@ -154,11 +156,11 @@ e_online_button_init (EOnlineButton *button)
button->priv->image = g_object_ref (widget);
gtk_widget_show (widget);
- g_signal_connect (
+ e_signal_connect_notify (
button, "notify::online",
G_CALLBACK (online_button_update_tooltip), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
button, "notify::sensitive",
G_CALLBACK (online_button_update_tooltip), NULL);
}
diff --git a/e-util/e-paned.c b/e-util/e-paned.c
index f56a06796c..b4a0914163 100644
--- a/e-util/e-paned.c
+++ b/e-util/e-paned.c
@@ -26,6 +26,8 @@
#include <glib/gi18n-lib.h>
+#include "e-misc-utils.h"
+
#define E_PANED_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_PANED, EPanedPrivate))
@@ -375,11 +377,11 @@ e_paned_init (EPaned *paned)
paned->priv->proportion = 0.5;
paned->priv->fixed_resize = TRUE;
- g_signal_connect (
+ e_signal_connect_notify (
paned, "notify::orientation",
G_CALLBACK (paned_notify_orientation_cb), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
paned, "notify::position",
G_CALLBACK (paned_notify_position_cb), NULL);
}
@@ -471,6 +473,9 @@ e_paned_set_proportion (EPaned *paned,
g_return_if_fail (E_IS_PANED (paned));
g_return_if_fail (CLAMP (proportion, 0.0, 1.0) == proportion);
+ if (paned->priv->proportion == proportion)
+ return;
+
paned->priv->proportion = proportion;
paned->priv->sync_request = SYNC_REQUEST_PROPORTION;
diff --git a/e-util/e-picture-gallery.c b/e-util/e-picture-gallery.c
index 117602877b..71e48e01a0 100644
--- a/e-util/e-picture-gallery.c
+++ b/e-util/e-picture-gallery.c
@@ -25,6 +25,7 @@
#include "e-picture-gallery.h"
#include "e-icon-factory.h"
+#include "e-misc-utils.h"
#define E_PICTURE_GALLERY_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -377,7 +378,7 @@ picture_gallery_constructed (GObject *object)
gtk_target_table_free (targets, n_targets);
gtk_target_list_unref (list);
- g_signal_connect (object, "notify::visible", G_CALLBACK (visible_cb), NULL);
+ e_signal_connect_notify (object, "notify::visible", G_CALLBACK (visible_cb), NULL);
}
static void
diff --git a/e-util/e-search-bar.c b/e-util/e-search-bar.c
index 13b4ee6f87..d3ade3540d 100644
--- a/e-util/e-search-bar.c
+++ b/e-util/e-search-bar.c
@@ -28,6 +28,7 @@
#include <gdk/gdkkeysyms.h>
#include "e-dialog-widgets.h"
+#include "e-misc-utils.h"
#define E_SEARCH_BAR_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -235,7 +236,7 @@ search_bar_set_web_view (ESearchBar *search_bar,
search_bar->priv->web_view = g_object_ref (web_view);
- g_signal_connect (
+ e_signal_connect_notify (
web_view, "notify::load-status",
G_CALLBACK (web_view_load_status_changed_cb), search_bar);
}
diff --git a/e-util/e-source-config-dialog.c b/e-util/e-source-config-dialog.c
index 507f8c459b..f5d1b72b16 100644
--- a/e-util/e-source-config-dialog.c
+++ b/e-util/e-source-config-dialog.c
@@ -26,6 +26,7 @@
#include "e-alert-bar.h"
#include "e-alert-dialog.h"
#include "e-alert-sink.h"
+#include "e-misc-utils.h"
#define E_SOURCE_CONFIG_DIALOG_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -275,7 +276,7 @@ source_config_dialog_constructed (GObject *object)
priv->alert_bar = g_object_ref (widget);
/* EAlertBar controls its own visibility. */
- handler_id = g_signal_connect (
+ handler_id = e_signal_connect_notify (
priv->alert_bar, "notify::visible",
G_CALLBACK (source_config_alert_bar_visible_cb), object);
diff --git a/e-util/e-spell-entry.c b/e-util/e-spell-entry.c
index cea403948b..75c7a6a9c8 100644
--- a/e-util/e-spell-entry.c
+++ b/e-util/e-spell-entry.c
@@ -26,6 +26,7 @@
#include <editor/gtkhtml-spell-language.h>
#include <editor/gtkhtml-spell-checker.h>
+#include "e-misc-utils.h"
#include "e-spell-entry.h"
#define E_SPELL_ENTRY_GET_PRIVATE(obj) \
@@ -878,7 +879,7 @@ e_spell_entry_init (ESpellEntry *spell_entry)
g_signal_connect (
spell_entry, "changed",
G_CALLBACK (spell_entry_changed), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
spell_entry, "notify::scroll-offset",
G_CALLBACK (spell_entry_notify_scroll_offset), NULL);
diff --git a/e-util/e-table-click-to-add.c b/e-util/e-table-click-to-add.c
index b0af6eaac6..77422534c4 100644
--- a/e-util/e-table-click-to-add.c
+++ b/e-util/e-table-click-to-add.c
@@ -414,7 +414,7 @@ finish_editing (ETableClickToAdd *etcta)
etcta->row, "key_press",
G_CALLBACK (item_key_press), etcta);
- g_signal_connect (
+ e_signal_connect_notify (
etcta->row, "notify::is-editing",
G_CALLBACK (table_click_to_add_row_is_editing_changed_cb), etcta);
@@ -472,7 +472,7 @@ etcta_event (GnomeCanvasItem *item,
etcta->row, "key_press",
G_CALLBACK (item_key_press), etcta);
- g_signal_connect (
+ e_signal_connect_notify (
etcta->row, "notify::is-editing",
G_CALLBACK (table_click_to_add_row_is_editing_changed_cb), etcta);
diff --git a/e-util/e-table-group-leaf.c b/e-util/e-table-group-leaf.c
index 4cb5f18374..88ea6b0e8d 100644
--- a/e-util/e-table-group-leaf.c
+++ b/e-util/e-table-group-leaf.c
@@ -368,7 +368,7 @@ etgl_realize (GnomeCanvasItem *item)
etgl->item, "start_drag",
G_CALLBACK (etgl_start_drag), etgl);
- g_signal_connect (
+ e_signal_connect_notify (
etgl->item, "notify::is-editing",
G_CALLBACK (etgl_item_is_editing_changed_cb), etgl);
diff --git a/e-util/e-table.c b/e-util/e-table.c
index 0dd02a2422..096313549e 100644
--- a/e-util/e-table.c
+++ b/e-util/e-table.c
@@ -1147,7 +1147,7 @@ et_build_groups (ETable *et)
g_signal_connect (
et->group, "start_drag",
G_CALLBACK (group_start_drag), et);
- g_signal_connect (
+ e_signal_connect_notify (
et->group, "notify::is-editing",
G_CALLBACK (group_is_editing_changed_cb), et);
@@ -1529,7 +1529,7 @@ e_table_setup_table (ETable *e_table,
g_signal_connect (
e_table->click_to_add, "cursor_change",
G_CALLBACK (click_to_add_cursor_change), e_table);
- g_signal_connect (
+ e_signal_connect_notify (
e_table->click_to_add, "notify::is-editing",
G_CALLBACK (click_to_add_is_editing_changed_cb), e_table);
}
@@ -2211,7 +2211,7 @@ et_set_property (GObject *object,
etable->click_to_add, "cursor_change",
G_CALLBACK (click_to_add_cursor_change),
etable);
- g_signal_connect (
+ e_signal_connect_notify (
etable->click_to_add, "notify::is-editing",
G_CALLBACK (click_to_add_is_editing_changed_cb), etable);
} else {
diff --git a/e-util/e-tree-view-frame.c b/e-util/e-tree-view-frame.c
index d3f70c6283..bde8b9fafa 100644
--- a/e-util/e-tree-view-frame.c
+++ b/e-util/e-tree-view-frame.c
@@ -29,10 +29,16 @@
* extended through e_tree_view_frame_insert_toolbar_action().
**/
-#include "e-tree-view-frame.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <libebackend/libebackend.h>
+#include "e-misc-utils.h"
+
+#include "e-tree-view-frame.h"
+
#define E_TREE_VIEW_FRAME_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_TREE_VIEW_FRAME, ETreeViewFramePrivate))
@@ -937,13 +943,13 @@ e_tree_view_frame_set_tree_view (ETreeViewFrame *tree_view_frame,
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
- handler_id = g_signal_connect (
+ handler_id = e_signal_connect_notify (
tree_view, "notify::reorderable",
G_CALLBACK (tree_view_frame_notify_reorderable_cb),
tree_view_frame);
tree_view_frame->priv->notify_reorderable_handler_id = handler_id;
- handler_id = g_signal_connect (
+ handler_id = e_signal_connect_notify (
selection, "notify::mode",
G_CALLBACK (tree_view_frame_notify_select_mode_cb),
tree_view_frame);
diff --git a/e-util/e-tree.c b/e-util/e-tree.c
index d56456b4ad..30d20fc4c8 100644
--- a/e-util/e-tree.c
+++ b/e-util/e-tree.c
@@ -1165,7 +1165,7 @@ et_build_item (ETree *tree)
g_signal_connect (
tree->priv->item, "start_drag",
G_CALLBACK (item_start_drag), tree);
- g_signal_connect (
+ e_signal_connect_notify (
tree->priv->item, "notify::is-editing",
G_CALLBACK (tree_item_is_editing_changed_cb), tree);
}
@@ -1283,7 +1283,7 @@ et_setup_table_canvas_vadjustment (ETree *tree)
if (vadjustment) {
tree->priv->table_canvas_vadjustment = g_object_ref (vadjustment);
- g_signal_connect (
+ e_signal_connect_notify (
vadjustment, "notify::value",
G_CALLBACK (e_tree_table_canvas_scrolled_cb), tree);
}
@@ -1336,7 +1336,7 @@ e_tree_setup_table (ETree *tree)
G_CALLBACK (tree_canvas_reflow), tree);
et_setup_table_canvas_vadjustment (tree);
- g_signal_connect_swapped (
+ e_signal_connect_notify_swapped (
tree->priv->table_canvas, "notify::vadjustment",
G_CALLBACK (et_setup_table_canvas_vadjustment), tree);
diff --git a/e-util/e-web-view-gtkhtml.c b/e-util/e-web-view-gtkhtml.c
index 799240d45d..7963a1cbf9 100644
--- a/e-util/e-web-view-gtkhtml.c
+++ b/e-util/e-web-view-gtkhtml.c
@@ -1791,6 +1791,9 @@ e_web_view_gtkhtml_set_animate (EWebViewGtkHTML *web_view,
g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view));
+ if (gtk_html_get_animate (GTK_HTML (web_view)) == animate)
+ return;
+
gtk_html_set_animate (GTK_HTML (web_view), animate);
g_object_notify (G_OBJECT (web_view), "animate");
@@ -1817,6 +1820,9 @@ e_web_view_gtkhtml_set_caret_mode (EWebViewGtkHTML *web_view,
g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view));
+ if (gtk_html_get_caret_mode (GTK_HTML (web_view)) == caret_mode)
+ return;
+
gtk_html_set_caret_mode (GTK_HTML (web_view), caret_mode);
g_object_notify (G_OBJECT (web_view), "caret-mode");
@@ -1844,6 +1850,9 @@ e_web_view_gtkhtml_set_disable_printing (EWebViewGtkHTML *web_view,
{
g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view));
+ if (web_view->priv->disable_printing == disable_printing)
+ return;
+
web_view->priv->disable_printing = disable_printing;
g_object_notify (G_OBJECT (web_view), "disable-printing");
@@ -1863,6 +1872,9 @@ e_web_view_gtkhtml_set_disable_save_to_disk (EWebViewGtkHTML *web_view,
{
g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view));
+ if (web_view->priv->disable_save_to_disk == disable_save_to_disk)
+ return;
+
web_view->priv->disable_save_to_disk = disable_save_to_disk;
g_object_notify (G_OBJECT (web_view), "disable-save-to-disk");
@@ -1889,6 +1901,9 @@ e_web_view_gtkhtml_set_editable (EWebViewGtkHTML *web_view,
g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view));
+ if (gtk_html_get_editable (GTK_HTML (web_view)) == editable)
+ return;
+
gtk_html_set_editable (GTK_HTML (web_view), editable);
g_object_notify (G_OBJECT (web_view), "editable");
@@ -1915,6 +1930,9 @@ e_web_view_gtkhtml_set_inline_spelling (EWebViewGtkHTML *web_view,
g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view));
+ if (gtk_html_get_inline_spelling (GTK_HTML (web_view)) == inline_spelling)
+ return;
+
gtk_html_set_inline_spelling (GTK_HTML (web_view), inline_spelling);
g_object_notify (G_OBJECT (web_view), "inline-spelling");
@@ -1941,6 +1959,9 @@ e_web_view_gtkhtml_set_magic_links (EWebViewGtkHTML *web_view,
g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view));
+ if (gtk_html_get_magic_links (GTK_HTML (web_view)) == magic_links)
+ return;
+
gtk_html_set_magic_links (GTK_HTML (web_view), magic_links);
g_object_notify (G_OBJECT (web_view), "magic-links");
@@ -1967,6 +1988,9 @@ e_web_view_gtkhtml_set_magic_smileys (EWebViewGtkHTML *web_view,
g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view));
+ if (gtk_html_get_magic_smileys (GTK_HTML (web_view)) == magic_smileys)
+ return;
+
gtk_html_set_magic_smileys (GTK_HTML (web_view), magic_smileys);
g_object_notify (G_OBJECT (web_view), "magic-smileys");
@@ -1986,6 +2010,9 @@ e_web_view_gtkhtml_set_selected_uri (EWebViewGtkHTML *web_view,
{
g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view));
+ if (g_strcmp0 (web_view->priv->selected_uri, selected_uri) == 0)
+ return;
+
g_free (web_view->priv->selected_uri);
web_view->priv->selected_uri = g_strdup (selected_uri);
@@ -2006,6 +2033,9 @@ e_web_view_gtkhtml_set_cursor_image (EWebViewGtkHTML *web_view,
{
g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view));
+ if (web_view->priv->cursor_image == image)
+ return;
+
if (image != NULL)
g_object_ref (image);
@@ -2031,6 +2061,9 @@ e_web_view_gtkhtml_set_open_proxy (EWebViewGtkHTML *web_view,
{
g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view));
+ if (web_view->priv->open_proxy == open_proxy)
+ return;
+
if (open_proxy != NULL) {
g_return_if_fail (GTK_IS_ACTION (open_proxy));
g_object_ref (open_proxy);
@@ -2066,6 +2099,9 @@ e_web_view_gtkhtml_set_print_proxy (EWebViewGtkHTML *web_view,
{
g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view));
+ if (web_view->priv->print_proxy == print_proxy)
+ return;
+
if (print_proxy != NULL) {
g_return_if_fail (GTK_IS_ACTION (print_proxy));
g_object_ref (print_proxy);
@@ -2093,6 +2129,9 @@ e_web_view_gtkhtml_set_save_as_proxy (EWebViewGtkHTML *web_view,
{
g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view));
+ if (web_view->priv->save_as_proxy == save_as_proxy)
+ return;
+
if (save_as_proxy != NULL) {
g_return_if_fail (GTK_IS_ACTION (save_as_proxy));
g_object_ref (save_as_proxy);
diff --git a/e-util/e-web-view.c b/e-util/e-web-view.c
index bb02bd16f1..398540128d 100644
--- a/e-util/e-web-view.c
+++ b/e-util/e-web-view.c
@@ -1699,7 +1699,7 @@ e_web_view_init (EWebView *web_view)
web_view, "document-load-finished",
G_CALLBACK (style_updated_cb), NULL);
- g_signal_connect (
+ e_signal_connect_notify (
web_view, "notify::load-status",
G_CALLBACK (web_view_load_status_changed_cb), NULL);