[master/rhel7] Fix crashes in the LayoutIndicator dispose function.
David Shea
dshea at redhat.com
Thu Feb 6 10:29:18 UTC 2014
dispose can be called multiple times, so we need to indicate that the
signal handlers on the XklEngine are unset, lest a second call to
dispose cause a segfault. Also, dispose always needs to call the parent
class's dispose.
Resolves: rhbz#1061206
---
widgets/src/LayoutIndicator.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/widgets/src/LayoutIndicator.c b/widgets/src/LayoutIndicator.c
index e1797f7..e3d4039 100644
--- a/widgets/src/LayoutIndicator.c
+++ b/widgets/src/LayoutIndicator.c
@@ -59,7 +59,9 @@ struct _AnacondaLayoutIndicatorPrivate {
GdkCursor *cursor;
XklConfigRec *config_rec;
gulong state_changed_handler_id;
+ gboolean state_changed_handler_id_set;
gulong config_changed_handler_id;
+ gboolean config_changed_handler_id_set;
};
G_DEFINE_TYPE(AnacondaLayoutIndicator, anaconda_layout_indicator, GTK_TYPE_EVENT_BOX)
@@ -198,9 +200,11 @@ static void anaconda_layout_indicator_init(AnacondaLayoutIndicator *self) {
self->priv->state_changed_handler_id = g_signal_connect(klass->engine, "X-state-changed",
G_CALLBACK(x_state_changed),
g_object_ref(self));
+ self->priv->state_changed_handler_id_set = TRUE;
self->priv->config_changed_handler_id = g_signal_connect(klass->engine, "X-config-changed",
G_CALLBACK(x_config_changed),
g_object_ref(self));
+ self->priv->config_changed_handler_id_set = TRUE;
/* init layout attribute with the current layout */
self->priv->layout = get_current_layout(klass->engine, self->priv->config_rec);
@@ -238,8 +242,17 @@ static void anaconda_layout_indicator_dispose(GObject *object) {
AnacondaLayoutIndicatorClass *klass = ANACONDA_LAYOUT_INDICATOR_GET_CLASS(self);
/* disconnect signals (XklEngine will outlive us) */
- g_signal_handler_disconnect(klass->engine, self->priv->state_changed_handler_id);
- g_signal_handler_disconnect(klass->engine, self->priv->config_changed_handler_id);
+ if (self->priv->state_changed_handler_id_set)
+ {
+ g_signal_handler_disconnect(klass->engine, self->priv->state_changed_handler_id);
+ self->priv->state_changed_handler_id_set = FALSE;
+ }
+
+ if (self->priv->config_changed_handler_id_set)
+ {
+ g_signal_handler_disconnect(klass->engine, self->priv->config_changed_handler_id);
+ self->priv->config_changed_handler_id_set = FALSE;
+ }
/* unref all objects we reference (may be called multiple times) */
if (self->priv->layout_label) {
@@ -258,6 +271,8 @@ static void anaconda_layout_indicator_dispose(GObject *object) {
g_free(self->priv->layout);
self->priv->layout = NULL;
}
+
+ G_OBJECT_CLASS(anaconda_layout_indicator_parent_class)->dispose(object);
}
static void anaconda_layout_indicator_realize(GtkWidget *widget, gpointer data) {
--
1.8.5.3
More information about the anaconda-patches
mailing list