widget: Move surface relative transform fields into its own struct

The purpose being to reduce the size of GtkWidgetPrivate. What is left
is a pointer to the allocated struct.
This commit is contained in:
Jonas Ådahl 2019-04-25 15:39:06 +02:00
parent 1ad406e15d
commit 3a1ef7aa2c
2 changed files with 90 additions and 54 deletions

View File

@ -2908,7 +2908,7 @@ gtk_widget_root (GtkWidget *widget)
if (priv->context) if (priv->context)
gtk_style_context_set_display (priv->context, gtk_root_get_display (priv->root)); gtk_style_context_set_display (priv->context, gtk_root_get_display (priv->root));
if (priv->surface_transform_changed_callbacks) if (priv->surface_transform_data)
add_parent_surface_transform_changed_listener (widget); add_parent_surface_transform_changed_listener (widget);
GTK_WIDGET_GET_CLASS (widget)->root (widget); GTK_WIDGET_GET_CLASS (widget)->root (widget);
@ -2920,6 +2920,7 @@ static void
gtk_widget_unroot (GtkWidget *widget) gtk_widget_unroot (GtkWidget *widget)
{ {
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
GtkWidgetSurfaceTransformData *surface_transform_data;
/* roots are rooted by default and cannot be unrooted */ /* roots are rooted by default and cannot be unrooted */
if (GTK_IS_ROOT (widget)) if (GTK_IS_ROOT (widget))
@ -2928,7 +2929,9 @@ gtk_widget_unroot (GtkWidget *widget)
g_assert (priv->root); g_assert (priv->root);
g_assert (!priv->realized); g_assert (!priv->realized);
if (priv->parent_surface_transform_changed_parent) surface_transform_data = priv->surface_transform_data;
if (surface_transform_data &&
surface_transform_data->tracked_parent)
remove_parent_surface_transform_changed_listener (widget); remove_parent_surface_transform_changed_listener (widget);
GTK_WIDGET_GET_CLASS (widget)->unroot (widget); GTK_WIDGET_GET_CLASS (widget)->unroot (widget);
@ -3618,15 +3621,17 @@ static void
notify_surface_transform_changed (GtkWidget *widget) notify_surface_transform_changed (GtkWidget *widget)
{ {
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
GtkWidgetSurfaceTransformData *surface_transform_data =
priv->surface_transform_data;
graphene_matrix_t *surface_transform; graphene_matrix_t *surface_transform;
GList *l; GList *l;
if (priv->cached_surface_transform_valid) if (surface_transform_data->cached_surface_transform_valid)
surface_transform = &priv->cached_surface_transform; surface_transform = &surface_transform_data->cached_surface_transform;
else else
surface_transform = NULL; surface_transform = NULL;
for (l = priv->surface_transform_changed_callbacks; l;) for (l = surface_transform_data->callbacks; l;)
{ {
GtkSurfaceTransformChangedCallbackInfo *info = l->data; GtkSurfaceTransformChangedCallbackInfo *info = l->data;
GList *l_next = l->next; GList *l_next = l->next;
@ -3635,8 +3640,8 @@ notify_surface_transform_changed (GtkWidget *widget)
surface_transform, surface_transform,
info->user_data) == G_SOURCE_REMOVE) info->user_data) == G_SOURCE_REMOVE)
{ {
priv->surface_transform_changed_callbacks = surface_transform_data->callbacks =
g_list_delete_link (priv->surface_transform_changed_callbacks, l); g_list_delete_link (surface_transform_data->callbacks, l);
surface_transform_changed_callback_info_destroy (info); surface_transform_changed_callback_info_destroy (info);
} }
@ -3645,58 +3650,57 @@ notify_surface_transform_changed (GtkWidget *widget)
} }
static void static void
destroy_surface_transform_changed_callbacks (GtkWidget *widget) destroy_surface_transform_data (GtkWidget *widget)
{ {
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
GList *l; GtkWidgetSurfaceTransformData *surface_transform_data;
for (l = priv->surface_transform_changed_callbacks; l;) surface_transform_data = priv->surface_transform_data;
{ if (!surface_transform_data)
GtkSurfaceTransformChangedCallbackInfo *info = l->data; return;
GList *l_next = l->next;
priv->surface_transform_changed_callbacks = g_list_free_full (surface_transform_data->callbacks,
g_list_delete_link (priv->surface_transform_changed_callbacks, l); (GDestroyNotify) surface_transform_changed_callback_info_destroy);
surface_transform_changed_callback_info_destroy (info); g_slice_free (GtkWidgetSurfaceTransformData, surface_transform_data);
priv->surface_transform_data = NULL;
l = l_next;
}
} }
static void static void
sync_widget_surface_transform (GtkWidget *widget) sync_widget_surface_transform (GtkWidget *widget)
{ {
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
GtkWidgetSurfaceTransformData *surface_transform_data =
priv->surface_transform_data;
gboolean was_valid; gboolean was_valid;
graphene_matrix_t prev_transform; graphene_matrix_t prev_transform;
was_valid = priv->cached_surface_transform_valid; was_valid = surface_transform_data->cached_surface_transform_valid;
prev_transform = priv->cached_surface_transform; prev_transform = surface_transform_data->cached_surface_transform;
if (GTK_IS_ROOT (widget)) if (GTK_IS_ROOT (widget))
{ {
gsk_transform_to_matrix (priv->transform, gsk_transform_to_matrix (priv->transform,
&priv->cached_surface_transform); &surface_transform_data->cached_surface_transform);
priv->cached_surface_transform_valid = TRUE; surface_transform_data->cached_surface_transform_valid = TRUE;
} }
else if (!priv->root) else if (!priv->root)
{ {
priv->cached_surface_transform_valid = FALSE; surface_transform_data->cached_surface_transform_valid = FALSE;
} }
else if (gtk_widget_compute_transform (widget, GTK_WIDGET (priv->root), else if (gtk_widget_compute_transform (widget, GTK_WIDGET (priv->root),
&priv->cached_surface_transform)) &surface_transform_data->cached_surface_transform))
{ {
priv->cached_surface_transform_valid = TRUE; surface_transform_data->cached_surface_transform_valid = TRUE;
} }
else else
{ {
g_warning ("Could not compute surface transform"); g_warning ("Could not compute surface transform");
priv->cached_surface_transform_valid = FALSE; surface_transform_data->cached_surface_transform_valid = FALSE;
} }
if (was_valid != priv->cached_surface_transform_valid || if (was_valid != surface_transform_data->cached_surface_transform_valid ||
(was_valid && priv->cached_surface_transform_valid && (was_valid && surface_transform_data->cached_surface_transform_valid &&
!graphene_matrix_equal (&priv->cached_surface_transform, !graphene_matrix_equal (&surface_transform_data->cached_surface_transform,
&prev_transform))) &prev_transform)))
notify_surface_transform_changed (widget); notify_surface_transform_changed (widget);
} }
@ -3719,32 +3723,48 @@ static void
remove_parent_surface_transform_changed_listener (GtkWidget *widget) remove_parent_surface_transform_changed_listener (GtkWidget *widget)
{ {
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
GtkWidgetSurfaceTransformData *surface_transform_data =
priv->surface_transform_data;
g_assert (priv->parent_surface_transform_changed_parent); g_assert (surface_transform_data->tracked_parent);
gtk_widget_remove_surface_transform_changed_callback ( gtk_widget_remove_surface_transform_changed_callback (
priv->parent_surface_transform_changed_parent, surface_transform_data->tracked_parent,
priv->parent_surface_transform_changed_id); surface_transform_data->parent_surface_transform_changed_id);
priv->parent_surface_transform_changed_id = 0; surface_transform_data->parent_surface_transform_changed_id = 0;
g_clear_object (&priv->parent_surface_transform_changed_parent); g_clear_object (&surface_transform_data->tracked_parent);
} }
static void static void
add_parent_surface_transform_changed_listener (GtkWidget *widget) add_parent_surface_transform_changed_listener (GtkWidget *widget)
{ {
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
GtkWidgetSurfaceTransformData *surface_transform_data =
priv->surface_transform_data;
GtkWidget *parent; GtkWidget *parent;
g_assert (!priv->parent_surface_transform_changed_parent);
g_assert (!surface_transform_data->tracked_parent);
parent = priv->parent; parent = priv->parent;
priv->parent_surface_transform_changed_id = surface_transform_data->parent_surface_transform_changed_id =
gtk_widget_add_surface_transform_changed_callback ( gtk_widget_add_surface_transform_changed_callback (
parent, parent,
parent_surface_transform_changed_cb, parent_surface_transform_changed_cb,
widget, widget,
NULL); NULL);
priv->parent_surface_transform_changed_parent = g_object_ref (parent); surface_transform_data->tracked_parent = g_object_ref (parent);
}
static GtkWidgetSurfaceTransformData *
ensure_surface_transform_data (GtkWidget *widget)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
if (!priv->surface_transform_data)
priv->surface_transform_data = g_slice_new0 (GtkWidgetSurfaceTransformData);
return priv->surface_transform_data;
} }
/** /**
@ -3768,17 +3788,20 @@ gtk_widget_add_surface_transform_changed_callback (GtkWidget
GDestroyNotify notify) GDestroyNotify notify)
{ {
GtkWidgetPrivate *priv; GtkWidgetPrivate *priv;
GtkWidgetSurfaceTransformData *surface_transform_data;
GtkSurfaceTransformChangedCallbackInfo *info; GtkSurfaceTransformChangedCallbackInfo *info;
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0); g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
g_return_val_if_fail (callback, 0); g_return_val_if_fail (callback, 0);
priv = gtk_widget_get_instance_private (widget); priv = gtk_widget_get_instance_private (widget);
surface_transform_data = ensure_surface_transform_data (widget);
if (priv->parent && !priv->parent_surface_transform_changed_id) if (priv->parent &&
!surface_transform_data->parent_surface_transform_changed_id)
add_parent_surface_transform_changed_listener (widget); add_parent_surface_transform_changed_listener (widget);
if (!priv->surface_transform_changed_callbacks) if (!surface_transform_data->callbacks)
sync_widget_surface_transform (widget); sync_widget_surface_transform (widget);
info = g_slice_new0 (GtkSurfaceTransformChangedCallbackInfo); info = g_slice_new0 (GtkSurfaceTransformChangedCallbackInfo);
@ -3788,8 +3811,8 @@ gtk_widget_add_surface_transform_changed_callback (GtkWidget
info->user_data = user_data; info->user_data = user_data;
info->notify = notify; info->notify = notify;
priv->surface_transform_changed_callbacks = surface_transform_data->callbacks =
g_list_prepend (priv->surface_transform_changed_callbacks, info); g_list_prepend (surface_transform_data->callbacks, info);
return info->id; return info->id;
} }
@ -3807,31 +3830,37 @@ gtk_widget_remove_surface_transform_changed_callback (GtkWidget *widget,
guint id) guint id)
{ {
GtkWidgetPrivate *priv; GtkWidgetPrivate *priv;
GtkWidgetSurfaceTransformData *surface_transform_data;
GList *l; GList *l;
g_return_if_fail (GTK_IS_WIDGET (widget)); g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (id); g_return_if_fail (id);
priv = gtk_widget_get_instance_private (widget); priv = gtk_widget_get_instance_private (widget);
surface_transform_data = priv->surface_transform_data;
for (l = priv->surface_transform_changed_callbacks; l; l = l->next) g_return_if_fail (surface_transform_data);
for (l = surface_transform_data->callbacks; l; l = l->next)
{ {
GtkSurfaceTransformChangedCallbackInfo *info = l->data; GtkSurfaceTransformChangedCallbackInfo *info = l->data;
if (info->id == id) if (info->id == id)
{ {
priv->surface_transform_changed_callbacks = surface_transform_data->callbacks =
g_list_delete_link (priv->surface_transform_changed_callbacks, l); g_list_delete_link (surface_transform_data->callbacks, l);
surface_transform_changed_callback_info_destroy (info); surface_transform_changed_callback_info_destroy (info);
break; break;
} }
} }
if (!priv->surface_transform_changed_callbacks) if (!surface_transform_data->callbacks)
{ {
if (priv->parent_surface_transform_changed_parent) if (surface_transform_data->tracked_parent)
remove_parent_surface_transform_changed_listener (widget); remove_parent_surface_transform_changed_listener (widget);
g_slice_free (GtkWidgetSurfaceTransformData, surface_transform_data);
priv->surface_transform_data = NULL;
} }
} }
@ -4449,7 +4478,7 @@ gtk_widget_allocate (GtkWidget *widget,
priv->transform = transform; priv->transform = transform;
if (priv->surface_transform_changed_callbacks) if (priv->surface_transform_data)
sync_widget_surface_transform (widget); sync_widget_surface_transform (widget);
if (!alloc_needed && !size_changed && !baseline_changed) if (!alloc_needed && !size_changed && !baseline_changed)
@ -8377,7 +8406,7 @@ gtk_widget_real_destroy (GtkWidget *object)
gtk_grab_remove (widget); gtk_grab_remove (widget);
destroy_tick_callbacks (widget); destroy_tick_callbacks (widget);
destroy_surface_transform_changed_callbacks (widget); destroy_surface_transform_data (widget);
} }
static void static void

View File

@ -47,6 +47,17 @@ typedef gboolean (*GtkSurfaceTransformChangedCallback) (GtkWidget
#define GTK_STATE_FLAGS_BITS 14 #define GTK_STATE_FLAGS_BITS 14
typedef struct _GtkWidgetSurfaceTransformData
{
GtkWidget *tracked_parent;
guint parent_surface_transform_changed_id;
GList *callbacks;
gboolean cached_surface_transform_valid;
graphene_matrix_t cached_surface_transform;
} GtkWidgetSurfaceTransformData;
struct _GtkWidgetPrivate struct _GtkWidgetPrivate
{ {
/* The state of the widget. Needs to be able to hold all GtkStateFlags bits /* The state of the widget. Needs to be able to hold all GtkStateFlags bits
@ -121,11 +132,7 @@ struct _GtkWidgetPrivate
GList *tick_callbacks; GList *tick_callbacks;
/* Surface relative transform updates callbacks */ /* Surface relative transform updates callbacks */
guint parent_surface_transform_changed_id; GtkWidgetSurfaceTransformData *surface_transform_data;
GtkWidget *parent_surface_transform_changed_parent;
GList *surface_transform_changed_callbacks;
gboolean cached_surface_transform_valid;
graphene_matrix_t cached_surface_transform;
/* The widget's name. If the widget does not have a name /* The widget's name. If the widget does not have a name
* (the name is NULL), then its name (as returned by * (the name is NULL), then its name (as returned by