forked from AuroraMiddleware/gtk
Optimize queue_resize_on_widget()
Optimized GtkSizeGroup code that is invoked for every queued resize and every request that is not previously cached by trading qdata on widgets for 3 extra bitfields on the GtkWidgetPrivate structure.
This commit is contained in:
parent
db97f8660a
commit
1c20c93423
@ -41,6 +41,7 @@ struct _GtkSizeGroupPrivate
|
||||
guint have_width : 1;
|
||||
guint have_height : 1;
|
||||
guint ignore_hidden : 1;
|
||||
guint visited : 1;
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -81,56 +82,16 @@ static void gtk_size_group_buildable_custom_finished (GtkBuildable *buildable,
|
||||
const gchar *tagname,
|
||||
gpointer user_data);
|
||||
|
||||
static GQuark size_groups_quark;
|
||||
static const gchar size_groups_tag[] = "gtk-size-groups";
|
||||
|
||||
static GQuark visited_quark;
|
||||
static const gchar visited_tag[] = "gtk-size-group-visited";
|
||||
|
||||
static GQuark bumping_quark;
|
||||
static const gchar bumping_tag[] = "gtk-size-group-bumping";
|
||||
|
||||
static GSList *
|
||||
get_size_groups (GtkWidget *widget)
|
||||
static void
|
||||
mark_group_unvisited (GtkSizeGroup *group)
|
||||
{
|
||||
return g_object_get_qdata (G_OBJECT (widget), size_groups_quark);
|
||||
group->priv->visited = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
set_size_groups (GtkWidget *widget,
|
||||
GSList *groups)
|
||||
mark_widget_unvisited (GtkWidget *widget)
|
||||
{
|
||||
g_object_set_qdata (G_OBJECT (widget), size_groups_quark, groups);
|
||||
}
|
||||
|
||||
static void
|
||||
mark_visited (gpointer object)
|
||||
{
|
||||
g_object_set_qdata (object, visited_quark, "visited");
|
||||
}
|
||||
|
||||
static void
|
||||
mark_unvisited (gpointer object)
|
||||
{
|
||||
g_object_set_qdata (object, visited_quark, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_visited (gpointer object)
|
||||
{
|
||||
return g_object_get_qdata (object, visited_quark) != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
mark_bumping (gpointer object, gboolean bumping)
|
||||
{
|
||||
g_object_set_qdata (object, bumping_quark, bumping ? "bumping" : NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_bumping (gpointer object)
|
||||
{
|
||||
return g_object_get_qdata (object, bumping_quark) != NULL;
|
||||
_gtk_widget_set_sizegroup_visited (widget, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -143,14 +104,14 @@ add_group_to_closure (GtkSizeGroup *group,
|
||||
GSList *tmp_widgets;
|
||||
|
||||
*groups = g_slist_prepend (*groups, group);
|
||||
mark_visited (group);
|
||||
priv->visited = TRUE;
|
||||
|
||||
tmp_widgets = priv->widgets;
|
||||
while (tmp_widgets)
|
||||
{
|
||||
GtkWidget *tmp_widget = tmp_widgets->data;
|
||||
|
||||
if (!is_visited (tmp_widget))
|
||||
if (!_gtk_widget_get_sizegroup_visited (tmp_widget))
|
||||
add_widget_to_closure (tmp_widget, mode, groups, widgets);
|
||||
|
||||
tmp_widgets = tmp_widgets->next;
|
||||
@ -166,16 +127,16 @@ add_widget_to_closure (GtkWidget *widget,
|
||||
GSList *tmp_groups;
|
||||
|
||||
*widgets = g_slist_prepend (*widgets, widget);
|
||||
mark_visited (widget);
|
||||
_gtk_widget_set_sizegroup_visited (widget, TRUE);
|
||||
|
||||
tmp_groups = get_size_groups (widget);
|
||||
tmp_groups = _gtk_widget_get_sizegroups (widget);
|
||||
while (tmp_groups)
|
||||
{
|
||||
GtkSizeGroup *tmp_group = tmp_groups->data;
|
||||
GtkSizeGroupPrivate *tmp_priv = tmp_group->priv;
|
||||
GtkSizeGroup *tmp_group = tmp_groups->data;
|
||||
GtkSizeGroupPrivate *tmp_priv = tmp_group->priv;
|
||||
|
||||
if ((tmp_priv->mode == GTK_SIZE_GROUP_BOTH || tmp_priv->mode == mode) &&
|
||||
!is_visited (tmp_group))
|
||||
!tmp_group->priv->visited)
|
||||
add_group_to_closure (tmp_group, mode, groups, widgets);
|
||||
|
||||
tmp_groups = tmp_groups->next;
|
||||
@ -243,7 +204,7 @@ queue_resize_on_widget (GtkWidget *widget,
|
||||
continue;
|
||||
}
|
||||
|
||||
widget_groups = get_size_groups (parent);
|
||||
widget_groups = _gtk_widget_get_sizegroups (parent);
|
||||
if (!widget_groups)
|
||||
{
|
||||
if (widget == parent)
|
||||
@ -257,8 +218,8 @@ queue_resize_on_widget (GtkWidget *widget,
|
||||
widgets = NULL;
|
||||
|
||||
add_widget_to_closure (parent, GTK_SIZE_GROUP_HORIZONTAL, &groups, &widgets);
|
||||
g_slist_foreach (widgets, (GFunc)mark_unvisited, NULL);
|
||||
g_slist_foreach (groups, (GFunc)mark_unvisited, NULL);
|
||||
g_slist_foreach (widgets, (GFunc)mark_widget_unvisited, NULL);
|
||||
g_slist_foreach (groups, (GFunc)mark_group_unvisited, NULL);
|
||||
|
||||
reset_group_sizes (groups);
|
||||
|
||||
@ -287,8 +248,8 @@ queue_resize_on_widget (GtkWidget *widget,
|
||||
widgets = NULL;
|
||||
|
||||
add_widget_to_closure (parent, GTK_SIZE_GROUP_VERTICAL, &groups, &widgets);
|
||||
g_slist_foreach (widgets, (GFunc)mark_unvisited, NULL);
|
||||
g_slist_foreach (groups, (GFunc)mark_unvisited, NULL);
|
||||
g_slist_foreach (widgets, (GFunc)mark_widget_unvisited, NULL);
|
||||
g_slist_foreach (groups, (GFunc)mark_group_unvisited, NULL);
|
||||
|
||||
reset_group_sizes (groups);
|
||||
|
||||
@ -326,17 +287,6 @@ queue_resize_on_group (GtkSizeGroup *size_group)
|
||||
queue_resize_on_widget (priv->widgets->data, TRUE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_size_group_quarks (void)
|
||||
{
|
||||
if (!size_groups_quark)
|
||||
{
|
||||
size_groups_quark = g_quark_from_static_string (size_groups_tag);
|
||||
visited_quark = g_quark_from_static_string (visited_tag);
|
||||
bumping_quark = g_quark_from_static_string (bumping_tag);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_size_group_class_init (GtkSizeGroupClass *klass)
|
||||
{
|
||||
@ -372,8 +322,6 @@ gtk_size_group_class_init (GtkSizeGroupClass *klass)
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GtkSizeGroupPrivate));
|
||||
|
||||
initialize_size_group_quarks ();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -391,6 +339,7 @@ gtk_size_group_init (GtkSizeGroup *size_group)
|
||||
priv->have_width = 0;
|
||||
priv->have_height = 0;
|
||||
priv->ignore_hidden = 0;
|
||||
priv->visited = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -600,12 +549,11 @@ gtk_size_group_add_widget (GtkSizeGroup *size_group,
|
||||
|
||||
priv = size_group->priv;
|
||||
|
||||
groups = get_size_groups (widget);
|
||||
groups = _gtk_widget_get_sizegroups (widget);
|
||||
|
||||
if (!g_slist_find (groups, size_group))
|
||||
{
|
||||
groups = g_slist_prepend (groups, size_group);
|
||||
set_size_groups (widget, groups);
|
||||
_gtk_widget_add_sizegroup (widget, size_group);
|
||||
|
||||
priv->widgets = g_slist_prepend (priv->widgets, widget);
|
||||
|
||||
@ -631,7 +579,6 @@ gtk_size_group_remove_widget (GtkSizeGroup *size_group,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkSizeGroupPrivate *priv;
|
||||
GSList *groups;
|
||||
|
||||
g_return_if_fail (GTK_IS_SIZE_GROUP (size_group));
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
@ -644,9 +591,7 @@ gtk_size_group_remove_widget (GtkSizeGroup *size_group,
|
||||
gtk_size_group_widget_destroyed,
|
||||
size_group);
|
||||
|
||||
groups = get_size_groups (widget);
|
||||
groups = g_slist_remove (groups, size_group);
|
||||
set_size_groups (widget, groups);
|
||||
_gtk_widget_remove_sizegroup (widget, size_group);
|
||||
|
||||
priv->widgets = g_slist_remove (priv->widgets, widget);
|
||||
queue_resize_on_group (size_group);
|
||||
@ -684,10 +629,9 @@ compute_dimension (GtkWidget *widget,
|
||||
gint min_result = 0, nat_result = 0;
|
||||
|
||||
add_widget_to_closure (widget, mode, &groups, &widgets);
|
||||
g_slist_foreach (widgets, (GFunc)mark_widget_unvisited, NULL);
|
||||
g_slist_foreach (groups, (GFunc)mark_group_unvisited, NULL);
|
||||
|
||||
g_slist_foreach (widgets, (GFunc)mark_unvisited, NULL);
|
||||
g_slist_foreach (groups, (GFunc)mark_unvisited, NULL);
|
||||
|
||||
g_slist_foreach (widgets, (GFunc)g_object_ref, NULL);
|
||||
|
||||
if (!groups)
|
||||
@ -755,7 +699,6 @@ compute_dimension (GtkWidget *widget,
|
||||
else
|
||||
{
|
||||
tmp_priv->have_height = TRUE;
|
||||
|
||||
tmp_priv->minimum_req.height = min_result;
|
||||
tmp_priv->natural_req.height = nat_result;
|
||||
}
|
||||
@ -795,15 +738,15 @@ _gtk_size_group_bump_requisition (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
if (!is_bumping (widget))
|
||||
if (!_gtk_widget_get_sizegroup_bumping (widget))
|
||||
{
|
||||
/* Avoid recursion here */
|
||||
mark_bumping (widget, TRUE);
|
||||
_gtk_widget_set_sizegroup_bumping (widget, TRUE);
|
||||
|
||||
if (get_size_groups (widget))
|
||||
if (_gtk_widget_get_sizegroups (widget))
|
||||
compute_dimension (widget, mode, minimum, natural);
|
||||
|
||||
mark_bumping (widget, FALSE);
|
||||
_gtk_widget_set_sizegroup_bumping (widget, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -819,8 +762,6 @@ void
|
||||
_gtk_size_group_queue_resize (GtkWidget *widget,
|
||||
GtkQueueResizeFlags flags)
|
||||
{
|
||||
initialize_size_group_quarks ();
|
||||
|
||||
queue_resize_on_widget (widget, TRUE, flags);
|
||||
}
|
||||
|
||||
|
@ -324,6 +324,8 @@ struct _GtkWidgetPrivate
|
||||
guint multidevice : 1;
|
||||
guint has_shape_mask : 1;
|
||||
guint in_reparent : 1;
|
||||
|
||||
/* Queue-resize related flags */
|
||||
guint resize_pending : 1;
|
||||
guint alloc_needed : 1;
|
||||
guint width_request_needed : 1;
|
||||
@ -338,6 +340,11 @@ struct _GtkWidgetPrivate
|
||||
guint hexpand_set : 1; /* whether to use application-forced */
|
||||
guint vexpand_set : 1; /* instead of computing from children */
|
||||
|
||||
/* SizeGroup related flags */
|
||||
guint sizegroup_visited : 1;
|
||||
guint sizegroup_bumping : 1;
|
||||
guint have_size_groups : 1;
|
||||
|
||||
/* The widget's name. If the widget does not have a name
|
||||
* (the name is NULL), then its name (as returned by
|
||||
* "gtk_widget_get_name") is its class's name.
|
||||
@ -697,6 +704,7 @@ static GQuark quark_tooltip_window = 0;
|
||||
static GQuark quark_visual = 0;
|
||||
static GQuark quark_modifier_style = 0;
|
||||
static GQuark quark_enabled_devices = 0;
|
||||
static GQuark quark_size_groups = 0;
|
||||
GParamSpecPool *_gtk_widget_child_property_pool = NULL;
|
||||
GObjectNotifyContext *_gtk_widget_child_property_notify_context = NULL;
|
||||
|
||||
@ -811,6 +819,7 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
quark_visual = g_quark_from_static_string ("gtk-widget-visual");
|
||||
quark_modifier_style = g_quark_from_static_string ("gtk-widget-modifier-style");
|
||||
quark_enabled_devices = g_quark_from_static_string ("gtk-widget-enabled-devices");
|
||||
quark_size_groups = g_quark_from_static_string ("gtk-widget-size-groups");
|
||||
|
||||
style_property_spec_pool = g_param_spec_pool_new (FALSE);
|
||||
_gtk_widget_child_property_pool = g_param_spec_pool_new (TRUE);
|
||||
@ -14064,6 +14073,67 @@ _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;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_widget_get_sizegroup_bumping (GtkWidget *widget)
|
||||
{
|
||||
return widget->priv->sizegroup_bumping;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_widget_set_sizegroup_bumping (GtkWidget *widget,
|
||||
gboolean bumping)
|
||||
{
|
||||
widget->priv->sizegroup_bumping = bumping;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_widget_add_sizegroup (GtkWidget *widget,
|
||||
gpointer group)
|
||||
{
|
||||
GSList *groups;
|
||||
|
||||
groups = g_object_get_qdata (G_OBJECT (widget), quark_size_groups);
|
||||
groups = g_slist_prepend (groups, group);
|
||||
g_object_set_qdata (G_OBJECT (widget), quark_size_groups, groups);
|
||||
|
||||
widget->priv->have_size_groups = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_widget_remove_sizegroup (GtkWidget *widget,
|
||||
gpointer group)
|
||||
{
|
||||
GSList *groups;
|
||||
|
||||
groups = g_object_get_qdata (G_OBJECT (widget), quark_size_groups);
|
||||
groups = g_slist_remove (groups, group);
|
||||
g_object_set_qdata (G_OBJECT (widget), quark_size_groups, groups);
|
||||
|
||||
widget->priv->have_size_groups = groups != NULL;
|
||||
}
|
||||
|
||||
GSList *
|
||||
_gtk_widget_get_sizegroups (GtkWidget *widget)
|
||||
{
|
||||
if (widget->priv->have_size_groups)
|
||||
return g_object_get_qdata (G_OBJECT (widget), quark_size_groups);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_path:
|
||||
* @widget: a #GtkWidget
|
||||
|
@ -79,6 +79,18 @@ 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);
|
||||
gboolean _gtk_widget_get_sizegroup_bumping (GtkWidget *widget);
|
||||
void _gtk_widget_set_sizegroup_bumping (GtkWidget *widget,
|
||||
gboolean bumping);
|
||||
void _gtk_widget_add_sizegroup (GtkWidget *widget,
|
||||
gpointer group);
|
||||
void _gtk_widget_remove_sizegroup (GtkWidget *widget,
|
||||
gpointer group);
|
||||
GSList *_gtk_widget_get_sizegroups (GtkWidget *widget);
|
||||
|
||||
void _gtk_widget_override_size_request (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
|
Loading…
Reference in New Issue
Block a user