Commit 8bdff7a5 authored by Benjamin Otte's avatar Benjamin Otte

sizegroup: Construct the set of sizegroup peers as a hash table

This way we don't need a marker on GtkWidgetParivate that needs to be
unset later, so we have all our data in the same place and can avoid
problems with reentrancy and shenanigans like that.

But the main reason I wrote that is cleaner code.
parent 1ef057f9
......@@ -147,24 +147,17 @@ static void gtk_size_group_buildable_custom_finished (GtkBuildable *buildable,
gpointer user_data);
static void
mark_widget_unvisited (GtkWidget *widget)
{
_gtk_widget_set_sizegroup_visited (widget, FALSE);
}
static void
add_widget_to_closure (GtkWidget *widget,
GtkSizeGroupMode mode,
GSList **widgets)
add_widget_to_closure (GHashTable *set,
GtkWidget *widget,
GtkSizeGroupMode mode)
{
GSList *tmp_groups, *tmp_widgets;
gboolean hidden;
if (_gtk_widget_get_sizegroup_visited (widget))
if (g_hash_table_lookup (set, widget))
return;
*widgets = g_slist_prepend (*widgets, widget);
_gtk_widget_set_sizegroup_visited (widget, TRUE);
g_hash_table_insert (set, widget, widget);
hidden = !gtk_widget_is_visible (widget);
for (tmp_groups = _gtk_widget_get_sizegroups (widget); tmp_groups; tmp_groups = tmp_groups->next)
......@@ -179,18 +172,19 @@ add_widget_to_closure (GtkWidget *widget,
continue;
for (tmp_widgets = tmp_priv->widgets; tmp_widgets; tmp_widgets = tmp_widgets->next)
add_widget_to_closure (tmp_widgets->data, mode, widgets);
add_widget_to_closure (set, tmp_widgets->data, mode);
}
}
static GSList *
static GHashTable *
widget_get_size_group_peers (GtkWidget *widget,
GtkSizeGroupMode mode)
{
GSList *result = NULL;
GHashTable *result;
result = g_hash_table_new (g_direct_hash, g_direct_equal);
add_widget_to_closure (widget, mode, &result);
g_slist_foreach (result, (GFunc) mark_widget_unvisited, NULL);
add_widget_to_closure (result, widget, mode);
return result;
}
......@@ -225,12 +219,13 @@ queue_resize_on_widget (GtkWidget *widget,
GtkQueueResizeFlags flags)
{
GtkWidget *parent = widget;
GSList *tmp_list;
while (parent)
{
GSList *widget_groups;
GSList *widgets;
GHashTable *widgets;
GHashTableIter iter;
gpointer current;
if (widget == parent && !check_siblings)
{
......@@ -251,41 +246,43 @@ queue_resize_on_widget (GtkWidget *widget,
widgets = widget_get_size_group_peers (parent, GTK_SIZE_GROUP_HORIZONTAL);
for (tmp_list = widgets; tmp_list; tmp_list = tmp_list->next)
g_hash_table_iter_init (&iter, widgets);
while (g_hash_table_iter_next (&iter, &current, NULL))
{
if (tmp_list->data == parent)
if (current == parent)
{
if (widget == parent)
real_queue_resize (parent, flags);
}
else if (tmp_list->data == widget)
else if (current == widget)
{
g_warning ("A container and its child are part of this SizeGroup");
}
else
queue_resize_on_widget (tmp_list->data, FALSE, flags);
queue_resize_on_widget (current, FALSE, flags);
}
g_slist_free (widgets);
g_hash_table_destroy (widgets);
widgets = widget_get_size_group_peers (parent, GTK_SIZE_GROUP_VERTICAL);
for (tmp_list = widgets; tmp_list; tmp_list = tmp_list->next)
g_hash_table_iter_init (&iter, widgets);
while (g_hash_table_iter_next (&iter, &current, NULL))
{
if (tmp_list->data == parent)
if (current == parent)
{
if (widget == parent)
real_queue_resize (parent, flags);
}
else if (tmp_list->data == widget)
else if (current == widget)
{
g_warning ("A container and its child are part of this SizeGroup");
}
else
queue_resize_on_widget (tmp_list->data, FALSE, flags);
queue_resize_on_widget (current, FALSE, flags);
}
g_slist_free (widgets);
g_hash_table_destroy (widgets);
parent = gtk_widget_get_parent (parent);
}
......@@ -650,8 +647,9 @@ _gtk_size_group_bump_requisition (GtkWidget *widget,
gint *minimum,
gint *natural)
{
GSList *widgets;
GSList *tmp_list;
GHashTable *widgets;
GHashTableIter iter;
gpointer key;
gint min_result = 0, nat_result = 0;
if (!_gtk_widget_get_sizegroups (widget))
......@@ -659,11 +657,12 @@ _gtk_size_group_bump_requisition (GtkWidget *widget,
widgets = widget_get_size_group_peers (widget, mode);
g_slist_foreach (widgets, (GFunc)g_object_ref, NULL);
g_hash_table_foreach (widgets, (GHFunc) g_object_ref, NULL);
for (tmp_list = widgets; tmp_list; tmp_list = tmp_list->next)
g_hash_table_iter_init (&iter, widgets);
while (g_hash_table_iter_next (&iter, &key, NULL))
{
GtkWidget *tmp_widget = tmp_list->data;
GtkWidget *tmp_widget = key;
gint min_dimension, nat_dimension;
if (tmp_widget == widget)
......@@ -680,9 +679,9 @@ _gtk_size_group_bump_requisition (GtkWidget *widget,
nat_result = MAX (nat_result, nat_dimension);
}
g_slist_foreach (widgets, (GFunc)g_object_unref, NULL);
g_hash_table_foreach (widgets, (GHFunc) g_object_unref, NULL);
g_slist_free (widgets);
g_hash_table_destroy (widgets);
*minimum = min_result;
*natural = nat_result;
......
......@@ -356,7 +356,6 @@ struct _GtkWidgetPrivate
guint vexpand_set : 1; /* instead of computing from children */
/* SizeGroup related flags */
guint sizegroup_visited : 1;
guint have_size_groups : 1;
/* The widget's name. If the widget does not have a name
......@@ -13817,19 +13816,6 @@ _gtk_widget_set_height_request_needed (GtkWidget *widget,
widget->priv->height_request_needed = height_request_needed;
}
gboolean
_gtk_widget_get_sizegroup_visited (GtkWidget *widget)
{
return widget->priv->sizegroup_visited;
}
void
_gtk_widget_set_sizegroup_visited (GtkWidget *widget,
gboolean visited)
{
widget->priv->sizegroup_visited = visited;
}
void
_gtk_widget_add_sizegroup (GtkWidget *widget,
gpointer group)
......
......@@ -87,9 +87,6 @@ gboolean _gtk_widget_get_height_request_needed (GtkWidget *widget);
void _gtk_widget_set_height_request_needed (GtkWidget *widget,
gboolean height_request_needed);
gboolean _gtk_widget_get_sizegroup_visited (GtkWidget *widget);
void _gtk_widget_set_sizegroup_visited (GtkWidget *widget,
gboolean visited);
void _gtk_widget_add_sizegroup (GtkWidget *widget,
gpointer group);
void _gtk_widget_remove_sizegroup (GtkWidget *widget,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment