Pass the layout signal via GdkSurface to GtkRoot

Don't have GtkRoot listen directly to the layout signal on the frame
clock, but let it pass through GdkSurface. This will allow GdkSurface to
be more involved in the layout phase.
This commit is contained in:
Jonas Ådahl 2020-11-24 22:02:53 +01:00
parent 475c07e935
commit ecc861bf06
5 changed files with 66 additions and 8 deletions

View File

@ -1370,6 +1370,45 @@ gdk_surface_process_updates_internal (GdkSurface *surface)
g_object_unref (surface);
}
static void
gdk_surface_layout_on_clock (GdkFrameClock *clock,
void *data)
{
GdkSurface *surface = GDK_SURFACE (data);
g_return_if_fail (GDK_IS_SURFACE (surface));
if (GDK_SURFACE_DESTROYED (surface))
return;
if (!GDK_SURFACE_IS_MAPPED (surface))
return;
if (surface->update_freeze_count)
return;
g_signal_emit (surface, signals[LAYOUT], 0, surface->width, surface->height);
}
void
gdk_surface_request_layout (GdkSurface *surface)
{
GdkFrameClock *frame_clock;
if (surface->update_freeze_count ||
gdk_surface_is_toplevel_frozen (surface))
{
surface->pending_phases |= GDK_FRAME_CLOCK_PHASE_LAYOUT;
return;
}
frame_clock = gdk_surface_get_frame_clock (surface);
g_return_if_fail (frame_clock);
gdk_frame_clock_request_phase (frame_clock,
GDK_FRAME_CLOCK_PHASE_LAYOUT);
}
static void
gdk_surface_paint_on_clock (GdkFrameClock *clock,
void *data)
@ -2451,6 +2490,10 @@ gdk_surface_set_frame_clock (GdkSurface *surface,
"resume-events",
G_CALLBACK (gdk_surface_resume_events),
surface);
g_signal_connect (G_OBJECT (clock),
"layout",
G_CALLBACK (gdk_surface_layout_on_clock),
surface);
g_signal_connect (G_OBJECT (clock),
"paint",
G_CALLBACK (gdk_surface_paint_on_clock),
@ -2471,6 +2514,9 @@ gdk_surface_set_frame_clock (GdkSurface *surface,
g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
G_CALLBACK (gdk_surface_resume_events),
surface);
g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
G_CALLBACK (gdk_surface_layout_on_clock),
surface);
g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
G_CALLBACK (gdk_surface_paint_on_clock),
surface);

View File

@ -118,6 +118,9 @@ void gdk_surface_beep (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
void gdk_surface_queue_render (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
void gdk_surface_request_layout (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
GdkFrameClock* gdk_surface_get_frame_clock (GdkSurface *surface);

View File

@ -195,8 +195,10 @@ gtk_root_after_update_cb (GdkFrameClock *clock,
}
static void
gtk_root_layout_cb (GdkFrameClock *clock,
GtkRoot *self)
gtk_root_layout_cb (GdkSurface *surface,
int width,
int height,
GtkRoot *self)
{
GtkWidget *widget = GTK_WIDGET (self);
@ -231,19 +233,22 @@ gtk_root_layout_cb (GdkFrameClock *clock,
if (gtk_root_needs_layout (self))
{
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_UPDATE);
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
gdk_frame_clock_request_phase (gdk_surface_get_frame_clock (surface),
GDK_FRAME_CLOCK_PHASE_UPDATE);
gdk_surface_request_layout (surface);
}
}
void
gtk_root_start_layout (GtkRoot *self)
{
GdkSurface *surface;
GdkFrameClock *clock;
if (!gtk_root_needs_layout (self))
return;
surface = gtk_widget_get_surface (GTK_WIDGET (self));
clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
if (clock == NULL)
return;
@ -260,19 +265,20 @@ gtk_root_start_layout (GtkRoot *self)
GINT_TO_POINTER (after_update_handler));
layout_handler =
g_signal_connect (clock, "layout",
g_signal_connect (surface, "layout",
G_CALLBACK (gtk_root_layout_cb), self);
g_object_set_qdata (G_OBJECT (self), quark_layout_handler,
GINT_TO_POINTER (layout_handler));
}
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_UPDATE);
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
gdk_surface_request_layout (surface);
}
void
gtk_root_stop_layout (GtkRoot *self)
{
GdkSurface *surface;
GdkFrameClock *clock;
guint layout_handler;
guint after_update_handler;
@ -287,8 +293,9 @@ gtk_root_stop_layout (GtkRoot *self)
if (layout_handler == 0)
return;
surface = gtk_widget_get_surface (GTK_WIDGET (self));
clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
g_signal_handler_disconnect (clock, layout_handler);
g_signal_handler_disconnect (surface, layout_handler);
g_signal_handler_disconnect (clock, after_update_handler);
g_object_set_qdata (G_OBJECT (self), quark_layout_handler, NULL);
g_object_set_qdata (G_OBJECT (self), quark_after_update_handler, NULL);

View File

@ -3244,7 +3244,7 @@ gtk_widget_remove_surface_transform_changed_callback (GtkWidget *widget,
}
}
static GdkSurface *
GdkSurface *
gtk_widget_get_surface (GtkWidget *widget)
{
GtkNative *native = gtk_widget_get_native (widget);

View File

@ -228,6 +228,8 @@ void gtk_widget_ensure_resize (GtkWidget *widget);
void gtk_widget_ensure_allocate (GtkWidget *widget);
void _gtk_widget_scale_changed (GtkWidget *widget);
GdkSurface * gtk_widget_get_surface (GtkWidget *widget);
void gtk_widget_render (GtkWidget *widget,
GdkSurface *surface,
const cairo_region_t *region);