[gtk+] Revert "gtkwidget: Widgets are now always double-buffered"
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] Revert "gtkwidget: Widgets are now always double-buffered"
- Date: Mon, 23 Jun 2014 21:56:56 +0000 (UTC)
commit 24b9e91f470d2f355c6e19013f302295151baacf
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Mon Jun 23 17:36:16 2014 -0400
Revert "gtkwidget: Widgets are now always double-buffered"
This reverts commit b875572f2af532b0e8f2dc368f8dc824b5f92724.
Apps like Abiword, gnumeric and gnome-chess, and toolkits like
ClutterGTK were all using this for various purposes, and this made them
break. Bring back this feature for now.
It still won't work under Wayland.
gdk/gdkwindow.c | 4 +++-
gtk/gtkmain.c | 23 +++++++++++++++--------
gtk/gtkwidget.c | 50 ++++++++++++++++++++++++++++++++++++++++++--------
3 files changed, 60 insertions(+), 17 deletions(-)
---
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 6131a04..4e4ec98 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -2706,7 +2706,9 @@ gdk_window_begin_paint_rect (GdkWindow *window,
* #GdkEventExpose has already been cleared to the window background,
* is already set as the clip region, and already has a backing store.
* Therefore in most cases, application code need not call
- * gdk_window_begin_paint_region().
+ * gdk_window_begin_paint_region(). (You can disable the automatic
+ * calls around expose events on a widget-by-widget basis by calling
+ * gtk_widget_set_double_buffered().)
*
* If you call this function multiple times before calling the
* matching gdk_window_end_paint(), the backing stores are pushed onto
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index 7762a63..860c334 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -1647,16 +1647,23 @@ gtk_main_do_event (GdkEvent *event)
break;
case GDK_EXPOSE:
- /* We handle exposes only on native windows, relying on the
- * draw() handler to propagate down to non-native windows.
- * This is ok now that we child windows always are considered
- * (semi)transparent.
- */
- if (event->any.window && gdk_window_has_native (event->expose.window))
+ if (event->any.window && gtk_widget_get_double_buffered (event_widget))
+ {
+ /* We handle exposes only on native windows, relying on the
+ * draw() handler to propagate down to non-native windows.
+ * This is ok now that we child windows always are 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
{
- 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);
}
break;
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index b5dea46..3241575 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -432,6 +432,7 @@ struct _GtkWidgetPrivate
guint shadowed : 1;
guint style_update_pending : 1;
guint app_paintable : 1;
+ guint double_buffered : 1;
guint redraw_on_alloc : 1;
guint no_show_all : 1;
guint child_visible : 1;
@@ -1369,7 +1370,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
*
* Since: 2.18
*
- * Deprecated: 3.14: Widgets are always double-buffered.
+ * Deprecated: 3.14: Widgets should not use this property.
*/
g_object_class_install_property (gobject_class,
PROP_DOUBLE_BUFFERED,
@@ -3812,6 +3813,7 @@ gtk_widget_set_property (GObject *object,
gtk_widget_queue_tooltip_query (widget);
break;
case PROP_DOUBLE_BUFFERED:
+ gtk_widget_set_double_buffered (widget, g_value_get_boolean (value));
break;
case PROP_HALIGN:
gtk_widget_set_halign (widget, g_value_get_enum (value));
@@ -3975,7 +3977,7 @@ gtk_widget_get_property (GObject *object,
g_value_set_object (value, gtk_widget_get_window (widget));
break;
case PROP_DOUBLE_BUFFERED:
- g_value_set_boolean (value, TRUE);
+ g_value_set_boolean (value, gtk_widget_get_double_buffered (widget));
break;
case PROP_HALIGN:
g_value_set_enum (value, gtk_widget_get_halign (widget));
@@ -4377,6 +4379,7 @@ gtk_widget_init (GtkWidget *widget)
priv->sensitive = TRUE;
priv->composite_child = composite_child_stack != 0;
+ priv->double_buffered = TRUE;
priv->redraw_on_alloc = TRUE;
priv->alloc_needed = TRUE;
@@ -6962,8 +6965,11 @@ _gtk_widget_draw_windows (GdkWindow *window,
{
gdk_window_get_user_data (window, (gpointer *) &widget);
+ /* Only clear bg if double bufferer. This is what we used
+ to do before, where begin_paint() did the clearing. */
pattern = gdk_window_get_background_pattern (window);
- if (pattern != NULL)
+ if (pattern != NULL &&
+ widget->priv->double_buffered)
{
cairo_save (cr);
cairo_set_source (cr, pattern);
@@ -9204,9 +9210,30 @@ gtk_widget_get_app_paintable (GtkWidget *widget)
* @widget: a #GtkWidget
* @double_buffered: %TRUE to double-buffer a widget
*
- * This function does nothing.
- *
- * Deprecated: 3.14: Widgets are always double-buffered.
+ * Widgets are double buffered by default; you can use this function
+ * to turn off the buffering. “Double buffered” simply means that
+ * gdk_window_begin_paint_region() and gdk_window_end_paint() are called
+ * automatically around expose events sent to the
+ * widget. gdk_window_begin_paint_region() diverts all drawing to a widget's
+ * window to an offscreen buffer, and gdk_window_end_paint() draws the
+ * buffer to the screen. The result is that users see the window
+ * update in one smooth step, and don’t see individual graphics
+ * primitives being rendered.
+ *
+ * In very simple terms, double buffered widgets don’t flicker,
+ * so you would only use this function to turn off double buffering
+ * if you had special needs and really knew what you were doing.
+ *
+ * Note: if you turn off double-buffering, you have to handle
+ * expose events, since even the clearing to the background color or
+ * pixmap will not happen automatically (as it is done in
+ * gdk_window_begin_paint_region()).
+ *
+ * Since 3.10 this function only works for widgets with native
+ * windows.
+ *
+ * Deprecated: 3.14: This does not work under non-X11 backends,
+ * and it should not be used in newly written code.
**/
void
gtk_widget_set_double_buffered (GtkWidget *widget,
@@ -9214,7 +9241,14 @@ gtk_widget_set_double_buffered (GtkWidget *widget,
{
g_return_if_fail (GTK_IS_WIDGET (widget));
- g_warning ("gtk_widget_set_double_buffered is deprecated and does nothing.");
+ double_buffered = (double_buffered != FALSE);
+
+ if (widget->priv->double_buffered != double_buffered)
+ {
+ widget->priv->double_buffered = double_buffered;
+
+ g_object_notify (G_OBJECT (widget), "double-buffered");
+ }
}
/**
@@ -9234,7 +9268,7 @@ gtk_widget_get_double_buffered (GtkWidget *widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
- return TRUE;
+ return widget->priv->double_buffered;
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]