]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkexpander.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / gtk / gtkexpander.c
index 4e38c8751bce73b6d918e04e6f205419e70bd243..6f6a196a6f4da67b286e615180a7d6a203a4dc39 100644 (file)
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  *
  * Authors:
- *     Mark McLoughlin <mark@skynet.ie>
+ *      Mark McLoughlin <mark@skynet.ie>
+ */
+
+/**
+ * SECTION:gtkexpander
+ * @Short_description: A container which can hide its child
+ * @Title: GtkExpander
+ *
+ * A #GtkExpander allows the user to hide or show its child by clicking
+ * on an expander triangle similar to the triangles used in a #GtkTreeView.
+ *
+ * Normally you use an expander as you would use any other descendant
+ * of #GtkBin; you create the child widget and use gtk_container_add()
+ * to add it to the expander. When the expander is toggled, it will take
+ * care of showing and hiding the child automatically.
+ *
+ * <refsect2 id="expander-special-usage">
+ * <title>Special Usage</title>
+ * <para>
+ * There are situations in which you may prefer to show and hide the
+ * expanded widget yourself, such as when you want to actually create
+ * the widget at expansion time. In this case, create a #GtkExpander
+ * but do not add a child to it. The expander widget has an
+ * #GtkExpander:expanded property which can be used to monitor
+ * its expansion state. You should watch this property with a signal
+ * connection as follows:
+ * </para>
+ * <informalexample>
+ * <programlisting id="expander-callback-example">
+ * expander = gtk_expander_new_with_mnemonic ("_More Options");
+ * g_signal_connect (expander, "notify::expanded",
+ *                   G_CALLBACK (expander_callback), NULL);
+ *
+ * ...
+ *
+ * static void
+ * expander_callback (GObject    *object,
+ *                    GParamSpec *param_spec,
+ *                    gpointer    user_data)
+ * {
+ *   GtkExpander *expander;
+ *
+ *   expander = GTK_EXPANDER (object);
+ *
+ *   if (gtk_expander_get_expanded (expander))
+ *     {
+ *       /&ast; Show or create widgets &ast;/
+ *     }
+ *   else
+ *     {
+ *       /&ast; Hide or destroy widgets &ast;/
+ *     }
+ * }
+ * </programlisting>
+ * </informalexample>
+ * </refsect2>
+ * <refsect2 id="GtkExpander-BUILDER-UI">
+ * <title>GtkExpander as GtkBuildable</title>
+ * <para>
+ * The GtkExpander implementation of the GtkBuildable interface
+ * supports placing a child in the label position by specifying
+ * "label" as the "type" attribute of a &lt;child&gt; element.
+ * A normal content child can be specified without specifying
+ * a &lt;child&gt; type attribute.
+ * </para>
+ * <example>
+ * <title>A UI definition fragment with GtkExpander</title>
+ * <programlisting><![CDATA[
+ * <object class="GtkExpander">
+ *   <child type="label">
+ *     <object class="GtkLabel" id="expander-label"/>
+ *   </child>
+ *   <child>
+ *     <object class="GtkEntry" id="expander-content"/>
+ *   </child>
+ * </object>
+ * ]]></programlisting>
+ * </example>
+ * </refsect2>
+ *
  */
 
 #include "config.h"
+
 #include <string.h>
+
 #include "gtkexpander.h"
 
 #include "gtklabel.h"
 #include "gtkbuildable.h"
-#include "gtksizerequest.h"
 #include "gtkcontainer.h"
 #include "gtkmarshalers.h"
 #include "gtkmain.h"
 #include "gtkintl.h"
 #include "gtkprivate.h"
-#include <gdk/gdkkeysyms.h>
 #include "gtkdnd.h"
+#include "a11y/gtkexpanderaccessible.h"
 
 
 #define DEFAULT_EXPANDER_SIZE 10
@@ -49,7 +127,8 @@ enum
   PROP_USE_MARKUP,
   PROP_SPACING,
   PROP_LABEL_WIDGET,
-  PROP_LABEL_FILL
+  PROP_LABEL_FILL,
+  PROP_RESIZE_TOPLEVEL
 };
 
 struct _GtkExpanderPrivate
@@ -58,8 +137,6 @@ struct _GtkExpanderPrivate
   GdkWindow        *event_window;
   gint              spacing;
 
-  GtkExpanderStyle  expander_style;
-  guint             animation_timeout;
   guint             expand_timer;
 
   guint             expanded : 1;
@@ -68,113 +145,107 @@ struct _GtkExpanderPrivate
   guint             button_down : 1;
   guint             prelight : 1;
   guint             label_fill : 1;
+  guint             resize_toplevel : 1;
 };
 
 static void gtk_expander_set_property (GObject          *object,
-                                      guint             prop_id,
-                                      const GValue     *value,
-                                      GParamSpec       *pspec);
+                                       guint             prop_id,
+                                       const GValue     *value,
+                                       GParamSpec       *pspec);
 static void gtk_expander_get_property (GObject          *object,
-                                      guint             prop_id,
-                                      GValue           *value,
-                                      GParamSpec       *pspec);
-
-static void gtk_expander_destroy (GtkObject *object);
+                                       guint             prop_id,
+                                       GValue           *value,
+                                       GParamSpec       *pspec);
 
+static void     gtk_expander_destroy        (GtkWidget        *widget);
 static void     gtk_expander_realize        (GtkWidget        *widget);
 static void     gtk_expander_unrealize      (GtkWidget        *widget);
 static void     gtk_expander_size_allocate  (GtkWidget        *widget,
-                                            GtkAllocation    *allocation);
+                                             GtkAllocation    *allocation);
 static void     gtk_expander_map            (GtkWidget        *widget);
 static void     gtk_expander_unmap          (GtkWidget        *widget);
 static gboolean gtk_expander_draw           (GtkWidget        *widget,
-                                            cairo_t          *cr);
+                                             cairo_t          *cr);
 static gboolean gtk_expander_button_press   (GtkWidget        *widget,
-                                            GdkEventButton   *event);
+                                             GdkEventButton   *event);
 static gboolean gtk_expander_button_release (GtkWidget        *widget,
-                                            GdkEventButton   *event);
+                                             GdkEventButton   *event);
 static gboolean gtk_expander_enter_notify   (GtkWidget        *widget,
-                                            GdkEventCrossing *event);
+                                             GdkEventCrossing *event);
 static gboolean gtk_expander_leave_notify   (GtkWidget        *widget,
-                                            GdkEventCrossing *event);
+                                             GdkEventCrossing *event);
 static gboolean gtk_expander_focus          (GtkWidget        *widget,
-                                            GtkDirectionType  direction);
+                                             GtkDirectionType  direction);
 static void     gtk_expander_grab_notify    (GtkWidget        *widget,
-                                            gboolean          was_grabbed);
-static void     gtk_expander_state_changed  (GtkWidget        *widget,
-                                            GtkStateType      previous_state);
+                                             gboolean          was_grabbed);
+static void     gtk_expander_state_flags_changed  (GtkWidget     *widget,
+                                                   GtkStateFlags  previous_state);
 static gboolean gtk_expander_drag_motion    (GtkWidget        *widget,
-                                            GdkDragContext   *context,
-                                            gint              x,
-                                            gint              y,
-                                            guint             time);
+                                             GdkDragContext   *context,
+                                             gint              x,
+                                             gint              y,
+                                             guint             time);
 static void     gtk_expander_drag_leave     (GtkWidget        *widget,
-                                            GdkDragContext   *context,
-                                            guint             time);
+                                             GdkDragContext   *context,
+                                             guint             time);
 
 static void gtk_expander_add    (GtkContainer *container,
-                                GtkWidget    *widget);
+                                 GtkWidget    *widget);
 static void gtk_expander_remove (GtkContainer *container,
-                                GtkWidget    *widget);
+                                 GtkWidget    *widget);
 static void gtk_expander_forall (GtkContainer *container,
-                                gboolean        include_internals,
-                                GtkCallback     callback,
-                                gpointer        callback_data);
+                                 gboolean        include_internals,
+                                 GtkCallback     callback,
+                                 gpointer        callback_data);
 
 static void gtk_expander_activate (GtkExpander *expander);
 
 static void get_expander_bounds (GtkExpander  *expander,
-                                GdkRectangle *rect);
+                                 GdkRectangle *rect);
 
 /* GtkBuildable */
 static void gtk_expander_buildable_init           (GtkBuildableIface *iface);
 static void gtk_expander_buildable_add_child      (GtkBuildable *buildable,
-                                                  GtkBuilder   *builder,
-                                                  GObject      *child,
-                                                  const gchar  *type);
-
-
-/* GtkSizeRequest */
-static void  gtk_expander_size_request_init     (GtkSizeRequestIface *iface);
-static void  gtk_expander_get_width             (GtkSizeRequest      *widget,
-                                                gint                *minimum_size,
-                                                gint                *natural_size);
-static void  gtk_expander_get_height            (GtkSizeRequest      *widget,
-                                                gint                *minimum_size,
-                                                gint                *natural_size);
-static void  gtk_expander_get_height_for_width  (GtkSizeRequest      *layout,
-                                                gint                 width,
-                                                gint                *minimum_height,
-                                                gint                *natural_height);
-static void  gtk_expander_get_width_for_height  (GtkSizeRequest      *layout,
-                                                gint                 width,
-                                                gint                *minimum_height,
-                                                gint                *natural_height);
+                                                   GtkBuilder   *builder,
+                                                   GObject      *child,
+                                                   const gchar  *type);
+
+
+/* GtkWidget      */
+static void  gtk_expander_get_preferred_width             (GtkWidget           *widget,
+                                                           gint                *minimum_size,
+                                                           gint                *natural_size);
+static void  gtk_expander_get_preferred_height            (GtkWidget           *widget,
+                                                           gint                *minimum_size,
+                                                           gint                *natural_size);
+static void  gtk_expander_get_preferred_height_for_width  (GtkWidget           *layout,
+                                                           gint                 width,
+                                                           gint                *minimum_height,
+                                                           gint                *natural_height);
+static void  gtk_expander_get_preferred_width_for_height  (GtkWidget           *layout,
+                                                           gint                 width,
+                                                           gint                *minimum_height,
+                                                           gint                *natural_height);
 
 G_DEFINE_TYPE_WITH_CODE (GtkExpander, gtk_expander, GTK_TYPE_BIN,
-                        G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
-                                               gtk_expander_buildable_init)
-                         G_IMPLEMENT_INTERFACE (GTK_TYPE_SIZE_REQUEST,
-                                                gtk_expander_size_request_init))
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+                                                gtk_expander_buildable_init))
 
 static void
 gtk_expander_class_init (GtkExpanderClass *klass)
 {
   GObjectClass *gobject_class;
-  GtkObjectClass *object_class;
   GtkWidgetClass *widget_class;
   GtkContainerClass *container_class;
 
   gobject_class   = (GObjectClass *) klass;
-  object_class    = (GtkObjectClass *) klass;
   widget_class    = (GtkWidgetClass *) klass;
   container_class = (GtkContainerClass *) klass;
 
   gobject_class->set_property = gtk_expander_set_property;
   gobject_class->get_property = gtk_expander_get_property;
 
-  object_class->destroy = gtk_expander_destroy;
-
+  widget_class->destroy              = gtk_expander_destroy;
   widget_class->realize              = gtk_expander_realize;
   widget_class->unrealize            = gtk_expander_unrealize;
   widget_class->size_allocate        = gtk_expander_size_allocate;
@@ -187,9 +258,13 @@ gtk_expander_class_init (GtkExpanderClass *klass)
   widget_class->leave_notify_event   = gtk_expander_leave_notify;
   widget_class->focus                = gtk_expander_focus;
   widget_class->grab_notify          = gtk_expander_grab_notify;
-  widget_class->state_changed        = gtk_expander_state_changed;
+  widget_class->state_flags_changed  = gtk_expander_state_flags_changed;
   widget_class->drag_motion          = gtk_expander_drag_motion;
   widget_class->drag_leave           = gtk_expander_drag_leave;
+  widget_class->get_preferred_width            = gtk_expander_get_preferred_width;
+  widget_class->get_preferred_height           = gtk_expander_get_preferred_height;
+  widget_class->get_preferred_height_for_width = gtk_expander_get_preferred_height_for_width;
+  widget_class->get_preferred_width_for_height = gtk_expander_get_preferred_width_for_height;
 
   container_class->add    = gtk_expander_add;
   container_class->remove = gtk_expander_remove;
@@ -200,89 +275,107 @@ gtk_expander_class_init (GtkExpanderClass *klass)
   g_type_class_add_private (klass, sizeof (GtkExpanderPrivate));
 
   g_object_class_install_property (gobject_class,
-                                  PROP_EXPANDED,
-                                  g_param_spec_boolean ("expanded",
-                                                        P_("Expanded"),
-                                                        P_("Whether the expander has been opened to reveal the child widget"),
-                                                        FALSE,
-                                                        GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+                                   PROP_EXPANDED,
+                                   g_param_spec_boolean ("expanded",
+                                                         P_("Expanded"),
+                                                         P_("Whether the expander has been opened to reveal the child widget"),
+                                                         FALSE,
+                                                         GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
-                                  PROP_LABEL,
-                                  g_param_spec_string ("label",
-                                                       P_("Label"),
-                                                       P_("Text of the expander's label"),
-                                                       NULL,
-                                                       GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+                                   PROP_LABEL,
+                                   g_param_spec_string ("label",
+                                                        P_("Label"),
+                                                        P_("Text of the expander's label"),
+                                                        NULL,
+                                                        GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
-                                  PROP_USE_UNDERLINE,
-                                  g_param_spec_boolean ("use-underline",
-                                                        P_("Use underline"),
-                                                        P_("If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key"),
-                                                        FALSE,
-                                                        GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+                                   PROP_USE_UNDERLINE,
+                                   g_param_spec_boolean ("use-underline",
+                                                         P_("Use underline"),
+                                                         P_("If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key"),
+                                                         FALSE,
+                                                         GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
-                                  PROP_USE_MARKUP,
-                                  g_param_spec_boolean ("use-markup",
-                                                        P_("Use markup"),
-                                                        P_("The text of the label includes XML markup. See pango_parse_markup()"),
-                                                        FALSE,
-                                                        GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+                                   PROP_USE_MARKUP,
+                                   g_param_spec_boolean ("use-markup",
+                                                         P_("Use markup"),
+                                                         P_("The text of the label includes XML markup. See pango_parse_markup()"),
+                                                         FALSE,
+                                                         GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
-                                  PROP_SPACING,
-                                  g_param_spec_int ("spacing",
-                                                    P_("Spacing"),
-                                                    P_("Space to put between the label and the child"),
-                                                    0,
-                                                    G_MAXINT,
-                                                    0,
-                                                    GTK_PARAM_READWRITE));
+                                   PROP_SPACING,
+                                   g_param_spec_int ("spacing",
+                                                     P_("Spacing"),
+                                                     P_("Space to put between the label and the child"),
+                                                     0,
+                                                     G_MAXINT,
+                                                     0,
+                                                     GTK_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class,
-                                  PROP_LABEL_WIDGET,
-                                  g_param_spec_object ("label-widget",
-                                                       P_("Label widget"),
-                                                       P_("A widget to display in place of the usual expander label"),
-                                                       GTK_TYPE_WIDGET,
-                                                       GTK_PARAM_READWRITE));
+                                   PROP_LABEL_WIDGET,
+                                   g_param_spec_object ("label-widget",
+                                                        P_("Label widget"),
+                                                        P_("A widget to display in place of the usual expander label"),
+                                                        GTK_TYPE_WIDGET,
+                                                        GTK_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class,
-                                  PROP_LABEL_FILL,
-                                  g_param_spec_boolean ("label-fill",
-                                                        P_("Label fill"),
-                                                        P_("Whether the label widget should fill all available horizontal space"),
-                                                        FALSE,
-                                                        GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+                                   PROP_LABEL_FILL,
+                                   g_param_spec_boolean ("label-fill",
+                                                         P_("Label fill"),
+                                                         P_("Whether the label widget should fill all available horizontal space"),
+                                                         FALSE,
+                                                         GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+  /**
+   * GtkExpander:resize-toplevel:
+   *
+   * When this property is %TRUE, the expander will resize the toplevel
+   * widget containing the expander upon expanding and collapsing.
+   *
+   * Since: 3.2
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_RESIZE_TOPLEVEL,
+                                   g_param_spec_boolean ("resize-toplevel",
+                                                         P_("Resize toplevel"),
+                                                         P_("Whether the expander will resize the toplevel window upon expanding and collapsing"),
+                                                         FALSE,
+                                                         GTK_PARAM_READWRITE));
 
   gtk_widget_class_install_style_property (widget_class,
-                                          g_param_spec_int ("expander-size",
-                                                            P_("Expander Size"),
-                                                            P_("Size of the expander arrow"),
-                                                            0,
-                                                            G_MAXINT,
-                                                            DEFAULT_EXPANDER_SIZE,
-                                                            GTK_PARAM_READABLE));
+                                           g_param_spec_int ("expander-size",
+                                                             P_("Expander Size"),
+                                                             P_("Size of the expander arrow"),
+                                                             0,
+                                                             G_MAXINT,
+                                                             DEFAULT_EXPANDER_SIZE,
+                                                             GTK_PARAM_READABLE));
 
   gtk_widget_class_install_style_property (widget_class,
-                                          g_param_spec_int ("expander-spacing",
-                                                            P_("Indicator Spacing"),
-                                                            P_("Spacing around expander arrow"),
-                                                            0,
-                                                            G_MAXINT,
-                                                            DEFAULT_EXPANDER_SPACING,
-                                                            GTK_PARAM_READABLE));
+                                           g_param_spec_int ("expander-spacing",
+                                                             P_("Indicator Spacing"),
+                                                             P_("Spacing around expander arrow"),
+                                                             0,
+                                                             G_MAXINT,
+                                                             DEFAULT_EXPANDER_SPACING,
+                                                             GTK_PARAM_READABLE));
 
   widget_class->activate_signal =
     g_signal_new (I_("activate"),
-                 G_TYPE_FROM_CLASS (gobject_class),
-                 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-                 G_STRUCT_OFFSET (GtkExpanderClass, activate),
-                 NULL, NULL,
-                 _gtk_marshal_VOID__VOID,
-                 G_TYPE_NONE, 0);
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                  G_STRUCT_OFFSET (GtkExpanderClass, activate),
+                  NULL, NULL,
+                  _gtk_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+
+  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_EXPANDER_ACCESSIBLE);
 }
 
 static void
@@ -301,9 +394,6 @@ gtk_expander_init (GtkExpander *expander)
   priv->event_window = NULL;
   priv->spacing = 0;
 
-  priv->expander_style = GTK_EXPANDER_COLLAPSED;
-  priv->animation_timeout = 0;
-
   priv->expanded = FALSE;
   priv->use_underline = FALSE;
   priv->use_markup = FALSE;
@@ -311,6 +401,7 @@ gtk_expander_init (GtkExpander *expander)
   priv->prelight = FALSE;
   priv->label_fill = FALSE;
   priv->expand_timer = 0;
+  priv->resize_toplevel = 0;
 
   gtk_drag_dest_set (GTK_WIDGET (expander), 0, NULL, 0, 0);
   gtk_drag_dest_set_track_motion (GTK_WIDGET (expander), TRUE);
@@ -318,9 +409,9 @@ gtk_expander_init (GtkExpander *expander)
 
 static void
 gtk_expander_buildable_add_child (GtkBuildable  *buildable,
-                                 GtkBuilder    *builder,
-                                 GObject       *child,
-                                 const gchar   *type)
+                                  GtkBuilder    *builder,
+                                  GObject       *child,
+                                  const gchar   *type)
 {
   if (!type)
     gtk_container_add (GTK_CONTAINER (buildable), GTK_WIDGET (child));
@@ -338,12 +429,12 @@ gtk_expander_buildable_init (GtkBuildableIface *iface)
 
 static void
 gtk_expander_set_property (GObject      *object,
-                          guint         prop_id,
-                          const GValue *value,
-                          GParamSpec   *pspec)
+                           guint         prop_id,
+                           const GValue *value,
+                           GParamSpec   *pspec)
 {
   GtkExpander *expander = GTK_EXPANDER (object);
-                                                                                                             
+
   switch (prop_id)
     {
     case PROP_EXPANDED:
@@ -367,6 +458,9 @@ gtk_expander_set_property (GObject      *object,
     case PROP_LABEL_FILL:
       gtk_expander_set_label_fill (expander, g_value_get_boolean (value));
       break;
+    case PROP_RESIZE_TOPLEVEL:
+      gtk_expander_set_resize_toplevel (expander, g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -375,9 +469,9 @@ gtk_expander_set_property (GObject      *object,
 
 static void
 gtk_expander_get_property (GObject    *object,
-                          guint       prop_id,
-                          GValue     *value,
-                          GParamSpec *pspec)
+                           guint       prop_id,
+                           GValue     *value,
+                           GParamSpec *pspec)
 {
   GtkExpander *expander = GTK_EXPANDER (object);
   GtkExpanderPrivate *priv = expander->priv;
@@ -401,12 +495,15 @@ gtk_expander_get_property (GObject    *object,
       break;
     case PROP_LABEL_WIDGET:
       g_value_set_object (value,
-                         priv->label_widget ?
-                         G_OBJECT (priv->label_widget) : NULL);
+                          priv->label_widget ?
+                          G_OBJECT (priv->label_widget) : NULL);
       break;
     case PROP_LABEL_FILL:
       g_value_set_boolean (value, priv->label_fill);
       break;
+    case PROP_RESIZE_TOPLEVEL:
+      g_value_set_boolean (value, gtk_expander_get_resize_toplevel (expander));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -414,17 +511,17 @@ gtk_expander_get_property (GObject    *object,
 }
 
 static void
-gtk_expander_destroy (GtkObject *object)
+gtk_expander_destroy (GtkWidget *widget)
 {
-  GtkExpanderPrivate *priv = GTK_EXPANDER (object)->priv;
-  
-  if (priv->animation_timeout)
+  GtkExpanderPrivate *priv = GTK_EXPANDER (widget)->priv;
+
+  if (priv->expand_timer)
     {
-      g_source_remove (priv->animation_timeout);
-      priv->animation_timeout = 0;
+      g_source_remove (priv->expand_timer);
+      priv->expand_timer = 0;
     }
-  
-  GTK_OBJECT_CLASS (gtk_expander_parent_class)->destroy (object);
+
+  GTK_WIDGET_CLASS (gtk_expander_parent_class)->destroy (widget);
 }
 
 static void
@@ -446,13 +543,13 @@ gtk_expander_realize (GtkWidget *widget)
   border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
 
   get_expander_bounds (GTK_EXPANDER (widget), &expander_rect);
-  
+
   if (priv->label_widget && gtk_widget_get_visible (priv->label_widget))
     {
       GtkRequisition label_requisition;
 
-      gtk_size_request_get_size (GTK_SIZE_REQUEST (priv->label_widget),
-                                 &label_requisition, NULL);
+      gtk_widget_get_preferred_size (priv->label_widget,
+                                     &label_requisition, NULL);
       label_height = label_requisition.height;
     }
   else
@@ -466,11 +563,11 @@ gtk_expander_realize (GtkWidget *widget)
   attributes.width = MAX (allocation.width - 2 * border_width, 1);
   attributes.height = MAX (expander_rect.height, label_height - 2 * border_width);
   attributes.wclass = GDK_INPUT_ONLY;
-  attributes.event_mask = gtk_widget_get_events (widget)     |
-                               GDK_BUTTON_PRESS_MASK        |
-                               GDK_BUTTON_RELEASE_MASK      |
-                               GDK_ENTER_NOTIFY_MASK        |
-                               GDK_LEAVE_NOTIFY_MASK;
+  attributes.event_mask = gtk_widget_get_events (widget)
+                          | GDK_BUTTON_PRESS_MASK
+                          | GDK_BUTTON_RELEASE_MASK
+                          | GDK_ENTER_NOTIFY_MASK
+                          | GDK_LEAVE_NOTIFY_MASK;
 
   attributes_mask = GDK_WA_X | GDK_WA_Y;
 
@@ -479,10 +576,8 @@ gtk_expander_realize (GtkWidget *widget)
   g_object_ref (window);
 
   priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
-                                      &attributes, attributes_mask);
-  gdk_window_set_user_data (priv->event_window, widget);
-
-  gtk_widget_style_attach (widget);
+                                       &attributes, attributes_mask);
+  gtk_widget_register_window (widget, priv->event_window);
 }
 
 static void
@@ -492,7 +587,7 @@ gtk_expander_unrealize (GtkWidget *widget)
 
   if (priv->event_window)
     {
-      gdk_window_set_user_data (priv->event_window, NULL);
+      gtk_widget_unregister_window (widget, priv->event_window);
       gdk_window_destroy (priv->event_window);
       priv->event_window = NULL;
     }
@@ -502,7 +597,7 @@ gtk_expander_unrealize (GtkWidget *widget)
 
 static void
 get_expander_bounds (GtkExpander  *expander,
-                    GdkRectangle *rect)
+                     GdkRectangle *rect)
 {
   GtkAllocation allocation;
   GtkWidget *widget;
@@ -523,12 +618,12 @@ get_expander_bounds (GtkExpander  *expander,
   border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
 
   gtk_widget_style_get (widget,
-                       "interior-focus", &interior_focus,
-                       "focus-line-width", &focus_width,
-                       "focus-padding", &focus_pad,
-                       "expander-size", &expander_size,
-                       "expander-spacing", &expander_spacing,
-                       NULL);
+                        "interior-focus", &interior_focus,
+                        "focus-line-width", &focus_width,
+                        "focus-padding", &focus_pad,
+                        "expander-size", &expander_size,
+                        "expander-spacing", &expander_spacing,
+                        NULL);
 
   ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;
 
@@ -548,9 +643,9 @@ get_expander_bounds (GtkExpander  *expander,
       gtk_widget_get_allocation (priv->label_widget, &label_allocation);
 
       if (expander_size < label_allocation.height)
-       rect->y += focus_width + focus_pad + (label_allocation.height - expander_size) / 2;
+        rect->y += focus_width + focus_pad + (label_allocation.height - expander_size) / 2;
       else
-       rect->y += expander_spacing;
+        rect->y += expander_spacing;
     }
   else
     {
@@ -560,9 +655,9 @@ get_expander_bounds (GtkExpander  *expander,
   if (!interior_focus)
     {
       if (ltr)
-       rect->x += focus_width + focus_pad;
+        rect->x += focus_width + focus_pad;
       else
-       rect->x -= focus_width + focus_pad;
+        rect->x -= focus_width + focus_pad;
       rect->y += focus_width + focus_pad;
     }
 
@@ -571,7 +666,7 @@ get_expander_bounds (GtkExpander  *expander,
 
 static void
 gtk_expander_size_allocate (GtkWidget     *widget,
-                           GtkAllocation *allocation)
+                            GtkAllocation *allocation)
 {
   GtkExpander *expander;
   GtkWidget *child;
@@ -596,12 +691,12 @@ gtk_expander_size_allocate (GtkWidget     *widget,
   gtk_widget_set_allocation (widget, allocation);
 
   gtk_widget_style_get (widget,
-                       "interior-focus", &interior_focus,
-                       "focus-line-width", &focus_width,
-                       "focus-padding", &focus_pad,
-                       "expander-size", &expander_size,
-                       "expander-spacing", &expander_spacing,
-                       NULL);
+                        "interior-focus", &interior_focus,
+                        "focus-line-width", &focus_width,
+                        "focus-padding", &focus_pad,
+                        "expander-size", &expander_size,
+                        "expander-spacing", &expander_spacing,
+                        NULL);
 
 
   /* Calculate some offsets/padding first */
@@ -612,7 +707,7 @@ gtk_expander_size_allocate (GtkWidget     *widget,
   child_ypad     = 2 * border_width + priv->spacing + (interior_focus ? 0 : 2 * focus_width + 2 * focus_pad);
   top_min_height = 2 * expander_spacing + expander_size;
 
-  child_visible = (child && GTK_WIDGET_CHILD_VISIBLE (child));
+  child_visible = (child && gtk_widget_get_child_visible (child));
 
   if (priv->label_widget && gtk_widget_get_visible (priv->label_widget))
     {
@@ -620,7 +715,7 @@ gtk_expander_size_allocate (GtkWidget     *widget,
       gint          natural_label_width;
       gboolean ltr;
 
-      gtk_size_request_get_width (GTK_SIZE_REQUEST (priv->label_widget), NULL, &natural_label_width);
+      gtk_widget_get_preferred_width (priv->label_widget, NULL, &natural_label_width);
 
       if (priv->label_fill)
         label_allocation.width = allocation->width - label_xpad;
@@ -629,9 +724,10 @@ gtk_expander_size_allocate (GtkWidget     *widget,
       label_allocation.width = MAX (label_allocation.width, 1);
 
       /* We distribute the minimum height to the label widget and prioritize
-       * the child widget giving it the remaining height */
-      gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (priv->label_widget),
-                                            label_allocation.width, &label_height, NULL);
+       * the child widget giving it the remaining height
+       */
+      gtk_widget_get_preferred_height_for_width (priv->label_widget,
+                                                 label_allocation.width, &label_height, NULL);
 
       ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;
 
@@ -645,9 +741,9 @@ gtk_expander_size_allocate (GtkWidget     *widget,
 
       label_allocation.y = allocation->y + border_width + focus_width + focus_pad;
       label_allocation.height = MIN (label_height,
-                                    allocation->height - 2 * border_width -
-                                    2 * focus_width - 2 * focus_pad -
-                                    (child_visible ? priv->spacing : 0));
+                                     allocation->height - 2 * border_width -
+                                     2 * focus_width - 2 * focus_pad -
+                                     (child_visible ? priv->spacing : 0));
       label_allocation.height = MAX (label_allocation.height, 1);
 
       gtk_widget_size_allocate (priv->label_widget, &label_allocation);
@@ -666,10 +762,10 @@ gtk_expander_size_allocate (GtkWidget     *widget,
       get_expander_bounds (expander, &rect);
 
       gdk_window_move_resize (priv->event_window,
-                             allocation->x + border_width,
-                             allocation->y + border_width,
-                             MAX (allocation->width - 2 * border_width, 1),
-                             MAX (rect.height, label_height - 2 * border_width));
+                              allocation->x + border_width,
+                              allocation->y + border_width,
+                              MAX (allocation->width - 2 * border_width, 1),
+                              MAX (rect.height, label_height - 2 * border_width));
     }
 
   if (child_visible)
@@ -678,7 +774,7 @@ gtk_expander_size_allocate (GtkWidget     *widget,
       gint top_height;
 
       top_height = MAX (top_min_height,
-                       label_height + (interior_focus ? 2 * focus_width + 2 * focus_pad : 0));
+                        label_height + (interior_focus ? 2 * focus_width + 2 * focus_pad : 0));
 
       child_allocation.x = allocation->x + border_width;
       child_allocation.y = allocation->y + top_height + child_yoffset;
@@ -720,13 +816,15 @@ gtk_expander_unmap (GtkWidget *widget)
 }
 
 static void
-gtk_expander_paint_prelight (GtkExpander *expander, cairo_t *cr)
+gtk_expander_paint_prelight (GtkExpander *expander,
+                             cairo_t     *cr)
 {
   GtkAllocation allocation;
   GtkWidget *widget;
   GtkContainer *container;
   GtkExpanderPrivate *priv;
   GdkRectangle area;
+  GtkStyleContext *context;
   gboolean interior_focus;
   int focus_width;
   int focus_pad;
@@ -739,12 +837,12 @@ gtk_expander_paint_prelight (GtkExpander *expander, cairo_t *cr)
   container = GTK_CONTAINER (expander);
 
   gtk_widget_style_get (widget,
-                       "interior-focus", &interior_focus,
-                       "focus-line-width", &focus_width,
-                       "focus-padding", &focus_pad,
-                       "expander-size", &expander_size,
-                       "expander-spacing", &expander_spacing,
-                       NULL);
+                        "interior-focus", &interior_focus,
+                        "focus-line-width", &focus_width,
+                        "focus-padding", &focus_pad,
+                        "expander-size", &expander_size,
+                        "expander-spacing", &expander_spacing,
+                        NULL);
 
   gtk_widget_get_allocation (widget, &allocation);
 
@@ -767,53 +865,68 @@ gtk_expander_paint_prelight (GtkExpander *expander, cairo_t *cr)
   area.height = MAX (area.height, expander_size + 2 * expander_spacing);
   area.height += !interior_focus ? (focus_width + focus_pad) * 2 : 0;
 
-  gtk_paint_flat_box (gtk_widget_get_style (widget),
-                      cr,
-                     GTK_STATE_PRELIGHT,
-                     GTK_SHADOW_ETCHED_OUT,
-                     widget, "expander",
-                     area.x, area.y,
-                     area.width, area.height);
+  context = gtk_widget_get_style_context (widget);
+  gtk_render_background (context, cr,
+                         area.x, area.y,
+                         area.width, area.height);
 }
 
 static void
-gtk_expander_paint (GtkExpander *expander, cairo_t *cr)
+gtk_expander_paint (GtkExpander *expander,
+                    cairo_t     *cr)
 {
+  GtkExpanderPrivate *priv = expander->priv;
   GtkWidget *widget;
   GdkRectangle clip;
   GtkAllocation allocation;
-  GtkStateType state;
+  GtkStyleContext *context;
+  GtkStateFlags state = 0;
+  gint size;
 
   widget = GTK_WIDGET (expander);
+  context = gtk_widget_get_style_context (widget);
+  state = gtk_widget_get_state_flags (widget);
 
   get_expander_bounds (expander, &clip);
   gtk_widget_get_allocation (widget, &allocation);
 
-  state = gtk_widget_get_state (widget);
+  gtk_style_context_save (context);
+
+  state &= ~(GTK_STATE_FLAG_PRELIGHT);
   if (expander->priv->prelight)
     {
-      state = GTK_STATE_PRELIGHT;
-
+      state |= GTK_STATE_FLAG_PRELIGHT;
+      gtk_style_context_set_state (context, state);
       gtk_expander_paint_prelight (expander, cr);
     }
 
-  gtk_paint_expander (gtk_widget_get_style (widget),
-                     cr,
-                     state,
-                     widget,
-                     "expander",
-                     clip.x + clip.width / 2 - allocation.x,
-                     clip.y + clip.height / 2 - allocation.y,
-                     expander->priv->expander_style);
+  gtk_widget_style_get (widget, "expander-size", &size, NULL);
+
+  /* Set active flag as per the expanded state */
+  if (priv->expanded)
+    state |= GTK_STATE_FLAG_ACTIVE;
+  else
+    state &= ~(GTK_STATE_FLAG_ACTIVE);
+
+  gtk_style_context_set_state (context, state);
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_EXPANDER);
+
+  gtk_render_expander (context, cr,
+                       clip.x - allocation.x,
+                       clip.y - allocation.y,
+                       size, size);
+
+  gtk_style_context_restore (context);
 }
 
 static void
 gtk_expander_paint_focus (GtkExpander *expander,
-                         cairo_t     *cr)
+                          cairo_t     *cr)
 {
   GtkWidget *widget;
   GtkExpanderPrivate *priv;
   GdkRectangle rect;
+  GtkStyleContext *context;
   gint x, y, width, height;
   gboolean interior_focus;
   gint border_width;
@@ -831,27 +944,27 @@ gtk_expander_paint_focus (GtkExpander *expander,
   gtk_widget_get_allocation (widget, &allocation);
 
   gtk_widget_style_get (widget,
-                       "interior-focus", &interior_focus,
-                       "focus-line-width", &focus_width,
-                       "focus-padding", &focus_pad,
-                       "expander-size", &expander_size,
-                       "expander-spacing", &expander_spacing,
-                       NULL);
+                        "interior-focus", &interior_focus,
+                        "focus-line-width", &focus_width,
+                        "focus-padding", &focus_pad,
+                        "expander-size", &expander_size,
+                        "expander-spacing", &expander_spacing,
+                        NULL);
 
   ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;
-  
+
   width = height = 0;
 
   if (priv->label_widget)
     {
       if (gtk_widget_get_visible (priv->label_widget))
-       {
-         GtkAllocation label_allocation;
+        {
+          GtkAllocation label_allocation;
 
-         gtk_widget_get_allocation (priv->label_widget, &label_allocation);
-         width  = label_allocation.width;
-         height = label_allocation.height;
-       }
+          gtk_widget_get_allocation (priv->label_widget, &label_allocation);
+          width  = label_allocation.width;
+          height = label_allocation.height;
+        }
 
       width  += 2 * focus_pad + 2 * focus_width;
       height += 2 * focus_pad + 2 * focus_width;
@@ -860,21 +973,21 @@ gtk_expander_paint_focus (GtkExpander *expander,
       y = border_width;
 
       if (ltr)
-       {
-         if (interior_focus)
-           x += expander_spacing * 2 + expander_size;
-       }
+        {
+          if (interior_focus)
+            x += expander_spacing * 2 + expander_size;
+        }
       else
-       {
-         x += allocation.width - 2 * border_width
-           - expander_spacing * 2 - expander_size - width;
-       }
+        {
+          x += allocation.width - 2 * border_width
+            - expander_spacing * 2 - expander_size - width;
+        }
 
       if (!interior_focus)
-       {
-         width += expander_size + 2 * expander_spacing;
-         height = MAX (height, expander_size + 2 * expander_spacing);
-       }
+        {
+          width += expander_size + 2 * expander_spacing;
+          height = MAX (height, expander_size + 2 * expander_spacing);
+        }
     }
   else
     {
@@ -886,22 +999,20 @@ gtk_expander_paint_focus (GtkExpander *expander,
       height = rect.height + 2 * focus_pad;
     }
 
-  gtk_paint_focus (gtk_widget_get_style (widget),
-                   cr,
-                   gtk_widget_get_state (widget),
-                  widget, "expander",
-                  x, y, width, height);
+  context = gtk_widget_get_style_context (widget);
+  gtk_render_focus (context, cr,
+                    x, y, width, height);
 }
 
 static gboolean
 gtk_expander_draw (GtkWidget *widget,
-                  cairo_t   *cr)
+                   cairo_t   *cr)
 {
   GtkExpander *expander = GTK_EXPANDER (widget);
 
   gtk_expander_paint (expander, cr);
 
-  if (gtk_widget_has_focus (widget))
+  if (gtk_widget_has_visible_focus (widget))
     gtk_expander_paint_focus (expander, cr);
 
   GTK_WIDGET_CLASS (gtk_expander_parent_class)->draw (widget, cr);
@@ -911,11 +1022,11 @@ gtk_expander_draw (GtkWidget *widget,
 
 static gboolean
 gtk_expander_button_press (GtkWidget      *widget,
-                          GdkEventButton *event)
+                           GdkEventButton *event)
 {
   GtkExpander *expander = GTK_EXPANDER (widget);
 
-  if (event->button == 1 && event->window == expander->priv->event_window)
+  if (event->button == GDK_BUTTON_PRIMARY && event->window == expander->priv->event_window)
     {
       expander->priv->button_down = TRUE;
       return TRUE;
@@ -926,11 +1037,11 @@ gtk_expander_button_press (GtkWidget      *widget,
 
 static gboolean
 gtk_expander_button_release (GtkWidget      *widget,
-                            GdkEventButton *event)
+                             GdkEventButton *event)
 {
   GtkExpander *expander = GTK_EXPANDER (widget);
 
-  if (event->button == 1 && expander->priv->button_down)
+  if (event->button == GDK_BUTTON_PRIMARY && expander->priv->button_down)
     {
       gtk_widget_activate (widget);
       expander->priv->button_down = FALSE;
@@ -942,15 +1053,15 @@ gtk_expander_button_release (GtkWidget      *widget,
 
 static void
 gtk_expander_grab_notify (GtkWidget *widget,
-                         gboolean   was_grabbed)
+                          gboolean   was_grabbed)
 {
   if (!was_grabbed)
     GTK_EXPANDER (widget)->priv->button_down = FALSE;
 }
 
 static void
-gtk_expander_state_changed (GtkWidget    *widget,
-                           GtkStateType  previous_state)
+gtk_expander_state_flags_changed (GtkWidget    *widget,
+                                  GtkStateFlags  previous_state)
 {
   if (!gtk_widget_is_sensitive (widget))
     GTK_EXPANDER (widget)->priv->button_down = FALSE;
@@ -971,20 +1082,19 @@ gtk_expander_redraw_expander (GtkExpander *expander)
 
 static gboolean
 gtk_expander_enter_notify (GtkWidget        *widget,
-                          GdkEventCrossing *event)
+                           GdkEventCrossing *event)
 {
   GtkExpander *expander = GTK_EXPANDER (widget);
-  GtkWidget *event_widget;
-
-  event_widget = gtk_get_event_widget ((GdkEvent *) event);
 
-  if (event_widget == widget &&
+  if (event->window == expander->priv->event_window &&
       event->detail != GDK_NOTIFY_INFERIOR)
     {
       expander->priv->prelight = TRUE;
 
       if (expander->priv->label_widget)
-       gtk_widget_set_state (expander->priv->label_widget, GTK_STATE_PRELIGHT);
+        gtk_widget_set_state_flags (expander->priv->label_widget,
+                                    GTK_STATE_FLAG_PRELIGHT,
+                                    FALSE);
 
       gtk_expander_redraw_expander (expander);
     }
@@ -994,20 +1104,18 @@ gtk_expander_enter_notify (GtkWidget        *widget,
 
 static gboolean
 gtk_expander_leave_notify (GtkWidget        *widget,
-                          GdkEventCrossing *event)
+                           GdkEventCrossing *event)
 {
   GtkExpander *expander = GTK_EXPANDER (widget);
-  GtkWidget *event_widget;
-
-  event_widget = gtk_get_event_widget ((GdkEvent *) event);
 
-  if (event_widget == widget &&
+  if (event->window == expander->priv->event_window &&
       event->detail != GDK_NOTIFY_INFERIOR)
     {
       expander->priv->prelight = FALSE;
 
       if (expander->priv->label_widget)
-       gtk_widget_set_state (expander->priv->label_widget, GTK_STATE_NORMAL);
+        gtk_widget_unset_state_flags (expander->priv->label_widget,
+                                      GTK_STATE_FLAG_PRELIGHT);
 
       gtk_expander_redraw_expander (expander);
     }
@@ -1029,10 +1137,10 @@ expand_timeout (gpointer data)
 
 static gboolean
 gtk_expander_drag_motion (GtkWidget        *widget,
-                         GdkDragContext   *context,
-                         gint              x,
-                         gint              y,
-                         guint             time)
+                          GdkDragContext   *context,
+                          gint              x,
+                          gint              y,
+                          guint             time)
 {
   GtkExpander *expander = GTK_EXPANDER (widget);
   GtkExpanderPrivate *priv = expander->priv;
@@ -1053,8 +1161,8 @@ gtk_expander_drag_motion (GtkWidget        *widget,
 
 static void
 gtk_expander_drag_leave (GtkWidget      *widget,
-                        GdkDragContext *context,
-                        guint           time)
+                         GdkDragContext *context,
+                         guint           time)
 {
   GtkExpander *expander = GTK_EXPANDER (widget);
   GtkExpanderPrivate *priv = expander->priv;
@@ -1076,7 +1184,7 @@ typedef enum
 
 static gboolean
 focus_current_site (GtkExpander      *expander,
-                   GtkDirectionType  direction)
+                    GtkDirectionType  direction)
 {
   GtkWidget *current_focus;
 
@@ -1090,8 +1198,8 @@ focus_current_site (GtkExpander      *expander,
 
 static gboolean
 focus_in_site (GtkExpander      *expander,
-              FocusSite         site,
-              GtkDirectionType  direction)
+               FocusSite         site,
+               GtkDirectionType  direction)
 {
   switch (site)
     {
@@ -1100,17 +1208,17 @@ focus_in_site (GtkExpander      *expander,
       return TRUE;
     case FOCUS_LABEL:
       if (expander->priv->label_widget)
-       return gtk_widget_child_focus (expander->priv->label_widget, direction);
+        return gtk_widget_child_focus (expander->priv->label_widget, direction);
       else
-       return FALSE;
+        return FALSE;
     case FOCUS_CHILD:
       {
-       GtkWidget *child = gtk_bin_get_child (GTK_BIN (expander));
+        GtkWidget *child = gtk_bin_get_child (GTK_BIN (expander));
 
-       if (child && GTK_WIDGET_CHILD_VISIBLE (child))
-         return gtk_widget_child_focus (child, direction);
-       else
-         return FALSE;
+        if (child && gtk_widget_get_child_visible (child))
+          return gtk_widget_child_focus (child, direction);
+        else
+          return FALSE;
       }
     case FOCUS_NONE:
       break;
@@ -1122,8 +1230,8 @@ focus_in_site (GtkExpander      *expander,
 
 static FocusSite
 get_next_site (GtkExpander      *expander,
-              FocusSite         site,
-              GtkDirectionType  direction)
+               FocusSite         site,
+               GtkDirectionType  direction)
 {
   gboolean ltr;
 
@@ -1133,91 +1241,134 @@ get_next_site (GtkExpander      *expander,
     {
     case FOCUS_NONE:
       switch (direction)
-       {
-       case GTK_DIR_TAB_BACKWARD:
-       case GTK_DIR_LEFT:
-       case GTK_DIR_UP:
-         return FOCUS_CHILD;
-       case GTK_DIR_TAB_FORWARD:
-       case GTK_DIR_DOWN:
-       case GTK_DIR_RIGHT:
-         return FOCUS_WIDGET;
-       }
+        {
+        case GTK_DIR_TAB_BACKWARD:
+        case GTK_DIR_LEFT:
+        case GTK_DIR_UP:
+          return FOCUS_CHILD;
+        case GTK_DIR_TAB_FORWARD:
+        case GTK_DIR_DOWN:
+        case GTK_DIR_RIGHT:
+          return FOCUS_WIDGET;
+        }
+      break;
     case FOCUS_WIDGET:
       switch (direction)
-       {
-       case GTK_DIR_TAB_BACKWARD:
-       case GTK_DIR_UP:
-         return FOCUS_NONE;
-       case GTK_DIR_LEFT:
-         return ltr ? FOCUS_NONE : FOCUS_LABEL;
-       case GTK_DIR_TAB_FORWARD:
-       case GTK_DIR_DOWN:
-         return FOCUS_LABEL;
-       case GTK_DIR_RIGHT:
-         return ltr ? FOCUS_LABEL : FOCUS_NONE;
-         break;
-       }
+        {
+        case GTK_DIR_TAB_BACKWARD:
+        case GTK_DIR_UP:
+          return FOCUS_NONE;
+        case GTK_DIR_LEFT:
+          return ltr ? FOCUS_NONE : FOCUS_LABEL;
+        case GTK_DIR_TAB_FORWARD:
+        case GTK_DIR_DOWN:
+          return FOCUS_LABEL;
+        case GTK_DIR_RIGHT:
+          return ltr ? FOCUS_LABEL : FOCUS_NONE;
+        }
+      break;
     case FOCUS_LABEL:
       switch (direction)
-       {
-       case GTK_DIR_TAB_BACKWARD:
-       case GTK_DIR_UP:
-         return FOCUS_WIDGET;
-       case GTK_DIR_LEFT:
-         return ltr ? FOCUS_WIDGET : FOCUS_CHILD;
-       case GTK_DIR_TAB_FORWARD:
-       case GTK_DIR_DOWN:
-         return FOCUS_CHILD;
-       case GTK_DIR_RIGHT:
-         return ltr ? FOCUS_CHILD : FOCUS_WIDGET;
-         break;
-       }
+        {
+        case GTK_DIR_TAB_BACKWARD:
+        case GTK_DIR_UP:
+          return FOCUS_WIDGET;
+        case GTK_DIR_LEFT:
+          return ltr ? FOCUS_WIDGET : FOCUS_CHILD;
+        case GTK_DIR_TAB_FORWARD:
+        case GTK_DIR_DOWN:
+          return FOCUS_CHILD;
+        case GTK_DIR_RIGHT:
+          return ltr ? FOCUS_CHILD : FOCUS_WIDGET;
+        }
+      break;
     case FOCUS_CHILD:
       switch (direction)
-       {
-       case GTK_DIR_TAB_BACKWARD:
-       case GTK_DIR_LEFT:
-       case GTK_DIR_UP:
-         return FOCUS_LABEL;
-       case GTK_DIR_TAB_FORWARD:
-       case GTK_DIR_DOWN:
-       case GTK_DIR_RIGHT:
-         return FOCUS_NONE;
-       }
+        {
+        case GTK_DIR_TAB_BACKWARD:
+        case GTK_DIR_LEFT:
+        case GTK_DIR_UP:
+          return FOCUS_LABEL;
+        case GTK_DIR_TAB_FORWARD:
+        case GTK_DIR_DOWN:
+        case GTK_DIR_RIGHT:
+          return FOCUS_NONE;
+        }
+      break;
     }
 
   g_assert_not_reached ();
   return FOCUS_NONE;
 }
 
+static void
+gtk_expander_resize_toplevel (GtkExpander *expander)
+{
+  GtkExpanderPrivate *priv = expander->priv;
+  GtkWidget *child = gtk_bin_get_child (GTK_BIN (expander));
+
+  if (child && priv->resize_toplevel &&
+      gtk_widget_get_realized (GTK_WIDGET (expander)))
+    {
+      GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (expander));
+
+      if (toplevel && gtk_widget_get_realized (toplevel))
+        {
+          GtkAllocation toplevel_allocation;
+
+          gtk_widget_get_allocation (toplevel, &toplevel_allocation);
+
+          if (priv->expanded)
+            {
+              GtkRequisition child_requisition;
+
+              gtk_widget_get_preferred_size (child, &child_requisition, NULL);
+
+              toplevel_allocation.height += child_requisition.height;
+            }
+          else
+            {
+              GtkAllocation child_allocation;
+
+              gtk_widget_get_allocation (child, &child_allocation);
+
+              toplevel_allocation.height -= child_allocation.height;
+            }
+
+          gtk_window_resize (GTK_WINDOW (toplevel),
+                             toplevel_allocation.width,
+                             toplevel_allocation.height);
+        }
+    }
+}
+
 static gboolean
 gtk_expander_focus (GtkWidget        *widget,
-                   GtkDirectionType  direction)
+                    GtkDirectionType  direction)
 {
   GtkExpander *expander = GTK_EXPANDER (widget);
-  
+
   if (!focus_current_site (expander, direction))
     {
       GtkWidget *old_focus_child;
       gboolean widget_is_focus;
       FocusSite site = FOCUS_NONE;
-      
+
       widget_is_focus = gtk_widget_is_focus (widget);
       old_focus_child = gtk_container_get_focus_child (GTK_CONTAINER (widget));
-      
+
       if (old_focus_child && old_focus_child == expander->priv->label_widget)
-       site = FOCUS_LABEL;
+        site = FOCUS_LABEL;
       else if (old_focus_child)
-       site = FOCUS_CHILD;
+        site = FOCUS_CHILD;
       else if (widget_is_focus)
-       site = FOCUS_WIDGET;
+        site = FOCUS_WIDGET;
 
       while ((site = get_next_site (expander, site, direction)) != FOCUS_NONE)
-       {
-         if (focus_in_site (expander, site, direction))
-           return TRUE;
-       }
+        {
+          if (focus_in_site (expander, site, direction))
+            return TRUE;
+        }
 
       return FALSE;
     }
@@ -1227,7 +1378,7 @@ gtk_expander_focus (GtkWidget        *widget,
 
 static void
 gtk_expander_add (GtkContainer *container,
-                 GtkWidget    *widget)
+                  GtkWidget    *widget)
 {
   GTK_CONTAINER_CLASS (gtk_expander_parent_class)->add (container, widget);
 
@@ -1237,7 +1388,7 @@ gtk_expander_add (GtkContainer *container,
 
 static void
 gtk_expander_remove (GtkContainer *container,
-                    GtkWidget    *widget)
+                     GtkWidget    *widget)
 {
   GtkExpander *expander = GTK_EXPANDER (container);
 
@@ -1249,9 +1400,9 @@ gtk_expander_remove (GtkContainer *container,
 
 static void
 gtk_expander_forall (GtkContainer *container,
-                    gboolean      include_internals,
-                    GtkCallback   callback,
-                    gpointer      callback_data)
+                     gboolean      include_internals,
+                     GtkCallback   callback,
+                     gpointer      callback_data)
 {
   GtkBin *bin = GTK_BIN (container);
   GtkExpanderPrivate *priv = GTK_EXPANDER (container)->priv;
@@ -1273,18 +1424,9 @@ gtk_expander_activate (GtkExpander *expander)
 
 
 static void
-gtk_expander_size_request_init (GtkSizeRequestIface *iface)
-{
-  iface->get_width            = gtk_expander_get_width;
-  iface->get_height           = gtk_expander_get_height;
-  iface->get_height_for_width = gtk_expander_get_height_for_width;
-  iface->get_width_for_height = gtk_expander_get_width_for_height;
-}
-
-static void     
-gtk_expander_get_width (GtkSizeRequest      *widget,
-                       gint                *minimum_size,
-                       gint                *natural_size)
+gtk_expander_get_preferred_width (GtkWidget *widget,
+                                  gint      *minimum_size,
+                                  gint      *natural_size)
 {
   GtkExpander *expander;
   GtkWidget *child;
@@ -1303,14 +1445,14 @@ gtk_expander_get_width (GtkSizeRequest      *widget,
   border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
 
   gtk_widget_style_get (GTK_WIDGET (widget),
-                       "interior-focus", &interior_focus,
-                       "focus-line-width", &focus_width,
-                       "focus-padding", &focus_pad,
-                       "expander-size", &expander_size,
-                       "expander-spacing", &expander_spacing,
-                       NULL);
-
-  *minimum_size = *natural_size = 
+                        "interior-focus", &interior_focus,
+                        "focus-line-width", &focus_width,
+                        "focus-padding", &focus_pad,
+                        "expander-size", &expander_size,
+                        "expander-spacing", &expander_spacing,
+                        NULL);
+
+  *minimum_size = *natural_size =
     expander_size + 2 * expander_spacing +
     2 * focus_width + 2 * focus_pad;
 
@@ -1318,19 +1460,19 @@ gtk_expander_get_width (GtkSizeRequest      *widget,
     {
       gint label_min, label_nat;
 
-      gtk_size_request_get_width (GTK_SIZE_REQUEST (priv->label_widget), 
-                                 &label_min, &label_nat);
+      gtk_widget_get_preferred_width (priv->label_widget,
+                                      &label_min, &label_nat);
 
       *minimum_size += label_min;
       *natural_size += label_nat;
     }
 
-  if (child && GTK_WIDGET_CHILD_VISIBLE (child))
+  if (child && gtk_widget_get_child_visible (child))
     {
       gint child_min, child_nat;
 
-      gtk_size_request_get_width (GTK_SIZE_REQUEST (child), 
-                                 &child_min, &child_nat);
+      gtk_widget_get_preferred_width (child,
+                                      &child_min, &child_nat);
 
       *minimum_size = MAX (*minimum_size, child_min);
       *natural_size = MAX (*natural_size, child_nat);
@@ -1342,10 +1484,10 @@ gtk_expander_get_width (GtkSizeRequest      *widget,
 }
 
 static void
-gtk_expander_get_height (GtkSizeRequest      *widget,
-                        gint                *minimum_size,
-                        gint                *natural_size)
-{  
+gtk_expander_get_preferred_height (GtkWidget *widget,
+                                   gint      *minimum_size,
+                                   gint      *natural_size)
+{
   GtkExpander *expander;
   GtkWidget *child;
   GtkExpanderPrivate *priv;
@@ -1363,14 +1505,14 @@ gtk_expander_get_height (GtkSizeRequest      *widget,
   border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
 
   gtk_widget_style_get (GTK_WIDGET (widget),
-                       "interior-focus", &interior_focus,
-                       "focus-line-width", &focus_width,
-                       "focus-padding", &focus_pad,
-                       "expander-size", &expander_size,
-                       "expander-spacing", &expander_spacing,
-                       NULL);
-
-  *minimum_size = *natural_size = 
+                        "interior-focus", &interior_focus,
+                        "focus-line-width", &focus_width,
+                        "focus-padding", &focus_pad,
+                        "expander-size", &expander_size,
+                        "expander-spacing", &expander_spacing,
+                        NULL);
+
+  *minimum_size = *natural_size =
     interior_focus ? (2 * focus_width + 2 * focus_pad) : 0;
 
 
@@ -1378,9 +1520,9 @@ gtk_expander_get_height (GtkSizeRequest      *widget,
     {
       gint label_min, label_nat;
 
-      gtk_size_request_get_height (GTK_SIZE_REQUEST (priv->label_widget), 
-                                  &label_min, &label_nat);
-      
+      gtk_widget_get_preferred_height (priv->label_widget,
+                                       &label_min, &label_nat);
+
       *minimum_size += label_min;
       *natural_size += label_nat;
     }
@@ -1395,12 +1537,12 @@ gtk_expander_get_height (GtkSizeRequest      *widget,
       *natural_size += extra;
     }
 
-  if (child && GTK_WIDGET_CHILD_VISIBLE (child))
+  if (child && gtk_widget_get_child_visible (child))
     {
       gint child_min, child_nat;
 
-      gtk_size_request_get_height (GTK_SIZE_REQUEST (child), 
-                                  &child_min, &child_nat);
+      gtk_widget_get_preferred_height (child,
+                                       &child_min, &child_nat);
 
       *minimum_size += child_min + priv->spacing;
       *natural_size += child_nat + priv->spacing;
@@ -1412,10 +1554,10 @@ gtk_expander_get_height (GtkSizeRequest      *widget,
 }
 
 static void
-gtk_expander_get_height_for_width (GtkSizeRequest *widget,
-                                  gint            width,
-                                  gint           *minimum_height,
-                                  gint           *natural_height)
+gtk_expander_get_preferred_height_for_width (GtkWidget *widget,
+                                             gint       width,
+                                             gint      *minimum_height,
+                                             gint      *natural_height)
 {
   GtkExpander *expander;
   GtkWidget *child;
@@ -1435,16 +1577,16 @@ gtk_expander_get_height_for_width (GtkSizeRequest *widget,
   border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
 
   gtk_widget_style_get (GTK_WIDGET (widget),
-                       "interior-focus", &interior_focus,
-                       "focus-line-width", &focus_width,
-                       "focus-padding", &focus_pad,
-                       "expander-size", &expander_size,
-                       "expander-spacing", &expander_spacing,
-                       NULL);
+                        "interior-focus", &interior_focus,
+                        "focus-line-width", &focus_width,
+                        "focus-padding", &focus_pad,
+                        "expander-size", &expander_size,
+                        "expander-spacing", &expander_spacing,
+                        NULL);
 
   label_xpad = 2 * border_width + expander_size + 2 * expander_spacing - 2 * focus_width + 2 * focus_pad;
 
-  *minimum_height = *natural_height = 
+  *minimum_height = *natural_height =
     interior_focus ? (2 * focus_width + 2 * focus_pad) : 0;
 
 
@@ -1452,10 +1594,10 @@ gtk_expander_get_height_for_width (GtkSizeRequest *widget,
     {
       gint label_min, label_nat;
 
-      gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (priv->label_widget), 
-                                            MAX (width - label_xpad, 1), 
-                                            &label_min, &label_nat);
-      
+      gtk_widget_get_preferred_height_for_width (priv->label_widget,
+                                                 MAX (width - label_xpad, 1),
+                                                 &label_min, &label_nat);
+
       *minimum_height += label_min;
       *natural_height += label_nat;
     }
@@ -1470,13 +1612,13 @@ gtk_expander_get_height_for_width (GtkSizeRequest *widget,
       *natural_height += extra;
     }
 
-  if (child && GTK_WIDGET_CHILD_VISIBLE (child))
+  if (child && gtk_widget_get_child_visible (child))
     {
       gint child_min, child_nat;
 
-      gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (child), 
-                                            MAX (width - 2 * border_width, 1), 
-                                            &child_min, &child_nat);
+      gtk_widget_get_preferred_height_for_width (child,
+                                                 MAX (width - 2 * border_width, 1),
+                                                 &child_min, &child_nat);
 
       *minimum_height += child_min + priv->spacing;
       *natural_height += child_nat + priv->spacing;
@@ -1487,12 +1629,12 @@ gtk_expander_get_height_for_width (GtkSizeRequest *widget,
 }
 
 static void
-gtk_expander_get_width_for_height (GtkSizeRequest *widget,
-                                  gint       height,
-                                  gint      *minimum_width,
-                                  gint      *natural_width)
+gtk_expander_get_preferred_width_for_height (GtkWidget *widget,
+                                             gint       height,
+                                             gint      *minimum_width,
+                                             gint      *natural_width)
 {
-  GTK_SIZE_REQUEST_GET_IFACE (widget)->get_width (widget, minimum_width, natural_width);
+  GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, minimum_width, natural_width);
 }
 
 
@@ -1500,13 +1642,13 @@ gtk_expander_get_width_for_height (GtkSizeRequest *widget,
 /**
  * gtk_expander_new:
  * @label: the text of the label
- * 
+ *
  * Creates a new expander using @label as the text of the label.
- * 
+ *
  * Return value: a new #GtkExpander widget.
  *
  * Since: 2.4
- **/
+ */
 GtkWidget *
 gtk_expander_new (const gchar *label)
 {
@@ -1515,94 +1657,27 @@ gtk_expander_new (const gchar *label)
 
 /**
  * gtk_expander_new_with_mnemonic:
- * @label: (allow-none): the text of the label with an underscore in front of the
- *         mnemonic character
+ * @label: (allow-none): the text of the label with an underscore
+ *     in front of the mnemonic character
  *
  * Creates a new expander using @label as the text of the label.
  * If characters in @label are preceded by an underscore, they are underlined.
- * If you need a literal underscore character in a label, use '__' (two 
- * underscores). The first underlined character represents a keyboard 
+ * If you need a literal underscore character in a label, use '__' (two
+ * underscores). The first underlined character represents a keyboard
  * accelerator called a mnemonic.
  * Pressing Alt and that key activates the button.
- * 
+ *
  * Return value: a new #GtkExpander widget.
  *
  * Since: 2.4
- **/
+ */
 GtkWidget *
 gtk_expander_new_with_mnemonic (const gchar *label)
 {
   return g_object_new (GTK_TYPE_EXPANDER,
-                      "label", label,
-                      "use-underline", TRUE,
-                      NULL);
-}
-
-static gboolean
-gtk_expander_animation_timeout (GtkExpander *expander)
-{
-  GtkExpanderPrivate *priv = expander->priv;
-  GtkWidget *widget = GTK_WIDGET (expander);
-  GtkWidget *child;
-  GdkRectangle area;
-  gboolean finish = FALSE;
-
-  if (gtk_widget_get_realized (widget))
-    {
-      get_expander_bounds (expander, &area);
-      gdk_window_invalidate_rect (gtk_widget_get_window (widget), &area, TRUE);
-    }
-
-  if (priv->expanded)
-    {
-      if (priv->expander_style == GTK_EXPANDER_COLLAPSED)
-       {
-         priv->expander_style = GTK_EXPANDER_SEMI_EXPANDED;
-       }
-      else
-       {
-         priv->expander_style = GTK_EXPANDER_EXPANDED;
-         finish = TRUE;
-       }
-    }
-  else
-    {
-      if (priv->expander_style == GTK_EXPANDER_EXPANDED)
-       {
-         priv->expander_style = GTK_EXPANDER_SEMI_COLLAPSED;
-       }
-      else
-       {
-         priv->expander_style = GTK_EXPANDER_COLLAPSED;
-         finish = TRUE;
-       }
-    }
-
-  if (finish)
-    {
-      priv->animation_timeout = 0;
-
-      child = gtk_bin_get_child (GTK_BIN (expander));
-      if (child)
-       gtk_widget_set_child_visible (child, priv->expanded);
-      gtk_widget_queue_resize (widget);
-    }
-
-  return !finish;
-}
-
-static void
-gtk_expander_start_animation (GtkExpander *expander)
-{
-  GtkExpanderPrivate *priv = expander->priv;
-
-  if (priv->animation_timeout)
-    g_source_remove (priv->animation_timeout);
-
-  priv->animation_timeout =
-               gdk_threads_add_timeout (50,
-                              (GSourceFunc) gtk_expander_animation_timeout,
-                              expander);
+                       "label", label,
+                       "use-underline", TRUE,
+                       NULL);
 }
 
 /**
@@ -1615,10 +1690,10 @@ gtk_expander_start_animation (GtkExpander *expander)
  * child widget to be hidden.
  *
  * Since: 2.4
- **/
+ */
 void
 gtk_expander_set_expanded (GtkExpander *expander,
-                          gboolean     expanded)
+                           gboolean     expanded)
 {
   GtkExpanderPrivate *priv;
   GtkWidget *child;
@@ -1631,29 +1706,18 @@ gtk_expander_set_expanded (GtkExpander *expander,
 
   if (priv->expanded != expanded)
     {
-      GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (expander));
-      gboolean     enable_animations;
+      GtkWidget *widget = GTK_WIDGET (expander);
 
       priv->expanded = expanded;
 
-      g_object_get (settings, "gtk-enable-animations", &enable_animations, NULL);
+      child = gtk_bin_get_child (GTK_BIN (expander));
 
-      if (enable_animations && gtk_widget_get_realized (GTK_WIDGET (expander)))
-       {
-         gtk_expander_start_animation (expander);
-       }
-      else
-       {
-         priv->expander_style = expanded ? GTK_EXPANDER_EXPANDED :
-                                           GTK_EXPANDER_COLLAPSED;
-
-          child = gtk_bin_get_child (GTK_BIN (expander));
-         if (child)
-           {
-             gtk_widget_set_child_visible (child, priv->expanded);
-             gtk_widget_queue_resize (GTK_WIDGET (expander));
-           }
-       }
+      if (child)
+        {
+          gtk_widget_set_child_visible (child, priv->expanded);
+          gtk_widget_queue_resize (widget);
+          gtk_expander_resize_toplevel (expander);
+        }
 
       g_object_notify (G_OBJECT (expander), "expanded");
     }
@@ -1668,10 +1732,10 @@ gtk_expander_set_expanded (GtkExpander *expander,
  *
  * See gtk_expander_set_expanded().
  *
- * Return value: the current state of the expander.
+ * Return value: the current state of the expander
  *
  * Since: 2.4
- **/
+ */
 gboolean
 gtk_expander_get_expanded (GtkExpander *expander)
 {
@@ -1683,16 +1747,16 @@ gtk_expander_get_expanded (GtkExpander *expander)
 /**
  * gtk_expander_set_spacing:
  * @expander: a #GtkExpander
- * @spacing: distance between the expander and child in pixels.
+ * @spacing: distance between the expander and child in pixels
  *
- * Sets the spacing field of @expander, which is the number of pixels to
- * place between expander and the child.
+ * Sets the spacing field of @expander, which is the number of
+ * pixels to place between expander and the child.
  *
  * Since: 2.4
- **/
+ */
 void
 gtk_expander_set_spacing (GtkExpander *expander,
-                         gint         spacing)
+                          gint         spacing)
 {
   g_return_if_fail (GTK_IS_EXPANDER (expander));
   g_return_if_fail (spacing >= 0);
@@ -1713,10 +1777,10 @@ gtk_expander_set_spacing (GtkExpander *expander,
  *
  * Gets the value set by gtk_expander_set_spacing().
  *
- * Return value: spacing between the expander and child.
+ * Return value: spacing between the expander and child
  *
  * Since: 2.4
- **/
+ */
 gint
 gtk_expander_get_spacing (GtkExpander *expander)
 {
@@ -1735,10 +1799,10 @@ gtk_expander_get_spacing (GtkExpander *expander)
  * This will also clear any previously set labels.
  *
  * Since: 2.4
- **/
+ */
 void
 gtk_expander_set_label (GtkExpander *expander,
-                       const gchar *label)
+                        const gchar *label)
 {
   g_return_if_fail (GTK_IS_EXPANDER (expander));
 
@@ -1778,11 +1842,11 @@ gtk_expander_set_label (GtkExpander *expander,
  * widget.
  *
  * Return value: The text of the label widget. This string is owned
- * by the widget and must not be modified or freed.
+ *     by the widget and must not be modified or freed.
  *
  * Since: 2.4
- **/
-G_CONST_RETURN char *
+ */
+const char *
 gtk_expander_get_label (GtkExpander *expander)
 {
   GtkExpanderPrivate *priv;
@@ -1806,10 +1870,10 @@ gtk_expander_get_label (GtkExpander *expander)
  * the next character should be used for the mnemonic accelerator key.
  *
  * Since: 2.4
- **/
+ */
 void
 gtk_expander_set_use_underline (GtkExpander *expander,
-                               gboolean     use_underline)
+                                gboolean     use_underline)
 {
   GtkExpanderPrivate *priv;
 
@@ -1824,7 +1888,7 @@ gtk_expander_set_use_underline (GtkExpander *expander,
       priv->use_underline = use_underline;
 
       if (GTK_IS_LABEL (priv->label_widget))
-       gtk_label_set_use_underline (GTK_LABEL (priv->label_widget), use_underline);
+        gtk_label_set_use_underline (GTK_LABEL (priv->label_widget), use_underline);
 
       g_object_notify (G_OBJECT (expander), "use-underline");
     }
@@ -1834,14 +1898,14 @@ gtk_expander_set_use_underline (GtkExpander *expander,
  * gtk_expander_get_use_underline:
  * @expander: a #GtkExpander
  *
- * Returns whether an embedded underline in the expander label indicates a
- * mnemonic. See gtk_expander_set_use_underline().
+ * Returns whether an embedded underline in the expander label
+ * indicates a mnemonic. See gtk_expander_set_use_underline().
  *
- * Return value: %TRUE if an embedded underline in the expander label
- *               indicates the mnemonic accelerator keys.
+ * Return value: %TRUE if an embedded underline in the expander
+ *     label indicates the mnemonic accelerator keys
  *
  * Since: 2.4
- **/
+ */
 gboolean
 gtk_expander_get_use_underline (GtkExpander *expander)
 {
@@ -1860,10 +1924,10 @@ gtk_expander_get_use_underline (GtkExpander *expander)
  * language</link>. See gtk_label_set_markup().
  *
  * Since: 2.4
- **/
+ */
 void
 gtk_expander_set_use_markup (GtkExpander *expander,
-                            gboolean     use_markup)
+                             gboolean     use_markup)
 {
   GtkExpanderPrivate *priv;
 
@@ -1878,7 +1942,7 @@ gtk_expander_set_use_markup (GtkExpander *expander,
       priv->use_markup = use_markup;
 
       if (GTK_IS_LABEL (priv->label_widget))
-       gtk_label_set_use_markup (GTK_LABEL (priv->label_widget), use_markup);
+        gtk_label_set_use_markup (GTK_LABEL (priv->label_widget), use_markup);
 
       g_object_notify (G_OBJECT (expander), "use-markup");
     }
@@ -1890,12 +1954,12 @@ gtk_expander_set_use_markup (GtkExpander *expander,
  *
  * Returns whether the label's text is interpreted as marked up with
  * the <link linkend="PangoMarkupFormat">Pango text markup
- * language</link>. See gtk_expander_set_use_markup ().
+ * language</link>. See gtk_expander_set_use_markup().
  *
  * Return value: %TRUE if the label's text will be parsed for markup
  *
  * Since: 2.4
- **/
+ */
 gboolean
 gtk_expander_get_use_markup (GtkExpander *expander)
 {
@@ -1913,10 +1977,10 @@ gtk_expander_get_use_markup (GtkExpander *expander)
  * that will appear embedded alongside the expander arrow.
  *
  * Since: 2.4
- **/
+ */
 void
 gtk_expander_set_label_widget (GtkExpander *expander,
-                              GtkWidget   *label_widget)
+                               GtkWidget   *label_widget)
 {
   GtkExpanderPrivate *priv;
   GtkWidget          *widget;
@@ -1932,7 +1996,7 @@ gtk_expander_set_label_widget (GtkExpander *expander,
 
   if (priv->label_widget)
     {
-      gtk_widget_set_state (priv->label_widget, GTK_STATE_NORMAL);
+      gtk_widget_set_state_flags (priv->label_widget, 0, TRUE);
       gtk_widget_unparent (priv->label_widget);
     }
 
@@ -1946,7 +2010,9 @@ gtk_expander_set_label_widget (GtkExpander *expander,
       gtk_widget_set_parent (label_widget, widget);
 
       if (priv->prelight)
-       gtk_widget_set_state (label_widget, GTK_STATE_PRELIGHT);
+        gtk_widget_set_state_flags (label_widget,
+                                    GTK_STATE_FLAG_PRELIGHT,
+                                    FALSE);
     }
 
   if (gtk_widget_get_visible (widget))
@@ -1966,10 +2032,10 @@ gtk_expander_set_label_widget (GtkExpander *expander,
  * gtk_expander_set_label_widget().
  *
  * Return value: (transfer none): the label widget,
- *     or %NULL if there is none.
+ *     or %NULL if there is none
  *
  * Since: 2.4
- **/
+ */
 GtkWidget *
 gtk_expander_get_label_widget (GtkExpander *expander)
 {
@@ -1981,11 +2047,11 @@ gtk_expander_get_label_widget (GtkExpander *expander)
 /**
  * gtk_expander_set_label_fill:
  * @expander: a #GtkExpander
- * @label_fill: %TRUE if the label should should fill all available horizontal
- *              space
+ * @label_fill: %TRUE if the label should should fill
+ *     all available horizontal space
  *
- * Sets whether the label widget should fill all available horizontal space
- * allocated to @expander.
+ * Sets whether the label widget should fill all available
+ * horizontal space allocated to @expander.
  *
  * Since: 2.22
  */
@@ -2016,11 +2082,11 @@ gtk_expander_set_label_fill (GtkExpander *expander,
  * gtk_expander_get_label_fill:
  * @expander: a #GtkExpander
  *
- * Returns whether the label widget will fill all available horizontal
- * space allocated to @expander.
+ * Returns whether the label widget will fill all available
+ * horizontal space allocated to @expander.
  *
- * Return value: %TRUE if the label widget will fill all available horizontal
- *               space
+ * Return value: %TRUE if the label widget will fill all
+ *     available horizontal space
  *
  * Since: 2.22
  */
@@ -2032,3 +2098,44 @@ gtk_expander_get_label_fill (GtkExpander *expander)
   return expander->priv->label_fill;
 }
 
+/**
+ * gtk_expander_set_resize_toplevel:
+ * @expander: a #GtkExpander
+ * @resize_toplevel: whether to resize the toplevel
+ *
+ * Sets whether the expander will resize the toplevel widget
+ * containing the expander upon resizing and collpasing.
+ *
+ * Since: 3.2
+ */
+void
+gtk_expander_set_resize_toplevel (GtkExpander *expander,
+                                  gboolean     resize_toplevel)
+{
+  g_return_if_fail (GTK_IS_EXPANDER (expander));
+
+  if (expander->priv->resize_toplevel != resize_toplevel)
+    {
+      expander->priv->resize_toplevel = resize_toplevel ? TRUE : FALSE;
+      g_object_notify (G_OBJECT (expander), "resize-toplevel");
+    }
+}
+
+/**
+ * gtk_expander_get_resize_toplevel:
+ * @expander: a #GtkExpander
+ *
+ * Returns whether the expander will resize the toplevel widget
+ * containing the expander upon resizing and collpasing.
+ *
+ * Return value: the "resize toplevel" setting.
+ *
+ * Since: 3.2
+ */
+gboolean
+gtk_expander_get_resize_toplevel (GtkExpander *expander)
+{
+  g_return_val_if_fail (GTK_IS_EXPANDER (expander), FALSE);
+
+  return expander->priv->resize_toplevel;
+}