printers: Don't crash after changing an option
Use GCancellable when setting a new value of an option. This prevents Printers panel from crash caused by calling of option widget's callback on finalized widget. https://bugzilla.gnome.org/show_bug.cgi?id=694874
This commit is contained in:
parent
affe13b180
commit
76d18ec85d
3 changed files with 68 additions and 7 deletions
|
@ -52,6 +52,8 @@ struct PpIPPOptionWidgetPrivate
|
||||||
gchar *option_name;
|
gchar *option_name;
|
||||||
|
|
||||||
GHashTable *ipp_attribute;
|
GHashTable *ipp_attribute;
|
||||||
|
|
||||||
|
GCancellable *cancellable;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (PpIPPOptionWidget, pp_ipp_option_widget, GTK_TYPE_HBOX)
|
G_DEFINE_TYPE (PpIPPOptionWidget, pp_ipp_option_widget, GTK_TYPE_HBOX)
|
||||||
|
@ -163,6 +165,12 @@ pp_ipp_option_widget_finalize (GObject *object)
|
||||||
g_hash_table_unref (priv->ipp_attribute);
|
g_hash_table_unref (priv->ipp_attribute);
|
||||||
priv->ipp_attribute = NULL;
|
priv->ipp_attribute = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->cancellable)
|
||||||
|
{
|
||||||
|
g_cancellable_cancel (priv->cancellable);
|
||||||
|
g_object_unref (priv->cancellable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (pp_ipp_option_widget_parent_class)->finalize (object);
|
G_OBJECT_CLASS (pp_ipp_option_widget_parent_class)->finalize (object);
|
||||||
|
@ -308,7 +316,11 @@ static void
|
||||||
printer_add_option_async_cb (gboolean success,
|
printer_add_option_async_cb (gboolean success,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
PpIPPOptionWidget *widget = (PpIPPOptionWidget *) user_data;
|
||||||
|
PpIPPOptionWidgetPrivate *priv = widget->priv;
|
||||||
|
|
||||||
update_widget (user_data);
|
update_widget (user_data);
|
||||||
|
g_clear_object (&priv->cancellable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -326,11 +338,18 @@ switch_changed_cb (GtkWidget *switch_button,
|
||||||
else
|
else
|
||||||
values[0] = g_strdup ("False");
|
values[0] = g_strdup ("False");
|
||||||
|
|
||||||
|
if (priv->cancellable)
|
||||||
|
{
|
||||||
|
g_cancellable_cancel (priv->cancellable);
|
||||||
|
g_object_unref (priv->cancellable);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->cancellable = g_cancellable_new ();
|
||||||
printer_add_option_async (priv->printer_name,
|
printer_add_option_async (priv->printer_name,
|
||||||
priv->option_name,
|
priv->option_name,
|
||||||
values,
|
values,
|
||||||
TRUE,
|
TRUE,
|
||||||
NULL,
|
priv->cancellable,
|
||||||
printer_add_option_async_cb,
|
printer_add_option_async_cb,
|
||||||
widget);
|
widget);
|
||||||
|
|
||||||
|
@ -347,11 +366,18 @@ combo_changed_cb (GtkWidget *combo,
|
||||||
values = g_new0 (gchar *, 2);
|
values = g_new0 (gchar *, 2);
|
||||||
values[0] = combo_box_get (combo);
|
values[0] = combo_box_get (combo);
|
||||||
|
|
||||||
|
if (priv->cancellable)
|
||||||
|
{
|
||||||
|
g_cancellable_cancel (priv->cancellable);
|
||||||
|
g_object_unref (priv->cancellable);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->cancellable = g_cancellable_new ();
|
||||||
printer_add_option_async (priv->printer_name,
|
printer_add_option_async (priv->printer_name,
|
||||||
priv->option_name,
|
priv->option_name,
|
||||||
values,
|
values,
|
||||||
TRUE,
|
TRUE,
|
||||||
NULL,
|
priv->cancellable,
|
||||||
printer_add_option_async_cb,
|
printer_add_option_async_cb,
|
||||||
widget);
|
widget);
|
||||||
|
|
||||||
|
@ -368,11 +394,18 @@ spin_button_changed_cb (GtkWidget *spin_button,
|
||||||
values = g_new0 (gchar *, 2);
|
values = g_new0 (gchar *, 2);
|
||||||
values[0] = g_strdup_printf ("%d", gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin_button)));
|
values[0] = g_strdup_printf ("%d", gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin_button)));
|
||||||
|
|
||||||
|
if (priv->cancellable)
|
||||||
|
{
|
||||||
|
g_cancellable_cancel (priv->cancellable);
|
||||||
|
g_object_unref (priv->cancellable);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->cancellable = g_cancellable_new ();
|
||||||
printer_add_option_async (priv->printer_name,
|
printer_add_option_async (priv->printer_name,
|
||||||
priv->option_name,
|
priv->option_name,
|
||||||
values,
|
values,
|
||||||
TRUE,
|
TRUE,
|
||||||
NULL,
|
priv->cancellable,
|
||||||
printer_add_option_async_cb,
|
printer_add_option_async_cb,
|
||||||
widget);
|
widget);
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,8 @@ struct PpPPDOptionWidgetPrivate
|
||||||
|
|
||||||
gchar *ppd_filename;
|
gchar *ppd_filename;
|
||||||
gboolean ppd_filename_set;
|
gboolean ppd_filename_set;
|
||||||
|
|
||||||
|
GCancellable *cancellable;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (PpPPDOptionWidget, pp_ppd_option_widget, GTK_TYPE_HBOX)
|
G_DEFINE_TYPE (PpPPDOptionWidget, pp_ppd_option_widget, GTK_TYPE_HBOX)
|
||||||
|
@ -203,6 +205,12 @@ pp_ppd_option_widget_finalize (GObject *object)
|
||||||
g_free (priv->ppd_filename);
|
g_free (priv->ppd_filename);
|
||||||
priv->ppd_filename = NULL;
|
priv->ppd_filename = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->cancellable)
|
||||||
|
{
|
||||||
|
g_cancellable_cancel (priv->cancellable);
|
||||||
|
g_object_unref (priv->cancellable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (pp_ppd_option_widget_parent_class)->finalize (object);
|
G_OBJECT_CLASS (pp_ppd_option_widget_parent_class)->finalize (object);
|
||||||
|
@ -361,7 +369,11 @@ static void
|
||||||
printer_add_option_async_cb (gboolean success,
|
printer_add_option_async_cb (gboolean success,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
PpPPDOptionWidget *widget = (PpPPDOptionWidget *) user_data;
|
||||||
|
PpPPDOptionWidgetPrivate *priv = widget->priv;
|
||||||
|
|
||||||
update_widget (user_data);
|
update_widget (user_data);
|
||||||
|
g_clear_object (&priv->cancellable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -379,11 +391,18 @@ switch_changed_cb (GtkWidget *switch_button,
|
||||||
else
|
else
|
||||||
values[0] = g_strdup ("False");
|
values[0] = g_strdup ("False");
|
||||||
|
|
||||||
|
if (priv->cancellable)
|
||||||
|
{
|
||||||
|
g_cancellable_cancel (priv->cancellable);
|
||||||
|
g_object_unref (priv->cancellable);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->cancellable = g_cancellable_new ();
|
||||||
printer_add_option_async (priv->printer_name,
|
printer_add_option_async (priv->printer_name,
|
||||||
priv->option_name,
|
priv->option_name,
|
||||||
values,
|
values,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL,
|
priv->cancellable,
|
||||||
printer_add_option_async_cb,
|
printer_add_option_async_cb,
|
||||||
widget);
|
widget);
|
||||||
|
|
||||||
|
@ -400,11 +419,18 @@ combo_changed_cb (GtkWidget *combo,
|
||||||
values = g_new0 (gchar *, 2);
|
values = g_new0 (gchar *, 2);
|
||||||
values[0] = combo_box_get (combo);
|
values[0] = combo_box_get (combo);
|
||||||
|
|
||||||
|
if (priv->cancellable)
|
||||||
|
{
|
||||||
|
g_cancellable_cancel (priv->cancellable);
|
||||||
|
g_object_unref (priv->cancellable);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->cancellable = g_cancellable_new ();
|
||||||
printer_add_option_async (priv->printer_name,
|
printer_add_option_async (priv->printer_name,
|
||||||
priv->option_name,
|
priv->option_name,
|
||||||
values,
|
values,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL,
|
priv->cancellable,
|
||||||
printer_add_option_async_cb,
|
printer_add_option_async_cb,
|
||||||
widget);
|
widget);
|
||||||
|
|
||||||
|
|
|
@ -3347,7 +3347,8 @@ printer_add_option_async_dbus_cb (GObject *source_object,
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->callback (success, data->user_data);
|
if (!g_cancellable_is_cancelled (data->cancellable))
|
||||||
|
data->callback (success, data->user_data);
|
||||||
|
|
||||||
if (data->cancellable)
|
if (data->cancellable)
|
||||||
g_object_unref (data->cancellable);
|
g_object_unref (data->cancellable);
|
||||||
|
@ -3386,7 +3387,8 @@ printer_add_option_async (const gchar *printer_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
data = g_new0 (PAOData, 1);
|
data = g_new0 (PAOData, 1);
|
||||||
data->cancellable = cancellable;
|
if (cancellable)
|
||||||
|
data->cancellable = g_object_ref (cancellable);
|
||||||
data->callback = callback;
|
data->callback = callback;
|
||||||
data->user_data = user_data;
|
data->user_data = user_data;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue