aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2014-06-05 17:47:13 +0800
committerMilan Crha <mcrha@redhat.com>2014-06-05 17:47:13 +0800
commit2e71c861438a25ceac5811d9d3aa528691e71410 (patch)
tree88acf6b67904de4caae1034cebb7c040f3fab804
parent2f3fbdd6c6ff42a6c71ebe1d1d78108affe59d0f (diff)
downloadgsoc2013-evolution-2e71c861438a25ceac5811d9d3aa528691e71410.tar
gsoc2013-evolution-2e71c861438a25ceac5811d9d3aa528691e71410.tar.gz
gsoc2013-evolution-2e71c861438a25ceac5811d9d3aa528691e71410.tar.bz2
gsoc2013-evolution-2e71c861438a25ceac5811d9d3aa528691e71410.tar.lz
gsoc2013-evolution-2e71c861438a25ceac5811d9d3aa528691e71410.tar.xz
gsoc2013-evolution-2e71c861438a25ceac5811d9d3aa528691e71410.tar.zst
gsoc2013-evolution-2e71c861438a25ceac5811d9d3aa528691e71410.zip
Properly disconnect signal handlers added with e_signal_connect_notify*()
This is a follow-up for the previous commit, where e_signal_connect_notify*() functions had been added. Due to a different callback and user data being attached to the 'notify' signal, the g_signal_handlers_*() functions do not work properly, thus these e_signal_connect_notify*() functions need a different way for a signal handler disconnect. A side-change was done in e-settings-web-view-gtkhtml.c, checking for a real key change from GSettings.
-rw-r--r--calendar/gui/e-meeting-time-sel.c5
-rw-r--r--calendar/gui/e-task-table.c22
-rw-r--r--calendar/gui/e-week-view.c10
-rw-r--r--calendar/gui/gnome-cal.c5
-rw-r--r--e-util/e-activity-bar.c2
-rw-r--r--e-util/e-activity-proxy.c2
-rw-r--r--e-util/e-buffer-tagger.c2
-rw-r--r--e-util/e-category-completion.c11
-rw-r--r--e-util/e-misc-utils.c65
-rw-r--r--e-util/e-misc-utils.h3
-rw-r--r--e-util/e-table-group-leaf.c6
-rw-r--r--e-util/e-table-group-leaf.h2
-rw-r--r--e-util/e-tree.c4
-rw-r--r--mail/e-mail-display.c12
-rw-r--r--modules/settings/e-settings-web-view-gtkhtml.c24
-rw-r--r--plugins/publish-calendar/publish-calendar.c6
16 files changed, 151 insertions, 30 deletions
diff --git a/calendar/gui/e-meeting-time-sel.c b/calendar/gui/e-meeting-time-sel.c
index 9bea92f2dc..3caf71795d 100644
--- a/calendar/gui/e-meeting-time-sel.c
+++ b/calendar/gui/e-meeting-time-sel.c
@@ -47,6 +47,7 @@
struct _EMeetingTimeSelectorPrivate {
gboolean use_24_hour_format;
+ gulong notify_free_busy_template_id;
};
/* An array of hour strings for 24 hour time, "0:00" .. "23:00". */
@@ -251,6 +252,8 @@ meeting_time_selector_dispose (GObject *object)
g_signal_handlers_disconnect_matched (
mts->model, G_SIGNAL_MATCH_DATA,
0, 0, NULL, NULL, mts);
+ e_signal_disconnect_notify_handler (mts->model, &mts->priv->notify_free_busy_template_id);
+
g_object_unref (mts->model);
mts->model = NULL;
}
@@ -396,7 +399,7 @@ e_meeting_time_selector_construct (EMeetingTimeSelector *mts,
if (mts->model)
g_object_ref (mts->model);
- e_signal_connect_notify_swapped (
+ mts->priv->notify_free_busy_template_id = e_signal_connect_notify_swapped (
mts->model, "notify::free-busy-template",
G_CALLBACK (free_busy_template_changed_cb), mts);
diff --git a/calendar/gui/e-task-table.c b/calendar/gui/e-task-table.c
index 10184ef725..0370997c32 100644
--- a/calendar/gui/e-task-table.c
+++ b/calendar/gui/e-task-table.c
@@ -58,6 +58,11 @@ struct _ETaskTablePrivate {
GtkTargetList *copy_target_list;
GtkTargetList *paste_target_list;
+
+ gulong notify_highlight_due_today_id;
+ gulong notify_color_due_today_id;
+ gulong notify_highlight_overdue_id;
+ gulong notify_color_overdue_id;
};
enum {
@@ -315,26 +320,25 @@ task_table_set_model (ETaskTable *task_table,
task_table);
/* redraw on drawing options change */
- e_signal_connect_notify (
+ task_table->priv->notify_highlight_due_today_id = e_signal_connect_notify (
model, "notify::highlight-due-today",
G_CALLBACK (task_table_queue_draw_cb),
task_table);
- e_signal_connect_notify (
+ task_table->priv->notify_color_due_today_id = e_signal_connect_notify (
model, "notify::color-due-today",
G_CALLBACK (task_table_queue_draw_cb),
task_table);
- e_signal_connect_notify (
+ task_table->priv->notify_highlight_overdue_id = e_signal_connect_notify (
model, "notify::highlight-overdue",
G_CALLBACK (task_table_queue_draw_cb),
task_table);
- e_signal_connect_notify (
+ task_table->priv->notify_color_overdue_id = e_signal_connect_notify (
model, "notify::color-overdue",
G_CALLBACK (task_table_queue_draw_cb),
task_table);
-
}
static void
@@ -428,7 +432,13 @@ task_table_dispose (GObject *object)
}
if (priv->model != NULL) {
- g_signal_handlers_disconnect_by_func (priv->model, task_table_queue_draw_cb, object);
+ g_signal_handlers_disconnect_by_data (priv->model, object);
+
+ e_signal_disconnect_notify_handler (priv->model, &priv->notify_highlight_due_today_id);
+ e_signal_disconnect_notify_handler (priv->model, &priv->notify_color_due_today_id);
+ e_signal_disconnect_notify_handler (priv->model, &priv->notify_highlight_overdue_id);
+ e_signal_disconnect_notify_handler (priv->model, &priv->notify_color_overdue_id);
+
g_object_unref (priv->model);
priv->model = NULL;
}
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index 21ec0229f4..f3343d9e5d 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -102,6 +102,8 @@ struct _EWeekViewPrivate {
* week_start_day, but if the Sat & Sun are compressed and the
* week starts on Sunday then we have to use Saturday. */
GDateWeekday display_start_day;
+
+ gulong notify_week_start_day_id;
};
typedef struct {
@@ -724,8 +726,10 @@ week_view_dispose (GObject *object)
e_week_view_cancel_layout (week_view);
- if (model)
+ if (model) {
g_signal_handlers_disconnect_by_data (model, object);
+ e_signal_disconnect_notify_handler (model, &week_view->priv->notify_week_start_day_id);
+ }
if (week_view->events) {
e_week_view_free_events (week_view);
@@ -761,18 +765,20 @@ week_view_dispose (GObject *object)
static void
week_view_constructed (GObject *object)
{
+ EWeekView *week_view;
ECalModel *model;
ECalendarView *calendar_view;
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (e_week_view_parent_class)->constructed (object);
+ week_view = E_WEEK_VIEW (object);
calendar_view = E_CALENDAR_VIEW (object);
model = e_calendar_view_get_model (calendar_view);
e_week_view_recalc_display_start_day (E_WEEK_VIEW (object));
- e_signal_connect_notify_swapped (
+ week_view->priv->notify_week_start_day_id = e_signal_connect_notify_swapped (
model, "notify::week-start-day",
G_CALLBACK (week_view_notify_week_start_day_cb), object);
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index 58877dc87d..dd89119c72 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -123,6 +123,8 @@ struct _GnomeCalendarPrivate {
gboolean lview_select_daten_range;
GCancellable *cancellable;
+
+ gulong notify_week_start_day_id;
};
struct _ViewData {
@@ -591,7 +593,7 @@ gnome_calendar_constructed (GObject *object)
calendar_view, "selection-changed",
G_CALLBACK (view_selection_changed_cb), gcal);
- e_signal_connect_notify_swapped (
+ gcal->priv->notify_week_start_day_id = e_signal_connect_notify_swapped (
model, "notify::week-start-day",
G_CALLBACK (gnome_calendar_notify_week_start_day_cb), gcal);
@@ -1575,6 +1577,7 @@ gnome_calendar_do_dispose (GObject *object)
if (priv->model != NULL) {
g_signal_handlers_disconnect_by_data (priv->model, object);
+ e_signal_disconnect_notify_handler (priv->model, &priv->notify_week_start_day_id);
g_object_unref (priv->model);
priv->model = NULL;
}
diff --git a/e-util/e-activity-bar.c b/e-util/e-activity-bar.c
index f90e51df94..795ece505c 100644
--- a/e-util/e-activity-bar.c
+++ b/e-util/e-activity-bar.c
@@ -389,7 +389,7 @@ e_activity_bar_set_activity (EActivityBar *bar,
G_OBJECT (activity), (GWeakNotify)
activity_bar_weak_notify_cb, bar);
- e_signal_connect_notify_swapped (
+ g_signal_connect_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 bb21a5bc8a..f3a452b5af 100644
--- a/e-util/e-activity-proxy.c
+++ b/e-util/e-activity-proxy.c
@@ -362,7 +362,7 @@ e_activity_proxy_set_activity (EActivityProxy *proxy,
G_OBJECT (activity), (GWeakNotify)
activity_proxy_weak_notify_cb, proxy);
- e_signal_connect_notify_swapped (
+ g_signal_connect_swapped (
activity, "notify::state",
G_CALLBACK (activity_proxy_feedback), proxy);
diff --git a/e-util/e-buffer-tagger.c b/e-util/e-buffer-tagger.c
index ccd23dc158..c3c923aa7b 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);
- e_signal_connect_notify (
+ g_signal_connect (
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 39e26e2edf..8210f72f60 100644
--- a/e-util/e-category-completion.c
+++ b/e-util/e-category-completion.c
@@ -35,6 +35,9 @@ struct _ECategoryCompletionPrivate {
GtkWidget *last_known_entry;
gchar *create;
gchar *prefix;
+
+ gulong notify_cursor_position_id;
+ gulong notify_text_id;
};
enum {
@@ -346,6 +349,8 @@ category_completion_track_entry (GtkEntryCompletion *completion)
g_signal_handlers_disconnect_matched (
priv->last_known_entry, G_SIGNAL_MATCH_DATA,
0, 0, NULL, NULL, completion);
+ e_signal_disconnect_notify_handler (priv->last_known_entry, &priv->notify_cursor_position_id);
+ e_signal_disconnect_notify_handler (priv->last_known_entry, &priv->notify_text_id);
g_object_unref (priv->last_known_entry);
}
@@ -358,11 +363,11 @@ category_completion_track_entry (GtkEntryCompletion *completion)
g_object_ref (priv->last_known_entry);
- e_signal_connect_notify_swapped (
+ priv->notify_cursor_position_id = e_signal_connect_notify_swapped (
priv->last_known_entry, "notify::cursor-position",
G_CALLBACK (category_completion_update_prefix), completion);
- e_signal_connect_notify_swapped (
+ priv->notify_text_id = e_signal_connect_notify_swapped (
priv->last_known_entry, "notify::text",
G_CALLBACK (category_completion_update_prefix), completion);
@@ -417,6 +422,8 @@ category_completion_dispose (GObject *object)
g_signal_handlers_disconnect_matched (
priv->last_known_entry, G_SIGNAL_MATCH_DATA,
0, 0, NULL, NULL, object);
+ e_signal_disconnect_notify_handler (priv->last_known_entry, &priv->notify_cursor_position_id);
+ e_signal_disconnect_notify_handler (priv->last_known_entry, &priv->notify_text_id);
g_object_unref (priv->last_known_entry);
priv->last_known_entry = NULL;
}
diff --git a/e-util/e-misc-utils.c b/e-util/e-misc-utils.c
index f7be7af5ac..510dad39b2 100644
--- a/e-util/e-misc-utils.c
+++ b/e-util/e-misc-utils.c
@@ -2394,6 +2394,16 @@ e_signal_connect_notify_cb (gpointer instance,
}
}
+/**
+ * e_signal_connect_notify:
+ *
+ * This installs a special handler in front of @c_handler, which will
+ * call the @c_handler only if the property value changed since the last
+ * time it was checked. Due to this, these handlers cannot be disconnected
+ * by by any of the g_signal_handlers_* functions, but only with the returned
+ * handler ID. A convenient e_signal_disconnect_notify_handler() was added
+ * to make it easier.
+ **/
gulong
e_signal_connect_notify (gpointer instance,
const gchar *notify_name,
@@ -2414,6 +2424,16 @@ e_signal_connect_notify (gpointer instance,
0);
}
+/**
+ * e_signal_connect_notify_after:
+ *
+ * This installs a special handler in front of @c_handler, which will
+ * call the @c_handler only if the property value changed since the last
+ * time it was checked. Due to this, these handlers cannot be disconnected
+ * by by any of the g_signal_handlers_* functions, but only with the returned
+ * handler ID. A convenient e_signal_disconnect_notify_handler() was added
+ * to make it easier.
+ **/
gulong
e_signal_connect_notify_after (gpointer instance,
const gchar *notify_name,
@@ -2434,6 +2454,16 @@ e_signal_connect_notify_after (gpointer instance,
G_CONNECT_AFTER);
}
+/**
+ * e_signal_connect_notify_swapped:
+ *
+ * This installs a special handler in front of @c_handler, which will
+ * call the @c_handler only if the property value changed since the last
+ * time it was checked. Due to this, these handlers cannot be disconnected
+ * by by any of the g_signal_handlers_* functions, but only with the returned
+ * handler ID. A convenient e_signal_disconnect_notify_handler() was added
+ * to make it easier.
+ **/
gulong
e_signal_connect_notify_swapped (gpointer instance,
const gchar *notify_name,
@@ -2454,6 +2484,16 @@ e_signal_connect_notify_swapped (gpointer instance,
0);
}
+/**
+ * e_signal_connect_notify_object:
+ *
+ * This installs a special handler in front of @c_handler, which will
+ * call the @c_handler only if the property value changed since the last
+ * time it was checked. Due to this, these handlers cannot be disconnected
+ * by by any of the g_signal_handlers_* functions, but only with the returned
+ * handler ID. A convenient e_signal_disconnect_notify_handler() was added
+ * to make it easier.
+ **/
gulong
e_signal_connect_notify_object (gpointer instance,
const gchar *notify_name,
@@ -2492,3 +2532,28 @@ e_signal_connect_notify_object (gpointer instance,
closure,
connect_flags & G_CONNECT_AFTER);
}
+
+/**
+ * e_signal_disconnect_notify_handler:
+ *
+ * Convenient handler disconnect function to be used with
+ * returned handler IDs from:
+ * e_signal_connect_notify()
+ * e_signal_connect_notify_after()
+ * e_signal_connect_notify_swapped()
+ * e_signal_connect_notify_object()
+ * but not necessarily only with these functions.
+ **/
+void
+e_signal_disconnect_notify_handler (gpointer instance,
+ gulong *handler_id)
+{
+ g_return_if_fail (instance != NULL);
+ g_return_if_fail (handler_id != NULL);
+
+ if (!*handler_id)
+ return;
+
+ g_signal_handler_disconnect (instance, *handler_id);
+ *handler_id = 0;
+}
diff --git a/e-util/e-misc-utils.h b/e-util/e-misc-utils.h
index 06de228899..ebc860b91e 100644
--- a/e-util/e-misc-utils.h
+++ b/e-util/e-misc-utils.h
@@ -228,6 +228,9 @@ gulong e_signal_connect_notify_object (gpointer instance,
GCallback c_handler,
gpointer gobject,
GConnectFlags connect_flags);
+void e_signal_disconnect_notify_handler
+ (gpointer instance,
+ gulong *handler_id);
G_END_DECLS
diff --git a/e-util/e-table-group-leaf.c b/e-util/e-table-group-leaf.c
index 88ea6b0e8d..ffdb8b94bc 100644
--- a/e-util/e-table-group-leaf.c
+++ b/e-util/e-table-group-leaf.c
@@ -108,9 +108,7 @@ etgl_dispose (GObject *object)
etgl->item,
etgl->etgl_start_drag_id);
- g_signal_handlers_disconnect_by_func (
- etgl->item,
- etgl_item_is_editing_changed_cb, etgl);
+ e_signal_disconnect_notify_handler (etgl->item, &etgl->notify_is_editing_id);
etgl->etgl_cursor_change_id = 0;
etgl->etgl_cursor_activated_id = 0;
@@ -368,7 +366,7 @@ etgl_realize (GnomeCanvasItem *item)
etgl->item, "start_drag",
G_CALLBACK (etgl_start_drag), etgl);
- e_signal_connect_notify (
+ etgl->notify_is_editing_id = 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-group-leaf.h b/e-util/e-table-group-leaf.h
index e4fcbedee8..c911890829 100644
--- a/e-util/e-table-group-leaf.h
+++ b/e-util/e-table-group-leaf.h
@@ -90,6 +90,8 @@ struct _ETableGroupLeaf {
gint etgl_start_drag_id;
ESelectionModel *selection_model;
+
+ gulong notify_is_editing_id;
};
struct _ETableGroupLeafClass {
diff --git a/e-util/e-tree.c b/e-util/e-tree.c
index 30d20fc4c8..697e88c800 100644
--- a/e-util/e-tree.c
+++ b/e-util/e-tree.c
@@ -1283,7 +1283,7 @@ et_setup_table_canvas_vadjustment (ETree *tree)
if (vadjustment) {
tree->priv->table_canvas_vadjustment = g_object_ref (vadjustment);
- e_signal_connect_notify (
+ g_signal_connect (
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);
- e_signal_connect_notify_swapped (
+ g_signal_connect_swapped (
tree->priv->table_canvas, "notify::vadjustment",
G_CALLBACK (et_setup_table_canvas_vadjustment), tree);
diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c
index fe91faab9a..5dc02860c7 100644
--- a/mail/e-mail-display.c
+++ b/mail/e-mail-display.c
@@ -606,18 +606,18 @@ mail_display_plugin_widget_requested (WebKitWebView *web_view,
/* When EAttachmentBar is expanded/collapsed it does not
* emit size-allocate signal despite it changes it's height. */
- e_signal_connect_notify (
+ g_signal_connect (
widget, "notify::expanded",
G_CALLBACK (mail_display_plugin_widget_resize),
display);
- e_signal_connect_notify (
+ g_signal_connect (
widget, "notify::active-view",
G_CALLBACK (mail_display_plugin_widget_resize),
display);
/* Always hide an attachment bar without attachments */
store = e_attachment_bar_get_store (E_ATTACHMENT_BAR (widget));
- e_signal_connect_notify (
+ g_signal_connect (
store, "notify::num-attachments",
G_CALLBACK (mail_display_attachment_count_changed),
box);
@@ -668,11 +668,11 @@ mail_display_plugin_widget_requested (WebKitWebView *web_view,
/* Show/hide the attachment when the EAttachmentButton
* is expanded/collapsed or shown/hidden. */
- e_signal_connect_notify (
+ g_signal_connect (
widget, "notify::expanded",
G_CALLBACK (attachment_button_expanded),
display);
- e_signal_connect_notify (
+ g_signal_connect (
widget, "notify::visible",
G_CALLBACK (attachment_button_expanded),
display);
@@ -994,7 +994,7 @@ mail_display_frame_created (WebKitWebView *web_view,
d (printf ("Frame %s created!\n", webkit_web_frame_get_name (frame)));
/* Call bind_func of all parts written in this frame */
- e_signal_connect_notify (
+ g_signal_connect (
frame, "notify::load-status",
G_CALLBACK (mail_parts_bind_dom), NULL);
}
diff --git a/modules/settings/e-settings-web-view-gtkhtml.c b/modules/settings/e-settings-web-view-gtkhtml.c
index b551b3e881..7815eb6a17 100644
--- a/modules/settings/e-settings-web-view-gtkhtml.c
+++ b/modules/settings/e-settings-web-view-gtkhtml.c
@@ -33,6 +33,7 @@
struct _ESettingsWebViewGtkHTMLPrivate {
GtkCssProvider *css_provider;
GSettings *settings;
+ GHashTable *old_values;
};
G_DEFINE_DYNAMIC_TYPE (
@@ -148,7 +149,21 @@ settings_web_view_gtkhtml_changed_cb (GSettings *settings,
const gchar *key,
ESettingsWebViewGtkHTML *extension)
{
- settings_web_view_gtkhtml_load_style (extension);
+ GVariant *new_value, *old_value;
+
+ new_value = g_settings_get_value (settings, key);
+ old_value = g_hash_table_lookup (extension->priv->old_values, key);
+
+ if (!new_value || !old_value || !g_variant_equal (new_value, old_value)) {
+ if (new_value)
+ g_hash_table_insert (extension->priv->old_values, g_strdup (key), new_value);
+ else
+ g_hash_table_remove (extension->priv->old_values, key);
+
+ settings_web_view_gtkhtml_load_style (extension);
+ } else if (new_value) {
+ g_variant_unref (new_value);
+ }
}
static void
@@ -227,6 +242,11 @@ settings_web_view_gtkhtml_dispose (GObject *object)
settings_web_view_gtkhtml_changed_cb, object);
}
+ if (priv->old_values) {
+ g_hash_table_destroy (priv->old_values);
+ priv->old_values = NULL;
+ }
+
g_clear_object (&priv->css_provider);
g_clear_object (&priv->settings);
@@ -289,6 +309,8 @@ e_settings_web_view_gtkhtml_init (ESettingsWebViewGtkHTML *extension)
settings = g_settings_new ("org.gnome.evolution.mail");
extension->priv->settings = settings;
+
+ extension->priv->old_values = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
}
void
diff --git a/plugins/publish-calendar/publish-calendar.c b/plugins/publish-calendar/publish-calendar.c
index 1eceaa0dd2..f48f1af10e 100644
--- a/plugins/publish-calendar/publish-calendar.c
+++ b/plugins/publish-calendar/publish-calendar.c
@@ -1006,10 +1006,12 @@ e_plugin_lib_enable (EPlugin *ep,
EShell *shell = e_shell_get_default ();
if (shell) {
- g_signal_handlers_disconnect_by_func (shell, G_CALLBACK (online_state_changed), NULL);
+ static gulong notify_online_id = 0;
+
+ e_signal_disconnect_notify_handler (shell, &notify_online_id);
if (enable) {
online = e_shell_get_online (shell);
- e_signal_connect_notify (
+ notify_online_id = e_signal_connect_notify (
shell, "notify::online",
G_CALLBACK (online_state_changed), NULL);
}