widget: Move frame clock handling to vfunc

Instead of connecting to / disconnecting from the frame clock, do it
inside the vfuncs next to changing the priv->realized boolean.

This removes a race between those 2 cases that could cause child
widgets' unrealize handlers to reconnect this widget to the frame clock
because it was still marked as realize when the widget had already
disconnected from the frame clock.

Fixes #168
This commit is contained in:
Benjamin Otte 2018-04-11 03:03:35 +02:00
parent 7ef8cb652b
commit 2abf082231

View File

@ -3689,14 +3689,16 @@ gtk_widget_has_tick_callback (GtkWidget *widget)
}
static void
gtk_widget_connect_frame_clock (GtkWidget *widget,
GdkFrameClock *frame_clock)
gtk_widget_connect_frame_clock (GtkWidget *widget)
{
GtkWidgetPrivate *priv = widget->priv;
GdkFrameClock *frame_clock;
if (GTK_IS_CONTAINER (widget))
gtk_container_start_idle_sizer (GTK_CONTAINER (widget));
frame_clock = gtk_widget_get_frame_clock (widget);
if (priv->tick_callbacks != NULL && !priv->clock_tick_id)
{
priv->clock_tick_id = g_signal_connect (frame_clock, "update",
@ -3712,8 +3714,7 @@ gtk_widget_connect_frame_clock (GtkWidget *widget,
}
static void
gtk_widget_disconnect_frame_clock (GtkWidget *widget,
GdkFrameClock *frame_clock)
gtk_widget_disconnect_frame_clock (GtkWidget *widget)
{
GtkWidgetPrivate *priv = widget->priv;
@ -3724,6 +3725,10 @@ gtk_widget_disconnect_frame_clock (GtkWidget *widget,
if (priv->clock_tick_id)
{
GdkFrameClock *frame_clock;
frame_clock = gtk_widget_get_frame_clock (widget);
g_signal_handler_disconnect (frame_clock, priv->clock_tick_id);
priv->clock_tick_id = 0;
gdk_frame_clock_end_updating (frame_clock);
@ -3798,8 +3803,6 @@ gtk_widget_realize (GtkWidget *widget)
if (priv->context)
gtk_style_context_set_scale (priv->context, gtk_widget_get_scale_factor (widget));
gtk_widget_connect_frame_clock (widget,
gtk_widget_get_frame_clock (widget));
gtk_widget_pop_verify_invariants (widget);
}
@ -3829,9 +3832,6 @@ gtk_widget_unrealize (GtkWidget *widget)
if (widget->priv->mapped)
gtk_widget_unmap (widget);
gtk_widget_disconnect_frame_clock (widget,
gtk_widget_get_frame_clock (widget));
g_signal_emit (widget, widget_signals[UNREALIZE], 0);
g_assert (!widget->priv->mapped);
g_assert (!widget->priv->realized);
@ -8746,6 +8746,8 @@ gtk_widget_real_realize (GtkWidget *widget)
}
priv->realized = TRUE;
gtk_widget_connect_frame_clock (widget);
}
/*****************************************
@ -8771,6 +8773,8 @@ gtk_widget_real_unrealize (GtkWidget *widget)
gtk_widget_forall (widget, (GtkCallback)gtk_widget_unrealize, NULL);
gtk_widget_disconnect_frame_clock (widget);
priv->realized = FALSE;
if (_gtk_widget_get_has_surface (widget))