diff --git a/gtk/gtkcellarea.c b/gtk/gtkcellarea.c index 40a5c9eaa3..9e770d69c7 100644 --- a/gtk/gtkcellarea.c +++ b/gtk/gtkcellarea.c @@ -497,6 +497,7 @@ typedef struct { GtkCellLayoutDataFunc func; gpointer data; GDestroyNotify destroy; + GtkCellLayout *proxy; } CellInfo; static CellInfo *cell_info_new (GtkCellLayoutDataFunc func, @@ -1208,8 +1209,8 @@ apply_cell_attributes (GtkCellRenderer *renderer, /* Call any GtkCellLayoutDataFunc that may have been set by the user */ if (info->func) - info->func (GTK_CELL_LAYOUT (data->area), renderer, - data->model, data->iter, info->data); + info->func (info->proxy ? info->proxy : GTK_CELL_LAYOUT (data->area), renderer, + data->model, data->iter, info->data); g_object_thaw_notify (G_OBJECT (renderer)); } @@ -1419,36 +1420,9 @@ gtk_cell_area_set_cell_data_func (GtkCellLayout *cell_layout, gpointer func_data, GDestroyNotify destroy) { - GtkCellArea *area = GTK_CELL_AREA (cell_layout); - GtkCellAreaPrivate *priv = area->priv; - CellInfo *info; + GtkCellArea *area = GTK_CELL_AREA (cell_layout); - info = g_hash_table_lookup (priv->cell_info, renderer); - - if (info) - { - if (info->destroy && info->data) - info->destroy (info->data); - - if (func) - { - info->func = func; - info->data = func_data; - info->destroy = destroy; - } - else - { - info->func = NULL; - info->data = NULL; - info->destroy = NULL; - } - } - else - { - info = cell_info_new (func, func_data, destroy); - - g_hash_table_insert (priv->cell_info, renderer, info); - } + _gtk_cell_area_set_cell_data_func_with_proxy (area, renderer, (GFunc)func, func_data, destroy, NULL); } static void @@ -3636,3 +3610,53 @@ gtk_cell_area_request_renderer (GtkCellArea *area, *minimum_size += focus_line_width; *natural_size += focus_line_width; } + +void +_gtk_cell_area_set_cell_data_func_with_proxy (GtkCellArea *area, + GtkCellRenderer *cell, + GFunc func, + gpointer func_data, + GDestroyNotify destroy, + gpointer proxy) +{ + GtkCellAreaPrivate *priv; + CellInfo *info; + + g_return_if_fail (GTK_IS_CELL_AREA (area)); + g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); + + priv = area->priv; + + info = g_hash_table_lookup (priv->cell_info, cell); + + /* Note we do not take a reference to the proxy, the proxy is a GtkCellLayout + * that is forwarding it's implementation to a delegate GtkCellArea therefore + * it's life-cycle is longer than the area's life cycle. + */ + if (info) + { + if (info->destroy && info->data) + info->destroy (info->data); + + if (func) + { + info->func = (GtkCellLayoutDataFunc)func; + info->data = func_data; + info->destroy = destroy; + info->proxy = proxy; + } + else + { + info->func = NULL; + info->data = NULL; + info->destroy = NULL; + info->proxy = NULL; + } + } + else + { + info = cell_info_new ((GtkCellLayoutDataFunc)func, func_data, destroy); + + g_hash_table_insert (priv->cell_info, cell, info); + } +} diff --git a/gtk/gtkcellarea.h b/gtk/gtkcellarea.h index d8d06cfecc..78d5e95450 100644 --- a/gtk/gtkcellarea.h +++ b/gtk/gtkcellarea.h @@ -470,6 +470,19 @@ void gtk_cell_area_request_renderer (GtkCellArea gint *minimum_size, gint *natural_size); +/* For api stability, this is called from gtkcelllayout.c in order to ensure the correct + * object is passed to the user function in gtk_cell_layout_set_cell_data_func. + * + * This private api takes gpointer & GFunc arguments to circumvent circular header file + * dependancies. + */ +void _gtk_cell_area_set_cell_data_func_with_proxy (GtkCellArea *area, + GtkCellRenderer *cell, + GFunc func, + gpointer func_data, + GDestroyNotify destroy, + gpointer proxy); + G_END_DECLS #endif /* __GTK_CELL_AREA_H__ */ diff --git a/gtk/gtkcelllayout.c b/gtk/gtkcelllayout.c index c54a8753b5..5a0ae592f5 100644 --- a/gtk/gtkcelllayout.c +++ b/gtk/gtkcelllayout.c @@ -357,7 +357,16 @@ gtk_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout, area = iface->get_area (cell_layout); if (area) - gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (area), cell, func, func_data, destroy); + { + /* Ensure that the correct proxy object is sent to 'func' */ + if (GTK_CELL_LAYOUT (area) != cell_layout) + _gtk_cell_area_set_cell_data_func_with_proxy (area, cell, + (GFunc)func, func_data, destroy, + cell_layout); + else + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (area), cell, + func, func_data, destroy); + } } }