Commit 2c7b2171 authored by Emmanuele Bassi's avatar Emmanuele Bassi
Browse files

Simplify the widget rendering entry point

Now that GDK has the appropriate API, we can simplify the widget drawing
code into a single function.

https://bugzilla.gnome.org/show_bug.cgi?id=766675
parent fc569f1a
......@@ -1804,32 +1804,7 @@ gtk_main_do_event (GdkEvent *event)
case GDK_EXPOSE:
if (event->any.window)
{
gboolean is_double_buffered;
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
is_double_buffered = gtk_widget_get_double_buffered (event_widget);
G_GNUC_END_IGNORE_DEPRECATIONS;
if (is_double_buffered)
{
/* We handle exposes only on native windows, relying on the
* draw() handler to propagate down to non-native windows.
* This is ok now that child windows are always considered
* (semi)transparent.
*/
if (gdk_window_has_native (event->expose.window))
{
gdk_window_begin_paint_region (event->any.window, event->expose.region);
gtk_widget_send_expose (event_widget, event);
gdk_window_end_paint (event->any.window);
}
}
else
{
gtk_widget_send_expose (event_widget, event);
}
}
gtk_widget_render (event_widget, event->any.window, event->expose.region);
break;
case GDK_PROPERTY_NOTIFY:
......
......@@ -6883,21 +6883,22 @@ gtk_widget_real_mnemonic_activate (GtkWidget *widget,
return TRUE;
}
static const cairo_user_data_key_t event_window_key;
static const cairo_user_data_key_t mark_for_draw_key;
static GdkWindow *
gtk_cairo_get_event_window (cairo_t *cr)
static gboolean
gtk_cairo_is_marked_for_draw (cairo_t *cr)
{
g_return_val_if_fail (cr != NULL, NULL);
return cairo_get_user_data (cr, &event_window_key);
return cairo_get_user_data (cr, &mark_for_draw_key) != NULL;
}
static void
gtk_cairo_set_event_window (cairo_t *cr,
GdkWindow *event_window)
gtk_cairo_set_marked_for_draw (cairo_t *cr,
gboolean marked)
{
cairo_set_user_data (cr, &event_window_key, event_window, NULL);
if (marked)
cairo_set_user_data (cr, &mark_for_draw_key, GINT_TO_POINTER (1), NULL);
else
cairo_set_user_data (cr, &mark_for_draw_key, NULL, NULL);
}
/**
......@@ -6919,25 +6920,28 @@ gtk_cairo_set_event_window (cairo_t *cr,
* Returns: %TRUE if @window should be drawn
*
* Since: 3.0
**/
*/
gboolean
gtk_cairo_should_draw_window (cairo_t *cr,
gtk_cairo_should_draw_window (cairo_t *cr,
GdkWindow *window)
{
GdkWindow *event_window;
GdkWindow *tmp;
g_return_val_if_fail (cr != NULL, FALSE);
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
event_window = gtk_cairo_get_event_window (cr);
if (gtk_cairo_is_marked_for_draw (cr))
return TRUE;
if (event_window == NULL)
tmp = gdk_cairo_get_window (cr);
if (tmp == NULL)
return TRUE;
while (!gdk_window_has_native (window))
window = gdk_window_get_parent (window);
return event_window == window;
return tmp == window;
}
void
......@@ -6964,9 +6968,19 @@ gtk_widget_draw_internal (GtkWidget *widget,
gboolean result;
gboolean push_group;
event_window = gtk_cairo_get_event_window (cr);
if (event_window)
gdk_window_mark_paint_from_clip (event_window, cr);
/* If this was a cairo_t passed via gtk_widget_draw() then we don't
* require a window
*/
if (gtk_cairo_is_marked_for_draw (cr))
{
event_window = NULL;
}
else
{
event_window = gdk_cairo_get_window (cr);
if (event_window != NULL)
gdk_window_mark_paint_from_clip (event_window, cr);
}
push_group =
widget->priv->alpha != 255 &&
......@@ -7077,7 +7091,7 @@ void
gtk_widget_draw (GtkWidget *widget,
cairo_t *cr)
{
GdkWindow *tmp_event_window;
gboolean was_marked;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (!widget->priv->alloc_needed);
......@@ -7086,17 +7100,18 @@ gtk_widget_draw (GtkWidget *widget,
cairo_save (cr);
/* We have to reset the event here so that draw functions can call
* gtk_widget_draw() on random other widgets and get the desired
* effect: Drawing all contents, not just the current window.
was_marked = gtk_cairo_is_marked_for_draw (cr);
/* We mark the window so that gtk_cairo_should_draw_window()
* will always return TRUE, and all GdkWindows get drawn
*/
tmp_event_window = gtk_cairo_get_event_window (cr);
gtk_cairo_set_event_window (cr, NULL);
gtk_cairo_set_marked_for_draw (cr, TRUE);
gtk_widget_draw_internal (widget, cr, TRUE);
gtk_cairo_set_marked_for_draw (cr, was_marked);
cairo_restore (cr);
gtk_cairo_set_event_window (cr, tmp_event_window);
}
static gboolean
......@@ -7506,32 +7521,12 @@ gint
gtk_widget_send_expose (GtkWidget *widget,
GdkEvent *event)
{
cairo_t *cr;
int x, y;
gboolean do_clip;
g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
g_return_val_if_fail (gtk_widget_get_realized (widget), TRUE);
g_return_val_if_fail (event != NULL, TRUE);
g_return_val_if_fail (event->type == GDK_EXPOSE, TRUE);
cr = gdk_cairo_create (event->expose.window);
gtk_cairo_set_event_window (cr, event->expose.window);
gdk_cairo_region (cr, event->expose.region);
cairo_clip (cr);
do_clip = _gtk_widget_get_translation_to_window (widget,
event->expose.window,
&x, &y);
cairo_translate (cr, -x, -y);
gtk_widget_draw_internal (widget, cr, do_clip);
/* unset here, so if someone keeps a reference to cr we
* don't leak the window. */
gtk_cairo_set_event_window (cr, NULL);
cairo_destroy (cr);
gtk_widget_render (widget, event->any.window, event->expose.region);
return FALSE;
}
......@@ -17439,3 +17434,30 @@ gtk_widget_reset_controllers (GtkWidget *widget)
gtk_event_controller_reset (controller_data->controller);
}
}
void
gtk_widget_render (GtkWidget *widget,
GdkWindow *window,
const cairo_region_t *region)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
gboolean do_clip;
cairo_t *cr;
int x, y;
if (priv->double_buffered)
{
/* We only render double buffered on native windows */
if (!gdk_window_has_native (window))
return;
}
cr = gdk_window_begin_draw_frame (window, region);
do_clip = _gtk_widget_get_translation_to_window (widget, window, &x, &y);
cairo_translate (cr, -x, -y);
gtk_widget_draw_internal (widget, cr, do_clip);
gdk_window_end_draw_frame (window, cr);
}
......@@ -302,6 +302,11 @@ gboolean gtk_widget_query_tooltip (GtkWidget *widget,
gboolean keyboard_mode,
GtkTooltip *tooltip);
void gtk_widget_render (GtkWidget *widget,
GdkWindow *window,
const cairo_region_t *region);
/* inline getters */
static inline gboolean
......
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