]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkassistant.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / gtk / gtkassistant.c
index ba3164296adc79f3152361cf773524b7a46cd510..3ba9f227be5abc7934d793a7877a92be13638a2d 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * GTK - The GIMP Toolkit
  * Copyright (C) 1999  Red Hat, Inc.
  * Copyright (C) 2002  Anders Carlsson <andersca@gnu.org>
@@ -18,9 +18,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser 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/>.
  */
 
 /**
 
 #include "gtkassistant.h"
 
-#include "gtkaccessible.h"
 #include "gtkbutton.h"
-#include "gtkhbox.h"
-#include "gtkhbbox.h"
+#include "gtkbox.h"
+#include "gtkframe.h"
+#include "gtknotebook.h"
 #include "gtkimage.h"
 #include "gtklabel.h"
+#include "gtksettings.h"
 #include "gtksizegroup.h"
 #include "gtksizerequest.h"
 #include "gtkstock.h"
-
+#include "gtktypebuiltins.h"
 #include "gtkintl.h"
 #include "gtkprivate.h"
 #include "gtkbuildable.h"
+#include "a11y/gtkwindowaccessible.h"
 
 
 #define HEADER_SPACING 12
@@ -84,12 +84,15 @@ typedef struct _GtkAssistantPage GtkAssistantPage;
 
 struct _GtkAssistantPage
 {
-  GtkWidget *page;
   GtkAssistantPageType type;
-  guint      complete : 1;
+  guint      complete     : 1;
   guint      complete_set : 1;
 
-  GtkWidget *title;
+  gchar *title;
+
+  GtkWidget *page;
+  GtkWidget *regular_title;
+  GtkWidget *current_title;
   GdkPixbuf *header_image;
   GdkPixbuf *sidebar_image;
 };
@@ -103,67 +106,47 @@ struct _GtkAssistantPrivate
   GtkWidget *close;
   GtkWidget *last;
 
-  GtkWidget *header_image;
-  GtkWidget *sidebar_image;
-
+  GtkWidget *sidebar;
+  GtkWidget *content;
   GtkWidget *action_area;
 
   GList     *pages;
-
-  GtkAssistantPage *current_page;
-
   GSList    *visited_pages;
+  GtkAssistantPage *current_page;
 
-  GtkSizeGroup *size_group;
+  GtkSizeGroup *button_size_group;
+  GtkSizeGroup *title_size_group;
 
   GtkAssistantPageFunc forward_function;
   gpointer forward_function_data;
   GDestroyNotify forward_data_destroy;
 
+  gint extra_buttons;
+
   guint committed : 1;
 };
 
 static void     gtk_assistant_class_init         (GtkAssistantClass *class);
 static void     gtk_assistant_init               (GtkAssistant      *assistant);
 static void     gtk_assistant_destroy            (GtkWidget         *widget);
-static void     gtk_assistant_style_set          (GtkWidget         *widget,
-                                                 GtkStyle          *old_style);
-static void     gtk_assistant_get_preferred_width  (GtkWidget        *widget,
-                                                    gint             *minimum,
-                                                    gint             *natural);
-static void     gtk_assistant_get_preferred_height (GtkWidget        *widget,
-                                                    gint             *minimum,
-                                                    gint             *natural);
-static void     gtk_assistant_size_allocate      (GtkWidget         *widget,
-                                                 GtkAllocation     *allocation);
 static void     gtk_assistant_map                (GtkWidget         *widget);
 static void     gtk_assistant_unmap              (GtkWidget         *widget);
 static gboolean gtk_assistant_delete_event       (GtkWidget         *widget,
-                                                 GdkEventAny       *event);
-static gboolean gtk_assistant_draw               (GtkWidget         *widget,
-                                                 cairo_t           *cr);
-static gboolean gtk_assistant_focus              (GtkWidget         *widget,
-                                                 GtkDirectionType   direction);
+                                                  GdkEventAny       *event);
 static void     gtk_assistant_add                (GtkContainer      *container,
-                                                 GtkWidget         *page);
+                                                  GtkWidget         *page);
 static void     gtk_assistant_remove             (GtkContainer      *container,
-                                                 GtkWidget         *page);
-static void     gtk_assistant_forall             (GtkContainer      *container,
-                                                 gboolean           include_internals,
-                                                 GtkCallback        callback,
-                                                 gpointer           callback_data);
+                                                  GtkWidget         *page);
 static void     gtk_assistant_set_child_property (GtkContainer      *container,
-                                                 GtkWidget         *child,
-                                                 guint              property_id,
-                                                 const GValue      *value,
-                                                 GParamSpec        *pspec);
+                                                  GtkWidget         *child,
+                                                  guint              property_id,
+                                                  const GValue      *value,
+                                                  GParamSpec        *pspec);
 static void     gtk_assistant_get_child_property (GtkContainer      *container,
-                                                 GtkWidget         *child,
-                                                 guint              property_id,
-                                                 GValue            *value,
-                                                 GParamSpec        *pspec);
-
-static AtkObject *gtk_assistant_get_accessible   (GtkWidget         *widget);
+                                                  GtkWidget         *child,
+                                                  guint              property_id,
+                                                  GValue            *value,
+                                                  GParamSpec        *pspec);
 
 static void       gtk_assistant_buildable_interface_init     (GtkBuildableIface *iface);
 static GObject   *gtk_assistant_buildable_get_internal_child (GtkBuildable  *buildable,
@@ -183,6 +166,14 @@ static void       gtk_assistant_buildable_custom_finished    (GtkBuildable  *bui
 
 static GList*     find_page                                  (GtkAssistant  *assistant,
                                                               GtkWidget     *page);
+static void       gtk_assistant_do_set_page_header_image     (GtkAssistant  *assistant,
+                                                              GtkWidget     *page,
+                                                              GdkPixbuf     *pixbuf);
+static void       gtk_assistant_do_set_page_side_image       (GtkAssistant  *assistant,
+                                                              GtkWidget     *page,
+                                                              GdkPixbuf     *pixbuf);
+
+GType             _gtk_assistant_accessible_get_type         (void);
 
 enum
 {
@@ -223,20 +214,14 @@ gtk_assistant_class_init (GtkAssistantClass *class)
   container_class = (GtkContainerClass *) class;
 
   widget_class->destroy = gtk_assistant_destroy;
-  widget_class->style_set = gtk_assistant_style_set;
-  widget_class->get_preferred_width = gtk_assistant_get_preferred_width;
-  widget_class->get_preferred_height = gtk_assistant_get_preferred_height;
-  widget_class->size_allocate = gtk_assistant_size_allocate;
   widget_class->map = gtk_assistant_map;
   widget_class->unmap = gtk_assistant_unmap;
   widget_class->delete_event = gtk_assistant_delete_event;
-  widget_class->draw = gtk_assistant_draw;
-  widget_class->focus = gtk_assistant_focus;
-  widget_class->get_accessible = gtk_assistant_get_accessible;
+
+  gtk_widget_class_set_accessible_type (widget_class, _gtk_assistant_accessible_get_type ());
 
   container_class->add = gtk_assistant_add;
   container_class->remove = gtk_assistant_remove;
-  container_class->forall = gtk_assistant_forall;
   container_class->set_child_property = gtk_assistant_set_child_property;
   container_class->get_child_property = gtk_assistant_get_child_property;
 
@@ -250,57 +235,61 @@ gtk_assistant_class_init (GtkAssistantClass *class)
    */
   signals[CANCEL] =
     g_signal_new (I_("cancel"),
-                 G_TYPE_FROM_CLASS (gobject_class),
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET (GtkAssistantClass, cancel),
-                 NULL, NULL,
-                 g_cclosure_marshal_VOID__VOID,
-                 G_TYPE_NONE, 0);
-    
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GtkAssistantClass, cancel),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+
   /**
    * GtkAssistant::prepare:
    * @assistant: the #GtkAssistant
    * @page: the current page
    *
-   * The ::prepare signal is emitted when a new page is set as the assistant's
-   * current page, before making the new page visible. A handler for this signal
-   * can do any preparation which are necessary before showing @page.
+   * The ::prepare signal is emitted when a new page is set as the
+   * assistant's current page, before making the new page visible.
+   *
+   * A handler for this signal can do any preparations which are
+   * necessary before showing @page.
    *
    * Since: 2.10
    */
   signals[PREPARE] =
     g_signal_new (I_("prepare"),
-                 G_TYPE_FROM_CLASS (gobject_class),
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET (GtkAssistantClass, prepare),
-                 NULL, NULL,
-                 g_cclosure_marshal_VOID__OBJECT,
-                 G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GtkAssistantClass, prepare),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__OBJECT,
+                  G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
 
   /**
    * GtkAssistant::apply:
    * @assistant: the #GtkAssistant
    *
-   * The ::apply signal is emitted when the apply button is clicked. The default
-   * behavior of the #GtkAssistant is to switch to the page after the current
-   * page, unless the current page is the last one.
+   * The ::apply signal is emitted when the apply button is clicked.
+   *
+   * The default behavior of the #GtkAssistant is to switch to the page
+   * after the current page, unless the current page is the last one.
    *
-   * A handler for the ::apply signal should carry out the actions for which
-   * the wizard has collected data. If the action takes a long time to complete,
-   * you might consider putting a page of type %GTK_ASSISTANT_PAGE_PROGRESS
-   * after the confirmation page and handle this operation within the
-   * #GtkAssistant::prepare signal of the progress page.
+   * A handler for the ::apply signal should carry out the actions for
+   * which the wizard has collected data. If the action takes a long time
+   * to complete, you might consider putting a page of type
+   * %GTK_ASSISTANT_PAGE_PROGRESS after the confirmation page and handle
+   * this operation within the #GtkAssistant::prepare signal of the progress
+   * page.
    *
    * Since: 2.10
    */
   signals[APPLY] =
     g_signal_new (I_("apply"),
-                 G_TYPE_FROM_CLASS (gobject_class),
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET (GtkAssistantClass, apply),
-                 NULL, NULL,
-                 g_cclosure_marshal_VOID__VOID,
-                 G_TYPE_NONE, 0);
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GtkAssistantClass, apply),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
 
   /**
    * GtkAssistant::close:
@@ -314,29 +303,29 @@ gtk_assistant_class_init (GtkAssistantClass *class)
    */
   signals[CLOSE] =
     g_signal_new (I_("close"),
-                 G_TYPE_FROM_CLASS (gobject_class),
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET (GtkAssistantClass, close),
-                 NULL, NULL,
-                 g_cclosure_marshal_VOID__VOID,
-                 G_TYPE_NONE, 0);
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GtkAssistantClass, close),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
 
   gtk_widget_class_install_style_property (widget_class,
-                                          g_param_spec_int ("header-padding",
-                                                            P_("Header Padding"),
-                                                            P_("Number of pixels around the header."),
-                                                            0,
-                                                            G_MAXINT,
-                                                            6,
-                                                            GTK_PARAM_READABLE));
+                                           g_param_spec_int ("header-padding",
+                                                             P_("Header Padding"),
+                                                             P_("Number of pixels around the header."),
+                                                             0,
+                                                             G_MAXINT,
+                                                             6,
+                                                             GTK_PARAM_READABLE));
   gtk_widget_class_install_style_property (widget_class,
-                                          g_param_spec_int ("content-padding",
-                                                            P_("Content Padding"),
-                                                            P_("Number of pixels around the content pages."),
-                                                            0,
-                                                            G_MAXINT,
-                                                            1,
-                                                            GTK_PARAM_READABLE));
+                                           g_param_spec_int ("content-padding",
+                                                             P_("Content Padding"),
+                                                             P_("Number of pixels around the content pages."),
+                                                             0,
+                                                             G_MAXINT,
+                                                             1,
+                                                             GTK_PARAM_READABLE));
 
   /**
    * GtkAssistant:page-type:
@@ -346,80 +335,80 @@ gtk_assistant_class_init (GtkAssistantClass *class)
    * Since: 2.10
    */
   gtk_container_class_install_child_property (container_class,
-                                             CHILD_PROP_PAGE_TYPE,
-                                             g_param_spec_enum ("page-type", 
-                                                                P_("Page type"),
-                                                                P_("The type of the assistant page"),
-                                                                GTK_TYPE_ASSISTANT_PAGE_TYPE,
-                                                                GTK_ASSISTANT_PAGE_CONTENT,
-                                                                GTK_PARAM_READWRITE));
+                                              CHILD_PROP_PAGE_TYPE,
+                                              g_param_spec_enum ("page-type",
+                                                                 P_("Page type"),
+                                                                 P_("The type of the assistant page"),
+                                                                 GTK_TYPE_ASSISTANT_PAGE_TYPE,
+                                                                 GTK_ASSISTANT_PAGE_CONTENT,
+                                                                 GTK_PARAM_READWRITE));
 
   /**
    * GtkAssistant:title:
    *
-   * The title that is displayed in the page header.
-   *
-   * If title and header-image are both %NULL, no header is displayed.
+   * The title of the page.
    *
    * Since: 2.10
    */
   gtk_container_class_install_child_property (container_class,
-                                             CHILD_PROP_PAGE_TITLE,
-                                             g_param_spec_string ("title", 
-                                                                  P_("Page title"),
-                                                                  P_("The title of the assistant page"),
-                                                                  NULL,
-                                                                  GTK_PARAM_READWRITE));
+                                              CHILD_PROP_PAGE_TITLE,
+                                              g_param_spec_string ("title",
+                                                                   P_("Page title"),
+                                                                   P_("The title of the assistant page"),
+                                                                   NULL,
+                                                                   GTK_PARAM_READWRITE));
 
   /**
    * GtkAssistant:header-image:
    *
-   * The image that is displayed next to the title in the page header.
-   *
-   * If title and header-image are both %NULL, no header is displayed.
+   * This image used to be displayed in the page header.
    *
    * Since: 2.10
+   *
+   * Deprecated: 3.2: Since GTK+ 3.2, a header is no longer shown;
+   *     add your header decoration to the page content instead.
    */
   gtk_container_class_install_child_property (container_class,
-                                             CHILD_PROP_PAGE_HEADER_IMAGE,
-                                             g_param_spec_object ("header-image", 
-                                                                  P_("Header image"),
-                                                                  P_("Header image for the assistant page"),
-                                                                  GDK_TYPE_PIXBUF,
-                                                                  GTK_PARAM_READWRITE));
+                                              CHILD_PROP_PAGE_HEADER_IMAGE,
+                                              g_param_spec_object ("header-image",
+                                                                   P_("Header image"),
+                                                                   P_("Header image for the assistant page"),
+                                                                   GDK_TYPE_PIXBUF,
+                                                                   GTK_PARAM_READWRITE));
 
   /**
-   * GtkAssistant:header-image:
-   *
-   * The image that is displayed next to the page.
+   * GtkAssistant:sidebar-image:
    *
-   * Set this to %NULL to make the sidebar disappear.
+   * This image used to be displayed in the 'sidebar'.
    *
    * Since: 2.10
+   *
+   * Deprecated: 3.2: Since GTK+ 3.2, the sidebar image is no longer shown.
    */
   gtk_container_class_install_child_property (container_class,
-                                             CHILD_PROP_PAGE_SIDEBAR_IMAGE,
-                                             g_param_spec_object ("sidebar-image", 
-                                                                  P_("Sidebar image"),
-                                                                  P_("Sidebar image for the assistant page"),
-                                                                  GDK_TYPE_PIXBUF,
-                                                                  GTK_PARAM_READWRITE));
+                                              CHILD_PROP_PAGE_SIDEBAR_IMAGE,
+                                              g_param_spec_object ("sidebar-image",
+                                                                   P_("Sidebar image"),
+                                                                   P_("Sidebar image for the assistant page"),
+                                                                   GDK_TYPE_PIXBUF,
+                                                                   GTK_PARAM_READWRITE));
+
   /**
    * GtkAssistant:complete:
    *
-   * Setting the "complete" child property to %TRUE marks a page as complete
-   * (i.e.: all the required fields are filled out). GTK+ uses this information
-   * to control the sensitivity of the navigation buttons.
+   * Setting the "complete" child property to %TRUE marks a page as
+   * complete (i.e.: all the required fields are filled out). GTK+ uses
+   * this information to control the sensitivity of the navigation buttons.
    *
    * Since: 2.10
-   **/
+   */
   gtk_container_class_install_child_property (container_class,
-                                             CHILD_PROP_PAGE_COMPLETE,
-                                             g_param_spec_boolean ("complete", 
-                                                                   P_("Page complete"),
-                                                                   P_("Whether all required fields on the page have been filled out"),
-                                                                   FALSE,
-                                                                   G_PARAM_READWRITE));
+                                              CHILD_PROP_PAGE_COMPLETE,
+                                              g_param_spec_boolean ("complete",
+                                                                    P_("Page complete"),
+                                                                    P_("Whether all required fields on the page have been filled out"),
+                                                                    FALSE,
+                                                                    G_PARAM_READWRITE));
 
   g_type_class_add_private (gobject_class, sizeof (GtkAssistantPrivate));
 }
@@ -448,28 +437,34 @@ default_forward_function (gint current_page, gpointer data)
       current_page++;
 
       if (page_node)
-       page_info = (GtkAssistantPage *) page_node->data;
+        page_info = (GtkAssistantPage *) page_node->data;
     }
 
   return current_page;
 }
 
-static void
-compute_last_button_state (GtkAssistant *assistant)
+static gboolean
+last_button_visible (GtkAssistant *assistant, GtkAssistantPage *page)
 {
   GtkAssistantPrivate *priv = assistant->priv;
-  GtkAssistantPage *page_info, *current_page_info;
+  GtkAssistantPage *page_info;
   gint count, page_num, n_pages;
 
+  if (page == NULL)
+    return FALSE;
+
+  if (page->type != GTK_ASSISTANT_PAGE_CONTENT)
+    return FALSE;
+
   count = 0;
-  page_num = gtk_assistant_get_current_page (assistant);
-  n_pages  = gtk_assistant_get_n_pages (assistant);
-  current_page_info = page_info = g_list_nth_data (priv->pages, page_num);
+  page_num = g_list_index (priv->pages, page);
+  n_pages  = g_list_length (priv->pages);
+  page_info = page;
 
   while (page_num >= 0 && page_num < n_pages &&
-        page_info->type == GTK_ASSISTANT_PAGE_CONTENT &&
-        (count == 0 || page_info->complete) &&
-        count < n_pages)
+         page_info->type == GTK_ASSISTANT_PAGE_CONTENT &&
+         (count == 0 || page_info->complete) &&
+         count < n_pages)
     {
       page_num = (priv->forward_function) (page_num, priv->forward_function_data);
       page_info = g_list_nth_data (priv->pages, page_num);
@@ -477,69 +472,93 @@ compute_last_button_state (GtkAssistant *assistant)
       count++;
     }
 
-  /* make the last button visible if we can skip multiple
+  /* Make the last button visible if we can skip multiple
    * pages and end on a confirmation or summary page
    */
   if (count > 1 && page_info &&
       (page_info->type == GTK_ASSISTANT_PAGE_CONFIRM ||
        page_info->type == GTK_ASSISTANT_PAGE_SUMMARY))
-    {
-      gtk_widget_show (priv->last);
-      gtk_widget_set_sensitive (priv->last,
-                               current_page_info->complete);
-    }
+    return TRUE;
   else
-    gtk_widget_hide (priv->last);
+    return FALSE;
 }
 
 static void
-compute_progress_state (GtkAssistant *assistant)
+update_actions_size (GtkAssistant *assistant)
 {
   GtkAssistantPrivate *priv = assistant->priv;
-  gint page_num, n_pages;
+  GList *l;
+  GtkAssistantPage *page;
+  gint buttons, page_buttons;
 
-  n_pages = gtk_assistant_get_n_pages (assistant);
-  page_num = gtk_assistant_get_current_page (assistant);
+  if (!priv->current_page)
+    return;
 
-  page_num = (priv->forward_function) (page_num, priv->forward_function_data);
+  /* Some heuristics to find out how many buttons we should
+   * reserve space for. It is possible to trick this code
+   * with page forward functions and invisible pages, etc.
+   */
+  buttons = 0;
+  for (l = priv->pages; l; l = l->next)
+    {
+      page = l->data;
 
-  if (page_num >= 0 && page_num < n_pages)
-    gtk_widget_show (priv->forward);
-  else
-    gtk_widget_hide (priv->forward);
+      if (!gtk_widget_get_visible (page->page))
+        continue;
+
+      page_buttons = 2; /* cancel, forward/apply/close */
+      if (l != priv->pages)
+        page_buttons += 1; /* back */
+      if (last_button_visible (assistant, page))
+        page_buttons += 1; /* last */
+
+      buttons = MAX (buttons, page_buttons);
+    }
+
+  buttons += priv->extra_buttons;
+
+  gtk_widget_set_size_request (priv->action_area,
+                               buttons * gtk_widget_get_allocated_width (priv->cancel) + (buttons - 1) * 6,
+                               -1);
 }
 
 static void
-set_assistant_header_image (GtkAssistant *assistant)
+compute_last_button_state (GtkAssistant *assistant)
 {
   GtkAssistantPrivate *priv = assistant->priv;
 
-  gtk_image_set_from_pixbuf (GTK_IMAGE (priv->header_image),
-                            priv->current_page->header_image);
+  gtk_widget_set_sensitive (priv->last, priv->current_page->complete);
+  if (last_button_visible (assistant, priv->current_page))
+    gtk_widget_show (priv->last);
+  else
+    gtk_widget_hide (priv->last);
 }
 
 static void
-set_assistant_sidebar_image (GtkAssistant *assistant)
+compute_progress_state (GtkAssistant *assistant)
 {
   GtkAssistantPrivate *priv = assistant->priv;
+  gint page_num, n_pages;
 
-  gtk_image_set_from_pixbuf (GTK_IMAGE (priv->sidebar_image),
-                            priv->current_page->sidebar_image);
+  n_pages = gtk_assistant_get_n_pages (assistant);
+  page_num = gtk_assistant_get_current_page (assistant);
 
-  if (priv->current_page->sidebar_image)
-    gtk_widget_show (priv->sidebar_image);
+  page_num = (priv->forward_function) (page_num, priv->forward_function_data);
+
+  if (page_num >= 0 && page_num < n_pages)
+    gtk_widget_show (priv->forward);
   else
-    gtk_widget_hide (priv->sidebar_image);
+    gtk_widget_hide (priv->forward);
 }
 
 static void
-set_assistant_buttons_state (GtkAssistant *assistant)
+update_buttons_state (GtkAssistant *assistant)
 {
   GtkAssistantPrivate *priv = assistant->priv;
 
   if (!priv->current_page)
     return;
-  
+
   switch (priv->current_page->type)
     {
     case GTK_ASSISTANT_PAGE_INTRO:
@@ -615,46 +634,104 @@ set_assistant_buttons_state (GtkAssistant *assistant)
     gtk_widget_show (priv->cancel);
 
   /* this is quite general, we don't want to
-   * go back if it's the first page */
+   * go back if it's the first page
+   */
   if (!priv->visited_pages)
     gtk_widget_hide (priv->back);
 }
 
-static void
-set_current_page (GtkAssistant     *assistant,
-                 GtkAssistantPage *page)
+static gboolean
+update_page_title_state (GtkAssistant *assistant, GList *list)
 {
+  GtkAssistantPage *page, *other;
   GtkAssistantPrivate *priv = assistant->priv;
-  GtkAssistantPage *old_page;
+  gboolean visible;
+  GList *l;
 
-  if (priv->current_page &&
-      gtk_widget_is_drawable (priv->current_page->page))
-    old_page = priv->current_page;
-  else
-    old_page = NULL;
+  page = list->data;
 
-  priv->current_page = page;
+  if (page->title == NULL || page->title[0] == 0)
+    visible = FALSE;
+  else
+    visible = gtk_widget_get_visible (page->page);
 
-  set_assistant_buttons_state (assistant);
-  set_assistant_header_image (assistant);
-  set_assistant_sidebar_image (assistant);
+  if (page == priv->current_page)
+    {
+      gtk_widget_set_visible (page->regular_title, FALSE);
+      gtk_widget_set_visible (page->current_title, visible);
+    }
+  else
+    {
+      /* If multiple consecutive pages have the same title,
+       * we only show it once, since it would otherwise look
+       * silly. We have to be a little careful, since we
+       * _always_ show the title of the current page.
+       */
+      if (list->prev)
+        {
+          other = list->prev->data;
+          if (g_strcmp0 (page->title, other->title) == 0)
+            visible = FALSE;
+        }
+      for (l = list->next; l; l = l->next)
+        {
+          other = l->data;
+          if (g_strcmp0 (page->title, other->title) != 0)
+            break;
 
-  g_signal_emit (assistant, signals [PREPARE], 0, priv->current_page->page);
+          if (other == priv->current_page)
+            {
+              visible = FALSE;
+              break;
+            }
+        }
 
-  if (gtk_widget_get_visible (priv->current_page->page) && gtk_widget_get_mapped (GTK_WIDGET (assistant)))
-    {
-      gtk_widget_set_child_visible (priv->current_page->page, TRUE);
-      gtk_widget_map (priv->current_page->page);
-      gtk_widget_map (priv->current_page->title);
+      gtk_widget_set_visible (page->regular_title, visible);
+      gtk_widget_set_visible (page->current_title, FALSE);
     }
-  
-  if (old_page && gtk_widget_get_mapped (old_page->page))
+
+  return visible;
+}
+
+static void
+update_title_state (GtkAssistant *assistant)
+{
+  GtkAssistantPrivate *priv = assistant->priv;
+  GList *l;
+  gboolean show_titles;
+
+  show_titles = FALSE;
+  for (l = priv->pages; l != NULL; l = l->next)
     {
-      gtk_widget_set_child_visible (old_page->page, FALSE);
-      gtk_widget_unmap (old_page->page);
-      gtk_widget_unmap (old_page->title);
+      if (update_page_title_state (assistant, l))
+        show_titles = TRUE;
     }
 
+  gtk_widget_set_visible (priv->sidebar, show_titles);
+}
+
+static void
+set_current_page (GtkAssistant *assistant,
+                  gint          page_num)
+{
+  GtkAssistantPrivate *priv = assistant->priv;
+
+  priv->current_page = (GtkAssistantPage *)g_list_nth_data (priv->pages, page_num);
+
+  g_signal_emit (assistant, signals [PREPARE], 0, priv->current_page->page);
+  /* do not continue if the prepare signal handler has already changed the
+   * current page */
+  if (priv->current_page != (GtkAssistantPage *)g_list_nth_data (priv->pages, page_num))
+    return;
+
+  update_title_state (assistant);
+
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->content), page_num);
+
+  /* update buttons state, flow may have changed */
+  if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
+    update_buttons_state (assistant);
+
   if (!gtk_widget_child_focus (priv->current_page->page, GTK_DIR_TAB_FORWARD))
     {
       GtkWidget *button[6];
@@ -669,7 +746,8 @@ set_current_page (GtkAssistant     *assistant,
       button[5] = priv->last;
       for (i = 0; i < 6; i++)
         {
-          if (gtk_widget_get_visible (button[i]) && gtk_widget_get_sensitive (button[i]))
+          if (gtk_widget_get_visible (button[i]) &&
+              gtk_widget_get_sensitive (button[i]))
             {
               gtk_widget_grab_focus (button[i]);
               break;
@@ -692,12 +770,12 @@ compute_next_step (GtkAssistant *assistant)
   n_pages = gtk_assistant_get_n_pages (assistant);
 
   next_page = (priv->forward_function) (current_page,
-                                       priv->forward_function_data);
+                                        priv->forward_function_data);
 
   if (next_page >= 0 && next_page < n_pages)
     {
       priv->visited_pages = g_slist_prepend (priv->visited_pages, page_info);
-      set_current_page (assistant, g_list_nth_data (priv->pages, next_page));
+      set_current_page (assistant, next_page);
 
       return TRUE;
     }
@@ -757,7 +835,7 @@ on_assistant_last (GtkWidget    *widget,
   GtkAssistantPrivate *priv = assistant->priv;
 
   while (priv->current_page->type == GTK_ASSISTANT_PAGE_CONTENT &&
-        priv->current_page->complete)
+         priv->current_page->complete)
     compute_next_step (assistant);
 }
 
@@ -772,58 +850,189 @@ alternative_button_order (GtkAssistant *assistant)
   settings = gtk_settings_get_for_screen (screen);
 
   g_object_get (settings,
-               "gtk-alternative-button-order", &result,
-               NULL);
+                "gtk-alternative-button-order", &result,
+                NULL);
   return result;
 }
 
+static gboolean
+assistant_sidebar_draw_cb (GtkWidget *widget,
+                           cairo_t *cr,
+                           gpointer user_data)
+{
+  gint width, height;
+  GtkStyleContext *context;
+
+  width = gtk_widget_get_allocated_width (widget);
+  height = gtk_widget_get_allocated_height (widget);
+  context = gtk_widget_get_style_context (widget);
+
+  gtk_render_background (context, cr, 0, 0, width, height);
+
+  return FALSE;
+}
+
+static void
+on_page_notify_visibility (GtkWidget  *widget,
+                           GParamSpec *arg,
+                           gpointer    data)
+{
+  GtkAssistant *assistant = GTK_ASSISTANT (data);
+
+  if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
+    {
+      update_buttons_state (assistant);
+      update_title_state (assistant);
+    }
+}
+
+static void
+assistant_remove_page_cb (GtkNotebook *notebook,
+                          GtkWidget *page,
+                          GtkAssistant *assistant)
+{
+  GtkAssistantPrivate *priv = assistant->priv;
+  GtkAssistantPage *page_info;
+  GList *page_node;
+  GList *element;
+
+  element = find_page (assistant, page);
+  if (!element)
+    return;
+
+  page_info = element->data;
+
+  /* If this is the current page, we need to switch away. */
+  if (page_info == priv->current_page)
+    {
+      if (!compute_next_step (assistant))
+        {
+          /* The best we can do at this point is probably to pick
+           * the first visible page.
+           */
+          page_node = priv->pages;
+
+          while (page_node &&
+                 !gtk_widget_get_visible (((GtkAssistantPage *) page_node->data)->page))
+            page_node = page_node->next;
+
+          if (page_node == element)
+            page_node = page_node->next;
+
+          if (page_node)
+            priv->current_page = page_node->data;
+          else
+            priv->current_page = NULL;
+        }
+    }
+
+  g_signal_handlers_disconnect_by_func (page_info->page, on_page_notify_visibility, assistant);
+
+  gtk_size_group_remove_widget (priv->title_size_group, page_info->regular_title);
+  gtk_size_group_remove_widget (priv->title_size_group, page_info->current_title);
+
+  gtk_container_remove (GTK_CONTAINER (priv->sidebar), page_info->regular_title);
+  gtk_container_remove (GTK_CONTAINER (priv->sidebar), page_info->current_title);
+
+  priv->pages = g_list_remove_link (priv->pages, element);
+  priv->visited_pages = g_slist_remove_all (priv->visited_pages, page_info);
+
+  g_free (page_info->title);
+
+  g_slice_free (GtkAssistantPage, page_info);
+  g_list_free_1 (element);
+
+  if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
+    {
+      update_buttons_state (assistant);
+      update_actions_size (assistant);
+    }
+}
+
 static void
 gtk_assistant_init (GtkAssistant *assistant)
 {
   GtkAssistantPrivate *priv;
+  GtkStyleContext *context;
+  GtkWidget *main_box;
+  GtkWidget *content_box;
+  GtkWidget *sidebar_frame;
 
   assistant->priv = G_TYPE_INSTANCE_GET_PRIVATE (assistant,
                                                  GTK_TYPE_ASSISTANT,
                                                  GtkAssistantPrivate);
   priv = assistant->priv;
 
-  gtk_container_set_reallocate_redraws (GTK_CONTAINER (assistant), TRUE);
-  gtk_container_set_border_width (GTK_CONTAINER (assistant), 12);
+  /* use border on inner panes instead */
+  gtk_container_set_border_width (GTK_CONTAINER (assistant), 0);
 
   gtk_widget_push_composite_child ();
 
-  /* Header */
-  priv->header_image = gtk_image_new ();
-  gtk_misc_set_alignment (GTK_MISC (priv->header_image), 1., 0.5);
-  gtk_widget_set_parent (priv->header_image, GTK_WIDGET (assistant));
-  gtk_widget_show (priv->header_image);
+  main_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+  priv->sidebar = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+
+  /* use a frame for the sidebar, and manually render a background
+   * in it. GtkFrame also gives us padding support for free.
+   */
+  sidebar_frame = gtk_frame_new (NULL);
+  context = gtk_widget_get_style_context (sidebar_frame);
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_SIDEBAR);
+
+  g_signal_connect (sidebar_frame, "draw",
+                    G_CALLBACK (assistant_sidebar_draw_cb), assistant);
 
-  /* Sidebar */
-  priv->sidebar_image = gtk_image_new ();
-  gtk_misc_set_alignment (GTK_MISC (priv->sidebar_image), 0., 0.);
-  gtk_widget_set_parent (priv->sidebar_image, GTK_WIDGET (assistant));
-  gtk_widget_show (priv->sidebar_image);
+  content_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+  gtk_container_set_border_width (GTK_CONTAINER (content_box), 12);
+  priv->content = gtk_notebook_new ();
+  gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->content), FALSE);
+  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->content), FALSE);
+  priv->action_area = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
 
-  /* Action area  */
-  priv->action_area  = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+  g_signal_connect (priv->content, "remove",
+                    G_CALLBACK (assistant_remove_page_cb), assistant);
+
+  gtk_container_add (GTK_CONTAINER (sidebar_frame), priv->sidebar);
+  gtk_box_pack_start (GTK_BOX (main_box), sidebar_frame, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (main_box), content_box, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (content_box), priv->content, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (content_box), priv->action_area, FALSE, TRUE, 0);
+  gtk_widget_set_halign (priv->action_area, GTK_ALIGN_END);
+
+  gtk_widget_show_all (main_box);
+
+  gtk_widget_set_parent (main_box, GTK_WIDGET (assistant));
+  _gtk_bin_set_child (GTK_BIN (assistant), main_box);
 
   priv->close   = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
   priv->apply   = gtk_button_new_from_stock (GTK_STOCK_APPLY);
-  priv->forward = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD);
-  priv->back    = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
+  priv->forward = gtk_button_new_with_mnemonic (_("C_ontinue"));
+  gtk_button_set_image (GTK_BUTTON (priv->forward),
+      gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_BUTTON));
+  priv->back    = gtk_button_new_with_mnemonic (_("Go _Back"));
+  gtk_button_set_image (GTK_BUTTON (priv->back),
+      gtk_image_new_from_stock (GTK_STOCK_GO_BACK, GTK_ICON_SIZE_BUTTON));
   priv->cancel  = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
-  priv->last    = gtk_button_new_from_stock (GTK_STOCK_GOTO_LAST);
+  priv->last    = gtk_button_new_with_mnemonic (_("_Finish"));
+  gtk_button_set_image (GTK_BUTTON (priv->last),
+      gtk_image_new_from_stock (GTK_STOCK_GOTO_LAST, GTK_ICON_SIZE_BUTTON));
   gtk_widget_set_can_default (priv->close, TRUE);
   gtk_widget_set_can_default (priv->apply, TRUE);
   gtk_widget_set_can_default (priv->forward, TRUE);
 
-  priv->size_group   = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
-  gtk_size_group_add_widget (priv->size_group, priv->close);
-  gtk_size_group_add_widget (priv->size_group, priv->apply);
-  gtk_size_group_add_widget (priv->size_group, priv->forward);
-  gtk_size_group_add_widget (priv->size_group, priv->back);
-  gtk_size_group_add_widget (priv->size_group, priv->cancel);
-  gtk_size_group_add_widget (priv->size_group, priv->last);
+  priv->button_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+  gtk_size_group_add_widget (priv->button_size_group, priv->close);
+  gtk_size_group_add_widget (priv->button_size_group, priv->apply);
+  gtk_size_group_add_widget (priv->button_size_group, priv->forward);
+  gtk_size_group_add_widget (priv->button_size_group, priv->back);
+  gtk_size_group_add_widget (priv->button_size_group, priv->cancel);
+  gtk_size_group_add_widget (priv->button_size_group, priv->last);
+
+  gtk_widget_set_no_show_all (priv->close, TRUE);
+  gtk_widget_set_no_show_all (priv->apply, TRUE);
+  gtk_widget_set_no_show_all (priv->forward, TRUE);
+  gtk_widget_set_no_show_all (priv->back, TRUE);
+  gtk_widget_set_no_show_all (priv->cancel, TRUE);
+  gtk_widget_set_no_show_all (priv->last, TRUE);
 
   if (!alternative_button_order (assistant))
     {
@@ -844,7 +1053,6 @@ gtk_assistant_init (GtkAssistant *assistant)
       gtk_box_pack_end (GTK_BOX (priv->action_area), priv->last, FALSE, FALSE, 0);
     }
 
-  gtk_widget_set_parent (priv->action_area, GTK_WIDGET (assistant));
   gtk_widget_show (priv->forward);
   gtk_widget_show (priv->back);
   gtk_widget_show (priv->cancel);
@@ -852,6 +1060,8 @@ gtk_assistant_init (GtkAssistant *assistant)
 
   gtk_widget_pop_composite_child ();
 
+  priv->title_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
   priv->pages = NULL;
   priv->current_page = NULL;
   priv->visited_pages = NULL;
@@ -861,47 +1071,47 @@ gtk_assistant_init (GtkAssistant *assistant)
   priv->forward_data_destroy = NULL;
 
   g_signal_connect (G_OBJECT (priv->close), "clicked",
-                   G_CALLBACK (on_assistant_close), assistant);
+                    G_CALLBACK (on_assistant_close), assistant);
   g_signal_connect (G_OBJECT (priv->apply), "clicked",
-                   G_CALLBACK (on_assistant_apply), assistant);
+                    G_CALLBACK (on_assistant_apply), assistant);
   g_signal_connect (G_OBJECT (priv->forward), "clicked",
-                   G_CALLBACK (on_assistant_forward), assistant);
+                    G_CALLBACK (on_assistant_forward), assistant);
   g_signal_connect (G_OBJECT (priv->back), "clicked",
-                   G_CALLBACK (on_assistant_back), assistant);
+                    G_CALLBACK (on_assistant_back), assistant);
   g_signal_connect (G_OBJECT (priv->cancel), "clicked",
-                   G_CALLBACK (on_assistant_cancel), assistant);
+                    G_CALLBACK (on_assistant_cancel), assistant);
   g_signal_connect (G_OBJECT (priv->last), "clicked",
-                   G_CALLBACK (on_assistant_last), assistant);
+                    G_CALLBACK (on_assistant_last), assistant);
 }
 
 static void
-gtk_assistant_set_child_property (GtkContainer    *container,
-                                 GtkWidget       *child,
-                                 guint            property_id,
-                                 const GValue    *value,
-                                 GParamSpec      *pspec)
+gtk_assistant_set_child_property (GtkContainer *container,
+                                  GtkWidget    *child,
+                                  guint         property_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
 {
   switch (property_id)
     {
     case CHILD_PROP_PAGE_TYPE:
       gtk_assistant_set_page_type (GTK_ASSISTANT (container), child,
-                                  g_value_get_enum (value));
+                                   g_value_get_enum (value));
       break;
     case CHILD_PROP_PAGE_TITLE:
       gtk_assistant_set_page_title (GTK_ASSISTANT (container), child,
-                                   g_value_get_string (value));
+                                    g_value_get_string (value));
       break;
     case CHILD_PROP_PAGE_HEADER_IMAGE:
-      gtk_assistant_set_page_header_image (GTK_ASSISTANT (container), child,
-                                          g_value_get_object (value));
+      gtk_assistant_do_set_page_header_image (GTK_ASSISTANT (container), child,
+                                              g_value_get_object (value));
       break;
     case CHILD_PROP_PAGE_SIDEBAR_IMAGE:
-      gtk_assistant_set_page_side_image (GTK_ASSISTANT (container), child,
-                                        g_value_get_object (value));
+      gtk_assistant_do_set_page_side_image (GTK_ASSISTANT (container), child,
+                                            g_value_get_object (value));
       break;
     case CHILD_PROP_PAGE_COMPLETE:
       gtk_assistant_set_page_complete (GTK_ASSISTANT (container), child,
-                                      g_value_get_boolean (value));
+                                       g_value_get_boolean (value));
       break;
     default:
       GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
@@ -911,32 +1121,34 @@ gtk_assistant_set_child_property (GtkContainer    *container,
 
 static void
 gtk_assistant_get_child_property (GtkContainer *container,
-                                 GtkWidget    *child,
-                                 guint         property_id,
-                                 GValue       *value,
-                                 GParamSpec   *pspec)
+                                  GtkWidget    *child,
+                                  guint         property_id,
+                                  GValue       *value,
+                                  GParamSpec   *pspec)
 {
+  GtkAssistant *assistant = GTK_ASSISTANT (container);
+
   switch (property_id)
     {
     case CHILD_PROP_PAGE_TYPE:
       g_value_set_enum (value,
-                       gtk_assistant_get_page_type (GTK_ASSISTANT (container), child));
+                        gtk_assistant_get_page_type (assistant, child));
       break;
     case CHILD_PROP_PAGE_TITLE:
       g_value_set_string (value,
-                         gtk_assistant_get_page_title (GTK_ASSISTANT (container), child));
+                          gtk_assistant_get_page_title (assistant, child));
       break;
     case CHILD_PROP_PAGE_HEADER_IMAGE:
       g_value_set_object (value,
-                         gtk_assistant_get_page_header_image (GTK_ASSISTANT (container), child));
+                          ((GtkAssistantPage*) find_page (assistant, child))->header_image);
       break;
     case CHILD_PROP_PAGE_SIDEBAR_IMAGE:
       g_value_set_object (value,
-                         gtk_assistant_get_page_side_image (GTK_ASSISTANT (container), child));
+                          ((GtkAssistantPage*) find_page (assistant, child))->sidebar_image);
       break;
     case CHILD_PROP_PAGE_COMPLETE:
       g_value_set_boolean (value,
-                          gtk_assistant_get_page_complete (GTK_ASSISTANT (container), child));
+                           gtk_assistant_get_page_complete (assistant, child));
       break;
     default:
       GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
@@ -945,384 +1157,87 @@ gtk_assistant_get_child_property (GtkContainer *container,
 }
 
 static void
-on_page_notify_visibility (GtkWidget  *widget,
-                          GParamSpec *arg,
-                          gpointer    data)
-{
-  GtkAssistant *assistant = GTK_ASSISTANT (data);
-
-  /* update buttons state, flow may have changed */
-  if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
-    set_assistant_buttons_state (assistant);
-}
-
-static void
-remove_page (GtkAssistant *assistant, 
-            GList        *element)
+gtk_assistant_destroy (GtkWidget *widget)
 {
+  GtkAssistant *assistant = GTK_ASSISTANT (widget);
   GtkAssistantPrivate *priv = assistant->priv;
-  GtkAssistantPage *page_info;
-  GList *page_node;
 
-  page_info = element->data;
+  /* We set current to NULL so that the remove code doesn't try
+   * to do anything funny
+   */
+  priv->current_page = NULL;
 
-  /* If this is the current page, we need to switch away. */
-  if (page_info == priv->current_page)
+  if (priv->content)
     {
-      if (!compute_next_step (assistant))
-        {
-         /* The best we can do at this point is probably to pick the first
-          * visible page.
-          */
-         page_node = priv->pages;
-
-         while (page_node && !gtk_widget_get_visible (((GtkAssistantPage *) page_node->data)->page))
-           page_node = page_node->next;
-
-          if (page_node == element)
-            page_node = page_node->next;
-
-         if (page_node)
-           priv->current_page = page_node->data;
-         else
-           priv->current_page = NULL;
-        }
-    }
-
-  priv->pages = g_list_remove_link (priv->pages, element);
-  priv->visited_pages = g_slist_remove_all (priv->visited_pages, page_info);
-
-  g_signal_handlers_disconnect_by_func (page_info->page, on_page_notify_visibility, assistant);
-  gtk_widget_unparent (page_info->page);
+      GtkNotebook *notebook;
+      GtkWidget *page;
 
-  if (page_info->header_image)
-    g_object_unref (page_info->header_image);
+      /* Remove all pages from the content notebook. */
+      notebook = (GtkNotebook *) priv->content;
+      while ((page = gtk_notebook_get_nth_page (notebook, 0)) != NULL)
+        gtk_container_remove ((GtkContainer *) notebook, page);
 
-  if (page_info->sidebar_image)
-    g_object_unref (page_info->sidebar_image);
+      /* Our GtkAssistantPage list should be empty now. */
+      g_warn_if_fail (priv->pages == NULL);
 
-  gtk_widget_destroy (page_info->title);
-  g_slice_free (GtkAssistantPage, page_info);
-  g_list_free_1 (element);
-}
-
-static void
-gtk_assistant_destroy (GtkWidget *widget)
-{
-  GtkAssistant *assistant = GTK_ASSISTANT (widget);
-  GtkAssistantPrivate *priv = assistant->priv;
-
-  if (priv->header_image)
-    {
-      gtk_widget_destroy (priv->header_image);
-      priv->header_image = NULL;
+      priv->content = NULL;
     }
 
-  if (priv->sidebar_image)
-    {
-      gtk_widget_destroy (priv->sidebar_image);
-      priv->sidebar_image = NULL;
-    }
+  if (priv->sidebar)
+    priv->sidebar = NULL;
 
   if (priv->action_area)
+    priv->action_area = NULL;
+
+  if (priv->button_size_group)
     {
-      gtk_widget_destroy (priv->action_area);
-      priv->action_area = NULL;
+      g_object_unref (priv->button_size_group);
+      priv->button_size_group = NULL;
     }
 
-  if (priv->size_group)
+  if (priv->title_size_group)
     {
-      g_object_unref (priv->size_group);
-      priv->size_group = NULL;
+      g_object_unref (priv->title_size_group);
+      priv->title_size_group = NULL;
     }
 
   if (priv->forward_function)
     {
       if (priv->forward_function_data &&
-         priv->forward_data_destroy)
-       priv->forward_data_destroy (priv->forward_function_data);
+          priv->forward_data_destroy)
+        priv->forward_data_destroy (priv->forward_function_data);
 
       priv->forward_function = NULL;
       priv->forward_function_data = NULL;
-      priv->forward_data_destroy = NULL;
-    }
-
-  if (priv->visited_pages)
-    {
-      g_slist_free (priv->visited_pages);
-      priv->visited_pages = NULL;
-    }
-
-  /* We set current to NULL so that the remove code doesn't try
-   * to do anything funny */
-  priv->current_page = NULL;
-
-  while (priv->pages)
-    remove_page (assistant, priv->pages);
-
-  GTK_WIDGET_CLASS (gtk_assistant_parent_class)->destroy (widget);
-}
-
-static GList*
-find_page (GtkAssistant  *assistant,
-          GtkWidget     *page)
-{
-  GtkAssistantPrivate *priv = assistant->priv;
-  GList *child = priv->pages;
-  
-  while (child)
-    {
-      GtkAssistantPage *page_info = child->data;
-      if (page_info->page == page)
-       return child;
-
-      child = child->next;
-    }
-  
-  return NULL;
-}
-
-static void
-set_title_colors (GtkWidget *assistant,
-                 GtkWidget *title_label)
-{
-  GtkStyle *style;
-
-  gtk_widget_ensure_style (assistant);
-  style = gtk_widget_get_style (assistant);
-
-  /* change colors schema, for making the header text visible */
-  gtk_widget_modify_bg (title_label, GTK_STATE_NORMAL, &style->bg[GTK_STATE_SELECTED]);
-  gtk_widget_modify_fg (title_label, GTK_STATE_NORMAL, &style->fg[GTK_STATE_SELECTED]);
-}
-
-static void
-set_title_font (GtkWidget *assistant,
-               GtkWidget *title_label)
-{
-  PangoFontDescription *desc;
-  gint size;
-
-  desc = pango_font_description_new ();
-  size = pango_font_description_get_size (gtk_widget_get_style (assistant)->font_desc);
-
-  pango_font_description_set_weight (desc, PANGO_WEIGHT_ULTRABOLD);
-  pango_font_description_set_size   (desc, size * PANGO_SCALE_XX_LARGE);
-
-  gtk_widget_modify_font (title_label, desc);
-  pango_font_description_free (desc);
-}
-
-static void
-gtk_assistant_style_set (GtkWidget *widget,
-                        GtkStyle  *old_style)
-{
-  GtkAssistant *assistant = GTK_ASSISTANT (widget);
-  GtkAssistantPrivate *priv = assistant->priv;
-  GList *list;
-
-  list = priv->pages;
-
-  while (list)
-    {
-      GtkAssistantPage *page = list->data;
-
-      set_title_colors (widget, page->title);
-      set_title_font (widget, page->title);
-
-      list = list->next;
-    }
-}
-
-static void
-gtk_assistant_size_request (GtkWidget      *widget,
-                           GtkRequisition *requisition)
-{
-  GtkAssistant *assistant = GTK_ASSISTANT (widget);
-  GtkAssistantPrivate *priv = assistant->priv;
-  GtkRequisition child_requisition;
-  gint header_padding, content_padding;
-  gint width, height, header_width, header_height;
-  guint border_width;
-  GList *list;
-
-  gtk_widget_style_get (widget,
-                       "header-padding", &header_padding,
-                       "content-padding", &content_padding,
-                       NULL);
-  width = height = 0;
-  header_width = header_height = 0;
-  list  = priv->pages;
-
-  while (list)
-    {
-      GtkAssistantPage *page = list->data;
-      gint w, h;
-
-      gtk_widget_get_preferred_size (page->page,
-                                     &child_requisition, NULL);
-      width  = MAX (width,  child_requisition.width);
-      height = MAX (height, child_requisition.height);
-
-      gtk_widget_get_preferred_size (page->title,
-                                     &child_requisition, NULL);
-      w = child_requisition.width;
-      h = child_requisition.height;
-
-      if (page->header_image)
-       {
-         w += gdk_pixbuf_get_width (page->header_image) + HEADER_SPACING;
-         h  = MAX (h, gdk_pixbuf_get_height (page->header_image));
-       }
-
-      header_width  = MAX (header_width, w);
-      header_height = MAX (header_height, h);
-
-      list = list->next;
-    }
-
-  gtk_widget_get_preferred_size (priv->sidebar_image,
-                                 &child_requisition, NULL);
-  width  += child_requisition.width;
-  height  = MAX (height, child_requisition.height);
-
-  gtk_widget_set_size_request (priv->header_image, header_width, header_height);
-  gtk_widget_get_preferred_size (priv->header_image,
-                                 &child_requisition, NULL);
-  width   = MAX (width, header_width) + 2 * header_padding;
-  height += header_height + 2 * header_padding;
-
-  gtk_widget_get_preferred_size (priv->action_area,
-                                 &child_requisition, NULL);
-  width   = MAX (width, child_requisition.width);
-  height += child_requisition.height + ACTION_AREA_SPACING;
-
-  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
-  width += border_width * 2 + content_padding * 2;
-  height += border_width * 2 + content_padding * 2;
-
-  requisition->width = width;
-  requisition->height = height;
-}
-
-static void
-gtk_assistant_get_preferred_width (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
-{
-  GtkRequisition requisition;
-
-  gtk_assistant_size_request (widget, &requisition);
-
-  *minimum = *natural = requisition.width;
-}
-
-static void
-gtk_assistant_get_preferred_height (GtkWidget *widget,
-                                    gint      *minimum,
-                                    gint      *natural)
-{
-  GtkRequisition requisition;
-
-  gtk_assistant_size_request (widget, &requisition);
-
-  *minimum = *natural = requisition.height;
-}
-
-static void
-gtk_assistant_size_allocate (GtkWidget      *widget,
-                            GtkAllocation  *allocation)
-{
-  GtkAssistant *assistant = GTK_ASSISTANT (widget);
-  GtkAssistantPrivate *priv = assistant->priv;
-  GtkRequisition header_requisition, action_requisition, sidebar_requisition;
-  GtkAllocation child_allocation, header_allocation;
-  GtkAllocation action_area_allocation, header_image_allocation;
-  gint header_padding, content_padding;
-  guint border_width;
-  gboolean rtl;
-  GList *pages;
-
-  rtl   = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
-  pages = priv->pages;
-
-  gtk_widget_style_get (widget,
-                       "header-padding", &header_padding,
-                       "content-padding", &content_padding,
-                       NULL);
-
-  gtk_widget_set_allocation (widget, allocation);
-  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
-
-  /* Header */
-  gtk_widget_get_preferred_size (priv->header_image,
-                                 &header_requisition, NULL);
-
-  header_allocation.x = border_width + header_padding;
-  header_allocation.y = border_width + header_padding;
-  header_allocation.width  = allocation->width - 2 * border_width - 2 * header_padding;
-  header_allocation.height = header_requisition.height;
-
-  gtk_widget_size_allocate (priv->header_image, &header_allocation);
-
-  /* Action area */
-  gtk_widget_get_preferred_size (priv->action_area,
-                                 &action_requisition, NULL);
-
-  child_allocation.x = border_width;
-  child_allocation.y = allocation->height - border_width - action_requisition.height;
-  child_allocation.width  = allocation->width - 2 * border_width;
-  child_allocation.height = action_requisition.height;
-
-  gtk_widget_size_allocate (priv->action_area, &child_allocation);
-
-  gtk_widget_get_allocation (priv->header_image, &header_image_allocation);
-  gtk_widget_get_allocation (priv->action_area, &action_area_allocation);
-
-  /* Sidebar */
-  gtk_widget_get_preferred_size (priv->sidebar_image,
-                                 &sidebar_requisition, NULL);
-
-  if (rtl)
-    child_allocation.x = allocation->width - border_width - sidebar_requisition.width;
-  else
-    child_allocation.x = border_width;
-
-  child_allocation.y = border_width + header_image_allocation.height + 2 * header_padding;
-  child_allocation.width = sidebar_requisition.width;
-  child_allocation.height = allocation->height - 2 * border_width -
-    header_image_allocation.height - 2 * header_padding - action_area_allocation.height;
-
-  gtk_widget_size_allocate (priv->sidebar_image, &child_allocation);
-
-  /* Pages */
-  child_allocation.x = border_width + content_padding;
-  child_allocation.y = border_width +
-    header_image_allocation.height + 2 * header_padding + content_padding;
-  child_allocation.width  = allocation->width - 2 * border_width - 2 * content_padding;
-  child_allocation.height = allocation->height - 2 * border_width -
-    header_image_allocation.height - 2 * header_padding - ACTION_AREA_SPACING - action_area_allocation.height - 2 * content_padding;
+      priv->forward_data_destroy = NULL;
+    }
 
-  if (gtk_widget_get_visible (priv->sidebar_image))
+  if (priv->visited_pages)
     {
-      GtkAllocation sidebar_image_allocation;
-
-      gtk_widget_get_allocation (priv->sidebar_image, &sidebar_image_allocation);
+      g_slist_free (priv->visited_pages);
+      priv->visited_pages = NULL;
+    }
 
-      if (!rtl)
-       child_allocation.x += sidebar_image_allocation.width;
+  GTK_WIDGET_CLASS (gtk_assistant_parent_class)->destroy (widget);
+}
 
-      child_allocation.width -= sidebar_image_allocation.width;
-    }
+static GList*
+find_page (GtkAssistant  *assistant,
+           GtkWidget     *page)
+{
+  GtkAssistantPrivate *priv = assistant->priv;
+  GList *child = priv->pages;
 
-  while (pages)
+  while (child)
     {
-      GtkAssistantPage *page = pages->data;
+      GtkAssistantPage *page_info = child->data;
+      if (page_info->page == page)
+        return child;
 
-      gtk_widget_size_allocate (page->page, &child_allocation);
-      gtk_widget_size_allocate (page->title, &header_allocation);
-      pages = pages->next;
+      child = child->next;
     }
+
+  return NULL;
 }
 
 static void
@@ -1332,33 +1247,31 @@ gtk_assistant_map (GtkWidget *widget)
   GtkAssistantPrivate *priv = assistant->priv;
   GList *page_node;
   GtkAssistantPage *page;
-
-  gtk_widget_set_mapped (widget, TRUE);
-
-  gtk_widget_map (priv->header_image);
-  gtk_widget_map (priv->action_area);
-
-  if (gtk_widget_get_visible (priv->sidebar_image) &&
-      !gtk_widget_get_mapped (priv->sidebar_image))
-    gtk_widget_map (priv->sidebar_image);
+  gint page_num;
 
   /* if there's no default page, pick the first one */
   page = NULL;
+  page_num = 0;
   if (!priv->current_page)
     {
       page_node = priv->pages;
 
       while (page_node && !gtk_widget_get_visible (((GtkAssistantPage *) page_node->data)->page))
-       page_node = page_node->next;
+        {
+          page_node = page_node->next;
+          page_num++;
+        }
 
       if (page_node)
-       page = page_node->data;
+        page = page_node->data;
     }
 
-  if (page &&
-      gtk_widget_get_visible (page->page) &&
-      !gtk_widget_get_mapped (page->page))
-    set_current_page (assistant, page);
+  if (page && gtk_widget_get_visible (page->page))
+    set_current_page (assistant, page_num);
+
+  update_buttons_state (assistant);
+  update_actions_size (assistant);
+  update_title_state (assistant);
 
   GTK_WIDGET_CLASS (gtk_assistant_parent_class)->map (widget);
 }
@@ -1369,18 +1282,6 @@ gtk_assistant_unmap (GtkWidget *widget)
   GtkAssistant *assistant = GTK_ASSISTANT (widget);
   GtkAssistantPrivate *priv = assistant->priv;
 
-  gtk_widget_set_mapped (widget, FALSE);
-
-  gtk_widget_unmap (priv->header_image);
-  gtk_widget_unmap (priv->action_area);
-
-  if (gtk_widget_is_drawable (priv->sidebar_image))
-    gtk_widget_unmap (priv->sidebar_image);
-
-  if (priv->current_page &&
-      gtk_widget_is_drawable (priv->current_page->page))
-    gtk_widget_unmap (priv->current_page->page);
-
   g_slist_free (priv->visited_pages);
   priv->visited_pages = NULL;
   priv->current_page  = NULL;
@@ -1390,7 +1291,7 @@ gtk_assistant_unmap (GtkWidget *widget)
 
 static gboolean
 gtk_assistant_delete_event (GtkWidget   *widget,
-                           GdkEventAny *event)
+                            GdkEventAny *event)
 {
   GtkAssistant *assistant = GTK_ASSISTANT (widget);
   GtkAssistantPrivate *priv = assistant->priv;
@@ -1404,196 +1305,36 @@ gtk_assistant_delete_event (GtkWidget   *widget,
   return TRUE;
 }
 
-static void
-assistant_paint_colored_box (GtkWidget *widget,
-                             cairo_t   *cr)
-{
-  GtkAssistant *assistant = GTK_ASSISTANT (widget);
-  GtkAssistantPrivate *priv = assistant->priv;
-  GtkAllocation allocation, action_area_allocation, header_image_allocation;
-  GtkStyle *style;
-  gint border_width, header_padding, content_padding;
-  gint content_x, content_width;
-  gboolean rtl;
-
-  rtl  = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
-  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
-
-  gtk_widget_style_get (widget,
-                       "header-padding",  &header_padding,
-                       "content-padding", &content_padding,
-                       NULL);
-
-  style = gtk_widget_get_style (widget);
-  gtk_widget_get_allocation (widget, &allocation);
-  gtk_widget_get_allocation (priv->action_area, &action_area_allocation);
-  gtk_widget_get_allocation (priv->header_image, &header_image_allocation);
-
-  /* colored box */
-  gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_SELECTED]);
-  cairo_rectangle (cr,
-                  border_width,
-                  border_width,
-                   allocation.width - 2 * border_width,
-                   allocation.height - action_area_allocation.height - 2 * border_width - ACTION_AREA_SPACING);
-  cairo_fill (cr);
-
-  /* content box */
-  content_x = content_padding + border_width;
-  content_width = allocation.width - 2 * content_padding - 2 * border_width;
-
-  if (gtk_widget_get_visible (priv->sidebar_image))
-    {
-      GtkAllocation sidebar_image_allocation;
-
-      gtk_widget_get_allocation (priv->sidebar_image, &sidebar_image_allocation);
-
-      if (!rtl)
-       content_x += sidebar_image_allocation.width;
-      content_width -= sidebar_image_allocation.width;
-    }
-
-  gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_NORMAL]);
-
-  cairo_rectangle (cr,
-                  content_x,
-                  header_image_allocation.height + content_padding + 2 * header_padding + border_width,
-                  content_width,
-                  allocation.height - 2 * border_width - action_area_allocation.height -
-                  header_image_allocation.height - 2 * content_padding - 2 * header_padding - ACTION_AREA_SPACING);
-  cairo_fill (cr);
-}
-
-static gboolean
-gtk_assistant_draw (GtkWidget *widget,
-                   cairo_t   *cr)
-{
-  GtkAssistant *assistant = GTK_ASSISTANT (widget);
-  GtkAssistantPrivate *priv = assistant->priv;
-  GtkContainer *container = GTK_CONTAINER (widget);
-
-  if (GTK_WIDGET_CLASS (gtk_assistant_parent_class)->draw)
-    GTK_WIDGET_CLASS (gtk_assistant_parent_class)->draw (widget, cr);
-
-  assistant_paint_colored_box (widget, cr);
-
-  gtk_container_propagate_draw (container, priv->header_image, cr);
-  gtk_container_propagate_draw (container, priv->sidebar_image, cr);
-  gtk_container_propagate_draw (container, priv->action_area, cr);
-
-  if (priv->current_page)
-    {
-      gtk_container_propagate_draw (container, priv->current_page->page, cr);
-      gtk_container_propagate_draw (container, priv->current_page->title, cr);
-    }
-
-  return FALSE;
-}
-
-static gboolean
-gtk_assistant_focus (GtkWidget        *widget,
-                    GtkDirectionType  direction)
-{
-  GtkAssistantPrivate *priv;
-  GtkContainer *container;
-
-  container = GTK_CONTAINER (widget);
-  priv = GTK_ASSISTANT (widget)->priv;
-
-  /* we only have to care about 2 widgets, action area and the current page */
-  if (gtk_container_get_focus_child (container) == priv->action_area)
-    {
-      if (!gtk_widget_child_focus (priv->action_area, direction) &&
-         (priv->current_page == NULL ||
-          !gtk_widget_child_focus (priv->current_page->page, direction)))
-       {
-         /* if we're leaving the action area and the current page hasn't
-            any focusable widget, clear focus and go back to the action area */
-         gtk_container_set_focus_child (GTK_CONTAINER (priv->action_area), NULL);
-         gtk_widget_child_focus (priv->action_area, direction);
-       }
-    }
-  else
-    {
-      if ((priv->current_page ==  NULL ||
-          !gtk_widget_child_focus (priv->current_page->page, direction)) &&
-         !gtk_widget_child_focus (priv->action_area, direction))
-       {
-         /* if we're leaving the current page and there isn't nothing focusable
-            in the action area, try to clear focus and go back to the page */
-         gtk_window_set_focus (GTK_WINDOW (widget), NULL);
-         if (priv->current_page != NULL)
-           gtk_widget_child_focus (priv->current_page->page, direction);
-       }
-    }
-
-  return TRUE;
-}
-
 static void
 gtk_assistant_add (GtkContainer *container,
-                  GtkWidget    *page)
+                   GtkWidget    *page)
 {
   gtk_assistant_append_page (GTK_ASSISTANT (container), page);
 }
 
 static void
 gtk_assistant_remove (GtkContainer *container,
-                     GtkWidget    *page)
-{
-  GtkAssistant *assistant = (GtkAssistant*) container;
-  GList *element;
-
-  element = find_page (assistant, page);
-
-  if (element)
-    {
-      remove_page (assistant, element);
-      gtk_widget_queue_resize ((GtkWidget *) container);
-    }
-}
-
-static void
-gtk_assistant_forall (GtkContainer *container,
-                     gboolean      include_internals,
-                     GtkCallback   callback,
-                     gpointer      callback_data)
+                      GtkWidget    *page)
 {
   GtkAssistant *assistant = (GtkAssistant*) container;
-  GtkAssistantPrivate *priv = assistant->priv;
-  GList *pages;
-
-  if (include_internals)
-    {
-      (*callback) (priv->header_image, callback_data);
-      (*callback) (priv->sidebar_image, callback_data);
-      (*callback) (priv->action_area, callback_data);
-    }
-
-  pages = priv->pages;
 
-  while (pages)
+  /* Forward this removal to the content notebook */
+  if (gtk_widget_get_parent (page) == assistant->priv->content)
     {
-      GtkAssistantPage *page = (GtkAssistantPage *) pages->data;
-
-      (*callback) (page->page, callback_data);
-
-      if (include_internals)
-       (*callback) (page->title, callback_data);
-
-      pages = pages->next;
+      container = (GtkContainer *) assistant->priv->content;
+      gtk_container_remove (container, page);
     }
 }
 
 /**
  * gtk_assistant_new:
- * 
+ *
  * Creates a new #GtkAssistant.
  *
  * Return value: a newly created #GtkAssistant
  *
  * Since: 2.10
- **/
+ */
 GtkWidget*
 gtk_assistant_new (void)
 {
@@ -1608,13 +1349,14 @@ gtk_assistant_new (void)
  * gtk_assistant_get_current_page:
  * @assistant: a #GtkAssistant
  *
- * Returns the page number of the current page
+ * Returns the page number of the current page.
  *
- * Return value: The index (starting from 0) of the current page in
- * the @assistant, if the @assistant has no pages, -1 will be returned
+ * Return value: The index (starting from 0) of the current
+ *     page in the @assistant, or -1 if the @assistant has no pages,
+ *     or no current page.
  *
  * Since: 2.10
- **/
+ */
 gint
 gtk_assistant_get_current_page (GtkAssistant *assistant)
 {
@@ -1634,19 +1376,21 @@ gtk_assistant_get_current_page (GtkAssistant *assistant)
  * gtk_assistant_set_current_page:
  * @assistant: a #GtkAssistant
  * @page_num: index of the page to switch to, starting from 0.
- *            If negative, the last page will be used. If greater
- *            than the number of pages in the @assistant, nothing
- *            will be done.
+ *     If negative, the last page will be used. If greater
+ *     than the number of pages in the @assistant, nothing
+ *     will be done.
  *
- * Switches the page to @page_num. Note that this will only be necessary
- * in custom buttons, as the @assistant flow can be set with
+ * Switches the page to @page_num.
+ *
+ * Note that this will only be necessary in custom buttons,
+ * as the @assistant flow can be set with
  * gtk_assistant_set_forward_page_func().
  *
  * Since: 2.10
- **/
+ */
 void
 gtk_assistant_set_current_page (GtkAssistant *assistant,
-                               gint          page_num)
+                                gint          page_num)
 {
   GtkAssistantPrivate *priv;
   GtkAssistantPage *page;
@@ -1658,64 +1402,66 @@ gtk_assistant_set_current_page (GtkAssistant *assistant,
   if (page_num >= 0)
     page = (GtkAssistantPage *) g_list_nth_data (priv->pages, page_num);
   else
-    page = (GtkAssistantPage *) g_list_last (priv->pages)->data;
+    {
+      page = (GtkAssistantPage *) g_list_last (priv->pages)->data;
+      page_num = g_list_length (priv->pages);
+    }
 
   g_return_if_fail (page != NULL);
 
   if (priv->current_page == page)
     return;
 
-  /* only add the page to the visited list if the
-   * assistant is mapped, if not, just use it as an
-   * initial page setting, for the cases where the
-   * initial page is != to 0
+  /* only add the page to the visited list if the assistant is mapped,
+   * if not, just use it as an initial page setting, for the cases where
+   * the initial page is != to 0
    */
   if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
     priv->visited_pages = g_slist_prepend (priv->visited_pages,
-                                          priv->current_page);
+                                           priv->current_page);
 
-  set_current_page (assistant, page);
+  set_current_page (assistant, page_num);
 }
 
 /**
  * gtk_assistant_next_page:
  * @assistant: a #GtkAssistant
  *
- * Navigate to the next page. It is a programming
- *  error to call this function if there is no next page.
+ * Navigate to the next page.
+ *
+ * It is a programming error to call this function when
+ * there is no next page.
  *
  * This function is for use when creating pages of the
- *  #GTK_ASSISTANT_PAGE_CUSTOM type.
+ * #GTK_ASSISTANT_PAGE_CUSTOM type.
  *
  * Since: 3.0
- **/
+ */
 void
 gtk_assistant_next_page (GtkAssistant *assistant)
 {
-  GtkAssistantPrivate *priv;
-
   g_return_if_fail (GTK_IS_ASSISTANT (assistant));
 
-  priv = assistant->priv;
-
   if (!compute_next_step (assistant))
-    g_critical ("Page flow is broken, you may want to end it with a page of "
-               "type GTK_ASSISTANT_PAGE_CONFIRM or GTK_ASSISTANT_PAGE_SUMMARY");
+    g_critical ("Page flow is broken.\n"
+                "You may want to end it with a page of type\n"
+                "GTK_ASSISTANT_PAGE_CONFIRM or GTK_ASSISTANT_PAGE_SUMMARY");
 }
 
 /**
  * gtk_assistant_previous_page:
  * @assistant: a #GtkAssistant
  *
- * Navigate to the previous visited page. It is a programming
- *  error to call this function if no previous page is
- *  available.
+ * Navigate to the previous visited page.
+ *
+ * It is a programming error to call this function when
+ * no previous page is available.
  *
  * This function is for use when creating pages of the
- *  #GTK_ASSISTANT_PAGE_CUSTOM type.
+ * #GTK_ASSISTANT_PAGE_CUSTOM type.
  *
  * Since: 3.0
- **/
+ */
 void
 gtk_assistant_previous_page (GtkAssistant *assistant)
 {
@@ -1739,9 +1485,9 @@ gtk_assistant_previous_page (GtkAssistant *assistant)
       g_slist_free_1 (page_node);
     }
   while (page_info->type == GTK_ASSISTANT_PAGE_PROGRESS ||
-        !gtk_widget_get_visible (page_info->page));
+         !gtk_widget_get_visible (page_info->page));
 
-  set_current_page (assistant, page_info);
+  set_current_page (assistant, g_list_index (priv->pages, page_info));
 }
 
 /**
@@ -1750,10 +1496,10 @@ gtk_assistant_previous_page (GtkAssistant *assistant)
  *
  * Returns the number of pages in the @assistant
  *
- * Return value: The number of pages in the @assistant.
+ * Return value: the number of pages in the @assistant
  *
  * Since: 2.10
- **/
+ */
 gint
 gtk_assistant_get_n_pages (GtkAssistant *assistant)
 {
@@ -1769,18 +1515,19 @@ gtk_assistant_get_n_pages (GtkAssistant *assistant)
 /**
  * gtk_assistant_get_nth_page:
  * @assistant: a #GtkAssistant
- * @page_num: The index of a page in the @assistant, or -1 to get the last page;
+ * @page_num: the index of a page in the @assistant,
+ *     or -1 to get the last page
  *
  * Returns the child widget contained in page number @page_num.
  *
- * Return value: (transfer none): The child widget, or %NULL
- *     if @page_num is out of bounds.
+ * Return value: (transfer none): the child widget, or %NULL
+ *     if @page_num is out of bounds
  *
  * Since: 2.10
- **/
+ */
 GtkWidget*
 gtk_assistant_get_nth_page (GtkAssistant *assistant,
-                           gint          page_num)
+                            gint          page_num)
 {
   GtkAssistantPrivate *priv;
   GtkAssistantPage *page;
@@ -1814,10 +1561,10 @@ gtk_assistant_get_nth_page (GtkAssistant *assistant,
  * Return value: the index (starting at 0) of the inserted page
  *
  * Since: 2.10
- **/
+ */
 gint
 gtk_assistant_prepend_page (GtkAssistant *assistant,
-                           GtkWidget    *page)
+                            GtkWidget    *page)
 {
   g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), 0);
   g_return_val_if_fail (GTK_IS_WIDGET (page), 0);
@@ -1835,10 +1582,10 @@ gtk_assistant_prepend_page (GtkAssistant *assistant,
  * Return value: the index (starting at 0) of the inserted page
  *
  * Since: 2.10
- **/
+ */
 gint
 gtk_assistant_append_page (GtkAssistant *assistant,
-                          GtkWidget    *page)
+                           GtkWidget    *page)
 {
   g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), 0);
   g_return_val_if_fail (GTK_IS_WIDGET (page), 0);
@@ -1851,22 +1598,23 @@ gtk_assistant_append_page (GtkAssistant *assistant,
  * @assistant: a #GtkAssistant
  * @page: a #GtkWidget
  * @position: the index (starting at 0) at which to insert the page,
- *            or -1 to append the page to the @assistant
+ *     or -1 to append the page to the @assistant
  *
  * Inserts a page in the @assistant at a given position.
  *
  * Return value: the index (starting from 0) of the inserted page
  *
  * Since: 2.10
- **/
+ */
 gint
 gtk_assistant_insert_page (GtkAssistant *assistant,
-                          GtkWidget    *page,
-                          gint          position)
+                           GtkWidget    *page,
+                           gint          position)
 {
   GtkAssistantPrivate *priv;
   GtkAssistantPage *page_info;
   gint n_pages;
+  GtkStyleContext *context;
 
   g_return_val_if_fail (GTK_IS_ASSISTANT (assistant), 0);
   g_return_val_if_fail (GTK_IS_WIDGET (page), 0);
@@ -1877,15 +1625,30 @@ gtk_assistant_insert_page (GtkAssistant *assistant,
 
   page_info = g_slice_new0 (GtkAssistantPage);
   page_info->page  = page;
-  page_info->title = gtk_label_new (NULL);
+  page_info->regular_title = gtk_label_new (NULL);
+  gtk_widget_set_no_show_all (page_info->regular_title, TRUE);
+  page_info->current_title = gtk_label_new (NULL);
+  gtk_widget_set_no_show_all (page_info->current_title, TRUE);
+
+  /* Note: we need to use misc alignment here as long as GtkLabel
+   * pays attention to it. GtkWiget::halign is ineffective, since
+   * all the labels are getting the same size anyway, due to the
+   * size group.
+   */
+  gtk_misc_set_alignment (GTK_MISC (page_info->regular_title), 0, 0.5);
+  gtk_widget_show (page_info->regular_title);
 
-  g_signal_connect (G_OBJECT (page), "notify::visible",
-                   G_CALLBACK (on_page_notify_visibility), assistant);
+  gtk_misc_set_alignment (GTK_MISC (page_info->current_title), 0, 0.5);
+  gtk_widget_hide (page_info->current_title);
+
+  context = gtk_widget_get_style_context (page_info->current_title);
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
 
-  gtk_misc_set_alignment (GTK_MISC (page_info->title), 0.,0.5);
-  set_title_colors (GTK_WIDGET (assistant), page_info->title);
-  set_title_font   (GTK_WIDGET (assistant), page_info->title);
-  gtk_widget_show  (page_info->title);
+  gtk_size_group_add_widget (priv->title_size_group, page_info->regular_title);
+  gtk_size_group_add_widget (priv->title_size_group, page_info->current_title);
+
+  g_signal_connect (G_OBJECT (page), "notify::visible",
+                    G_CALLBACK (on_page_notify_visibility), assistant);
 
   n_pages = g_list_length (priv->pages);
 
@@ -1894,41 +1657,69 @@ gtk_assistant_insert_page (GtkAssistant *assistant,
 
   priv->pages = g_list_insert (priv->pages, page_info, position);
 
-  gtk_widget_set_child_visible (page_info->page, FALSE);
-  gtk_widget_set_parent (page_info->page,  GTK_WIDGET (assistant));
-  gtk_widget_set_parent (page_info->title, GTK_WIDGET (assistant));
+  gtk_box_pack_start (GTK_BOX (priv->sidebar), page_info->regular_title, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (priv->sidebar), page_info->current_title, FALSE, FALSE, 0);
+  gtk_box_reorder_child (GTK_BOX (priv->sidebar), page_info->regular_title, 2 * position);
+  gtk_box_reorder_child (GTK_BOX (priv->sidebar), page_info->current_title, 2 * position + 1);
 
-  if (gtk_widget_get_realized (GTK_WIDGET (assistant)))
+  gtk_notebook_insert_page (GTK_NOTEBOOK (priv->content), page, NULL, position);
+
+  if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
     {
-      gtk_widget_realize (page_info->page);
-      gtk_widget_realize (page_info->title);
+      update_buttons_state (assistant);
+      update_actions_size (assistant);
     }
 
-  gtk_widget_queue_resize (GTK_WIDGET (assistant));
-
   return position;
 }
 
+/**
+ * gtk_assistant_remove_page:
+ * @assistant: a #GtkAssistant
+ * @page_num: the index of a page in the @assistant,
+ *     or -1 to remove the last page
+ *
+ * Removes the @page_num's page from @assistant.
+ *
+ * Since: 3.2
+ */
+void
+gtk_assistant_remove_page (GtkAssistant *assistant,
+                           gint          page_num)
+{
+  GtkWidget *page;
+
+  g_return_if_fail (GTK_IS_ASSISTANT (assistant));
+
+  page = gtk_assistant_get_nth_page (assistant, page_num);
+
+  if (page)
+    gtk_container_remove (GTK_CONTAINER (assistant), page);
+}
+
 /**
  * gtk_assistant_set_forward_page_func:
  * @assistant: a #GtkAssistant
- * @page_func: (allow-none): the #GtkAssistantPageFunc, or %NULL to use the default one
+ * @page_func: (allow-none): the #GtkAssistantPageFunc, or %NULL
+ *     to use the default one
  * @data: user data for @page_func
  * @destroy: destroy notifier for @data
  *
- * Sets the page forwarding function to be @page_func, this function will
- * be used to determine what will be the next page when the user presses
- * the forward button. Setting @page_func to %NULL will make the assistant
- * to use the default forward function, which just goes to the next visible 
- * page.
+ * Sets the page forwarding function to be @page_func.
+ *
+ * This function will be used to determine what will be
+ * the next page when the user presses the forward button.
+ * Setting @page_func to %NULL will make the assistant to
+ * use the default forward function, which just goes to the
+ * next visible page.
  *
  * Since: 2.10
- **/
+ */
 void
 gtk_assistant_set_forward_page_func (GtkAssistant         *assistant,
-                                    GtkAssistantPageFunc  page_func,
-                                    gpointer              data,
-                                    GDestroyNotify        destroy)
+                                     GtkAssistantPageFunc  page_func,
+                                     gpointer              data,
+                                     GDestroyNotify        destroy)
 {
   GtkAssistantPrivate *priv;
 
@@ -1954,22 +1745,24 @@ gtk_assistant_set_forward_page_func (GtkAssistant         *assistant,
     }
 
   /* Page flow has possibly changed, so the
-     buttons state might need to change too */
-  set_assistant_buttons_state (assistant);
+   * buttons state might need to change too
+   */
+  if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
+    update_buttons_state (assistant);
 }
 
 /**
  * gtk_assistant_add_action_widget:
  * @assistant: a #GtkAssistant
  * @child: a #GtkWidget
- * 
+ *
  * Adds a widget to the action area of a #GtkAssistant.
  *
  * Since: 2.10
- **/
+ */
 void
 gtk_assistant_add_action_widget (GtkAssistant *assistant,
-                                GtkWidget    *child)
+                                 GtkWidget    *child)
 {
   GtkAssistantPrivate *priv;
 
@@ -1979,7 +1772,12 @@ gtk_assistant_add_action_widget (GtkAssistant *assistant,
   priv = assistant->priv;
 
   if (GTK_IS_BUTTON (child))
-    gtk_size_group_add_widget (priv->size_group, child);
+    {
+      gtk_size_group_add_widget (priv->button_size_group, child);
+      priv->extra_buttons += 1;
+      if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
+        update_actions_size (assistant);
+    }
 
   gtk_box_pack_end (GTK_BOX (priv->action_area), child, FALSE, FALSE, 0);
 }
@@ -1992,10 +1790,10 @@ gtk_assistant_add_action_widget (GtkAssistant *assistant,
  * Removes a widget from the action area of a #GtkAssistant.
  *
  * Since: 2.10
- **/
+ */
 void
 gtk_assistant_remove_action_widget (GtkAssistant *assistant,
-                                   GtkWidget    *child)
+                                    GtkWidget    *child)
 {
   GtkAssistantPrivate *priv;
 
@@ -2005,7 +1803,12 @@ gtk_assistant_remove_action_widget (GtkAssistant *assistant,
   priv = assistant->priv;
 
   if (GTK_IS_BUTTON (child))
-    gtk_size_group_remove_widget (priv->size_group, child);
+    {
+      gtk_size_group_remove_widget (priv->button_size_group, child);
+      priv->extra_buttons -= 1;
+      if (gtk_widget_get_mapped (GTK_WIDGET (assistant)))
+        update_actions_size (assistant);
+    }
 
   gtk_container_remove (GTK_CONTAINER (priv->action_area), child);
 }
@@ -2015,16 +1818,18 @@ gtk_assistant_remove_action_widget (GtkAssistant *assistant,
  * @assistant: a #GtkAssistant
  * @page: a page of @assistant
  * @title: the new title for @page
- * 
- * Sets a title for @page. The title is displayed in the header
- * area of the assistant when @page is the current page.
+ *
+ * Sets a title for @page.
+ *
+ * The title is displayed in the header area of the assistant
+ * when @page is the current page.
  *
  * Since: 2.10
- **/
+ */
 void
 gtk_assistant_set_page_title (GtkAssistant *assistant,
-                             GtkWidget    *page,
-                             const gchar  *title)
+                              GtkWidget    *page,
+                              const gchar  *title)
 {
   GtkAssistantPage *page_info;
   GList *child;
@@ -2038,25 +1843,30 @@ gtk_assistant_set_page_title (GtkAssistant *assistant,
 
   page_info = (GtkAssistantPage*) child->data;
 
-  gtk_label_set_text ((GtkLabel*) page_info->title, title);
+  g_free (page_info->title);
+  page_info->title = g_strdup (title);
+
+  gtk_label_set_text ((GtkLabel*) page_info->regular_title, title);
+  gtk_label_set_text ((GtkLabel*) page_info->current_title, title);
+
   gtk_widget_queue_resize (GTK_WIDGET (assistant));
-  gtk_widget_child_notify (page, "title");
+  gtk_container_child_notify (GTK_CONTAINER (assistant), page, "title");
 }
 
 /**
  * gtk_assistant_get_page_title:
  * @assistant: a #GtkAssistant
  * @page: a page of @assistant
- * 
- * Gets the title for @page. 
- * 
- * Return value: the title for @page.
+ *
+ * Gets the title for @page.
+ *
+ * Return value: the title for @page
  *
  * Since: 2.10
- **/
-G_CONST_RETURN gchar*
+ */
+const gchar*
 gtk_assistant_get_page_title (GtkAssistant *assistant,
-                             GtkWidget    *page)
+                              GtkWidget    *page)
 {
   GtkAssistantPage *page_info;
   GList *child;
@@ -2070,7 +1880,7 @@ gtk_assistant_get_page_title (GtkAssistant *assistant,
 
   page_info = (GtkAssistantPage*) child->data;
 
-  return gtk_label_get_text ((GtkLabel*) page_info->title);
+  return page_info->title;
 }
 
 /**
@@ -2078,25 +1888,24 @@ gtk_assistant_get_page_title (GtkAssistant *assistant,
  * @assistant: a #GtkAssistant
  * @page: a page of @assistant
  * @type: the new type for @page
- * 
- * Sets the page type for @page. The page type determines the page
- * behavior in the @assistant.
+ *
+ * Sets the page type for @page.
+ *
+ * The page type determines the page behavior in the @assistant.
  *
  * Since: 2.10
- **/
+ */
 void
 gtk_assistant_set_page_type (GtkAssistant         *assistant,
-                            GtkWidget            *page,
-                            GtkAssistantPageType  type)
+                             GtkWidget            *page,
+                             GtkAssistantPageType  type)
 {
-  GtkAssistantPrivate *priv;
   GtkAssistantPage *page_info;
   GList *child;
 
   g_return_if_fail (GTK_IS_ASSISTANT (assistant));
   g_return_if_fail (GTK_IS_WIDGET (page));
 
-  priv = assistant->priv;
   child = find_page (assistant, page);
 
   g_return_if_fail (child != NULL);
@@ -2115,10 +1924,11 @@ gtk_assistant_set_page_type (GtkAssistant         *assistant,
         }
 
       /* Always set buttons state, a change in a future page
-        might change current page buttons */
-      set_assistant_buttons_state (assistant);
+       * might change current page buttons
+       */
+      update_buttons_state (assistant);
 
-      gtk_widget_child_notify (page, "page-type");
+      gtk_container_child_notify (GTK_CONTAINER (assistant), page, "page-type");
     }
 }
 
@@ -2129,13 +1939,13 @@ gtk_assistant_set_page_type (GtkAssistant         *assistant,
  *
  * Gets the page type of @page.
  *
- * Return value: the page type of @page.
+ * Return value: the page type of @page
  *
  * Since: 2.10
- **/
+ */
 GtkAssistantPageType
 gtk_assistant_get_page_type (GtkAssistant *assistant,
-                            GtkWidget    *page)
+                             GtkWidget    *page)
 {
   GtkAssistantPage *page_info;
   GList *child;
@@ -2158,25 +1968,33 @@ gtk_assistant_get_page_type (GtkAssistant *assistant,
  * @page: a page of @assistant
  * @pixbuf: (allow-none): the new header image @page
  *
- * Sets a header image for @page. This image is displayed in the header
- * area of the assistant when @page is the current page.
+ * Sets a header image for @page.
  *
  * Since: 2.10
- **/
+ *
+ * Deprecated: 3.2: Since GTK+ 3.2, a header is no longer shown;
+ *     add your header decoration to the page content instead.
+ */
 void
 gtk_assistant_set_page_header_image (GtkAssistant *assistant,
-                                    GtkWidget    *page,
-                                    GdkPixbuf    *pixbuf)
+                                     GtkWidget    *page,
+                                     GdkPixbuf    *pixbuf)
 {
-  GtkAssistantPrivate *priv;
-  GtkAssistantPage *page_info;
-  GList *child;
-
   g_return_if_fail (GTK_IS_ASSISTANT (assistant));
   g_return_if_fail (GTK_IS_WIDGET (page));
   g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
 
-  priv = assistant->priv;
+  gtk_assistant_do_set_page_header_image (assistant, page, pixbuf);
+}
+
+static void
+gtk_assistant_do_set_page_header_image (GtkAssistant *assistant,
+                                        GtkWidget    *page,
+                                        GdkPixbuf    *pixbuf)
+{
+  GtkAssistantPage *page_info;
+  GList *child;
+
   child = find_page (assistant, page);
 
   g_return_if_fail (child != NULL);
@@ -2186,18 +2004,15 @@ gtk_assistant_set_page_header_image (GtkAssistant *assistant,
   if (pixbuf != page_info->header_image)
     {
       if (page_info->header_image)
-       {
-         g_object_unref (page_info->header_image);
-         page_info->header_image = NULL;
-       }
+        {
+          g_object_unref (page_info->header_image);
+          page_info->header_image = NULL;
+        }
 
       if (pixbuf)
-       page_info->header_image = g_object_ref (pixbuf);
+        page_info->header_image = g_object_ref (pixbuf);
 
-      if (page_info == priv->current_page)
-       set_assistant_header_image (assistant);
-
-      gtk_widget_child_notify (page, "header-image");
+      gtk_container_child_notify (GTK_CONTAINER (assistant), page, "header-image");
     }
 }
 
@@ -2208,14 +2023,17 @@ gtk_assistant_set_page_header_image (GtkAssistant *assistant,
  *
  * Gets the header image for @page.
  *
- * Return value: (transfer none): the header image for @page, or %NULL
- *     if there's no header image for the page.
+ * Return value: (transfer none): the header image for @page,
+ *     or %NULL if there's no header image for the page
  *
  * Since: 2.10
- **/
+ *
+ * Deprecated: 3.2: Since GTK+ 3.2, a header is no longer shown;
+ *     add your header decoration to the page content instead.
+ */
 GdkPixbuf*
 gtk_assistant_get_page_header_image (GtkAssistant *assistant,
-                                    GtkWidget    *page)
+                                     GtkWidget    *page)
 {
   GtkAssistantPage *page_info;
   GList *child;
@@ -2236,27 +2054,38 @@ gtk_assistant_get_page_header_image (GtkAssistant *assistant,
  * gtk_assistant_set_page_side_image:
  * @assistant: a #GtkAssistant
  * @page: a page of @assistant
- * @pixbuf: (allow-none): the new header image @page
+ * @pixbuf: (allow-none): the new side image @page
  *
- * Sets a header image for @page. This image is displayed in the side
- * area of the assistant when @page is the current page.
+ * Sets a side image for @page.
+ *
+ * This image used to be displayed in the side area of the assistant
+ * when @page is the current page.
  *
  * Since: 2.10
- **/
+ *
+ * Deprecated: 3.2: Since GTK+ 3.2, sidebar images are not
+ *     shown anymore.
+ */
 void
 gtk_assistant_set_page_side_image (GtkAssistant *assistant,
-                                  GtkWidget    *page,
-                                  GdkPixbuf    *pixbuf)
+                                   GtkWidget    *page,
+                                   GdkPixbuf    *pixbuf)
 {
-  GtkAssistantPrivate *priv;
-  GtkAssistantPage *page_info;
-  GList *child;
-
   g_return_if_fail (GTK_IS_ASSISTANT (assistant));
   g_return_if_fail (GTK_IS_WIDGET (page));
   g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
 
-  priv = assistant->priv;
+  gtk_assistant_do_set_page_side_image (assistant, page, pixbuf);
+}
+
+static void
+gtk_assistant_do_set_page_side_image (GtkAssistant *assistant,
+                                      GtkWidget    *page,
+                                      GdkPixbuf    *pixbuf)
+{
+  GtkAssistantPage *page_info;
+  GList *child;
+
   child = find_page (assistant, page);
 
   g_return_if_fail (child != NULL);
@@ -2266,18 +2095,15 @@ gtk_assistant_set_page_side_image (GtkAssistant *assistant,
   if (pixbuf != page_info->sidebar_image)
     {
       if (page_info->sidebar_image)
-       {
-         g_object_unref (page_info->sidebar_image);
-         page_info->sidebar_image = NULL;
-       }
+        {
+          g_object_unref (page_info->sidebar_image);
+          page_info->sidebar_image = NULL;
+        }
 
       if (pixbuf)
-       page_info->sidebar_image = g_object_ref (pixbuf);
-
-      if (page_info == priv->current_page)
-       set_assistant_sidebar_image (assistant);
+        page_info->sidebar_image = g_object_ref (pixbuf);
 
-      gtk_widget_child_notify (page, "sidebar-image");
+      gtk_container_child_notify (GTK_CONTAINER (assistant), page, "sidebar-image");
     }
 }
 
@@ -2286,16 +2112,19 @@ gtk_assistant_set_page_side_image (GtkAssistant *assistant,
  * @assistant: a #GtkAssistant
  * @page: a page of @assistant
  *
- * Gets the header image for @page.
+ * Gets the side image for @page.
  *
- * Return value: (transfer none): the side image for @page, or %NULL
- *     if there's no side image for the page.
+ * Return value: (transfer none): the side image for @page,
+ *     or %NULL if there's no side image for the page
  *
  * Since: 2.10
- **/
+ *
+ * Deprecated: 3.2: Since GTK+ 3.2, sidebar images are not
+ *     shown anymore.
+ */
 GdkPixbuf*
 gtk_assistant_get_page_side_image (GtkAssistant *assistant,
-                                  GtkWidget    *page)
+                                   GtkWidget    *page)
 {
   GtkAssistantPage *page_info;
   GList *child;
@@ -2317,25 +2146,25 @@ gtk_assistant_get_page_side_image (GtkAssistant *assistant,
  * @assistant: a #GtkAssistant
  * @page: a page of @assistant
  * @complete: the completeness status of the page
- * 
- * Sets whether @page contents are complete. This will make
- * @assistant update the buttons state to be able to continue the task.
+ *
+ * Sets whether @page contents are complete.
+ *
+ * This will make @assistant update the buttons state
+ * to be able to continue the task.
  *
  * Since: 2.10
- **/
+ */
 void
 gtk_assistant_set_page_complete (GtkAssistant *assistant,
-                                GtkWidget    *page,
-                                gboolean      complete)
+                                 GtkWidget    *page,
+                                 gboolean      complete)
 {
-  GtkAssistantPrivate *priv;
   GtkAssistantPage *page_info;
   GList *child;
 
   g_return_if_fail (GTK_IS_ASSISTANT (assistant));
   g_return_if_fail (GTK_IS_WIDGET (page));
 
-  priv = assistant->priv;
   child = find_page (assistant, page);
 
   g_return_if_fail (child != NULL);
@@ -2348,10 +2177,11 @@ gtk_assistant_set_page_complete (GtkAssistant *assistant,
       page_info->complete_set = TRUE;
 
       /* Always set buttons state, a change in a future page
-        might change current page buttons */
-      set_assistant_buttons_state (assistant);
+       * might change current page buttons
+       */
+      update_buttons_state (assistant);
 
-      gtk_widget_child_notify (page, "complete");
+      gtk_container_child_notify (GTK_CONTAINER (assistant), page, "complete");
     }
 }
 
@@ -2359,16 +2189,16 @@ gtk_assistant_set_page_complete (GtkAssistant *assistant,
  * gtk_assistant_get_page_complete:
  * @assistant: a #GtkAssistant
  * @page: a page of @assistant
- * 
+ *
  * Gets whether @page is complete.
- * 
+ *
  * Return value: %TRUE if @page is complete.
  *
  * Since: 2.10
- **/
+ */
 gboolean
 gtk_assistant_get_page_complete (GtkAssistant *assistant,
-                                GtkWidget    *page)
+                                 GtkWidget    *page)
 {
   GtkAssistantPage *page_info;
   GList *child;
@@ -2388,10 +2218,10 @@ gtk_assistant_get_page_complete (GtkAssistant *assistant,
 /**
  * gtk_assistant_update_buttons_state:
  * @assistant: a #GtkAssistant
- * 
+ *
  * Forces @assistant to recompute the buttons state.
- * 
- * GTK+ automatically takes care of this in most situations, 
+ *
+ * GTK+ automatically takes care of this in most situations,
  * e.g. when the user goes to a different page, or when the
  * visibility or completeness of a page changes.
  *
@@ -2400,13 +2230,13 @@ gtk_assistant_get_page_complete (GtkAssistant *assistant,
  * affects the future page flow of the assistant.
  *
  * Since: 2.10
- **/
+ */
 void
 gtk_assistant_update_buttons_state (GtkAssistant *assistant)
 {
   g_return_if_fail (GTK_IS_ASSISTANT (assistant));
 
-  set_assistant_buttons_state (assistant);
+  update_buttons_state (assistant);
 }
 
 /**
@@ -2419,12 +2249,12 @@ gtk_assistant_update_buttons_state (GtkAssistant *assistant)
  *
  * Use this when the information provided up to the current
  * page is hereafter deemed permanent and cannot be modified
- * or undone.  For example, showing a progress page to track
+ * or undone. For example, showing a progress page to track
  * a long-running, unreversible operation after the user has
  * clicked apply on a confirmation page.
  *
  * Since: 2.22
- **/
+ */
 void
 gtk_assistant_commit (GtkAssistant *assistant)
 {
@@ -2435,33 +2265,32 @@ gtk_assistant_commit (GtkAssistant *assistant)
 
   assistant->priv->committed = TRUE;
 
-  set_assistant_buttons_state (assistant);
+  update_buttons_state (assistant);
 }
 
+/* accessible implementation */
 
+/* dummy typedefs */
+typedef GtkWindowAccessible      GtkAssistantAccessible;
+typedef GtkWindowAccessibleClass GtkAssistantAccessibleClass;
 
-/* accessible implementation */
+G_DEFINE_TYPE (GtkAssistantAccessible, _gtk_assistant_accessible, GTK_TYPE_WINDOW_ACCESSIBLE);
 
 static gint
 gtk_assistant_accessible_get_n_children (AtkObject *accessible)
 {
-  GtkAssistant *assistant;
   GtkWidget *widget;
 
   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
-
-  if (!widget)
+  if (widget == NULL)
     return 0;
 
-  assistant = GTK_ASSISTANT (widget);
-   
-  return g_list_length (assistant->priv->pages) + 1;
+  return g_list_length (GTK_ASSISTANT (widget)->priv->pages) + 1;
 }
 
-
 static AtkObject *
 gtk_assistant_accessible_ref_child (AtkObject *accessible,
-                                   gint       index)
+                                    gint       index)
 {
   GtkAssistant *assistant;
   GtkAssistantPrivate *priv;
@@ -2471,7 +2300,7 @@ gtk_assistant_accessible_ref_child (AtkObject *accessible,
   const gchar *title;
 
   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
-  if (!widget)
+  if (widget == NULL)
     return NULL;
 
   assistant = GTK_ASSISTANT (widget);
@@ -2494,7 +2323,7 @@ gtk_assistant_accessible_ref_child (AtkObject *accessible,
     }
   else
     return NULL;
-  
+
   obj = gtk_widget_get_accessible (child);
 
   if (title)
@@ -2504,130 +2333,20 @@ gtk_assistant_accessible_ref_child (AtkObject *accessible,
 }
 
 static void
-gtk_assistant_accessible_class_init (AtkObjectClass *class)
-{
-  class->get_n_children = gtk_assistant_accessible_get_n_children;
-  class->ref_child = gtk_assistant_accessible_ref_child;
-}
-
-static GType
-gtk_assistant_accessible_get_type (void)
+_gtk_assistant_accessible_class_init (GtkAssistantAccessibleClass *klass)
 {
-  static GType type = 0;
-  
-  if (!type)
-    {
-      /*
-       * Figure out the size of the class and instance
-       * we are deriving from
-       */
-      AtkObjectFactory *factory;
-      GType derived_type;
-      GTypeQuery query;
-      GType derived_atk_type;
-
-      derived_type = g_type_parent (GTK_TYPE_ASSISTANT);
-      factory = atk_registry_get_factory (atk_get_default_registry (),
-                                         derived_type);
-      derived_atk_type = atk_object_factory_get_accessible_type (factory);
-      g_type_query (derived_atk_type, &query);
-
-      type = g_type_register_static_simple (derived_atk_type,
-                                           I_("GtkAssistantAccessible"),
-                                           query.class_size,
-                                           (GClassInitFunc) gtk_assistant_accessible_class_init,
-                                           query.instance_size,
-                                           NULL, 0);
-    }
-
-  return type;
-}
-
-static AtkObject *
-gtk_assistant_accessible_new (GObject *obj)
-{
-  AtkObject *accessible;
+  AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass);
 
-  g_return_val_if_fail (GTK_IS_ASSISTANT (obj), NULL);
-
-  accessible = g_object_new (gtk_assistant_accessible_get_type (), NULL);
-  atk_object_initialize (accessible, obj);
-
-  return accessible;
-}
-
-static GType
-gtk_assistant_accessible_factory_get_accessible_type (void)
-{
-  return gtk_assistant_accessible_get_type ();
-}
-
-static AtkObject*
-gtk_assistant_accessible_factory_create_accessible (GObject *obj)
-{
-  return gtk_assistant_accessible_new (obj);
+  atk_class->get_n_children = gtk_assistant_accessible_get_n_children;
+  atk_class->ref_child = gtk_assistant_accessible_ref_child;
 }
 
 static void
-gtk_assistant_accessible_factory_class_init (AtkObjectFactoryClass *class)
+_gtk_assistant_accessible_init (GtkAssistantAccessible *self)
 {
-  class->create_accessible = gtk_assistant_accessible_factory_create_accessible;
-  class->get_accessible_type = gtk_assistant_accessible_factory_get_accessible_type;
-}
-
-static GType
-gtk_assistant_accessible_factory_get_type (void)
-{
-  static GType type = 0;
-
-  if (!type)
-    {
-      type = g_type_register_static_simple (ATK_TYPE_OBJECT_FACTORY,
-                                           I_("GtkAssistantAccessibleFactory"),
-                                           sizeof (AtkObjectFactoryClass),
-                                           (GClassInitFunc) gtk_assistant_accessible_factory_class_init,
-                                           sizeof (AtkObjectFactory),
-                                           NULL, 0);
-    }
-
-  return type;
-}
-
-static AtkObject *
-gtk_assistant_get_accessible (GtkWidget *widget)
-{
-  static gboolean first_time = TRUE;
-
-  if (first_time)
-    {
-      AtkObjectFactory *factory;
-      AtkRegistry *registry;
-      GType derived_type;
-      GType derived_atk_type;
-
-      /*
-       * Figure out whether accessibility is enabled by looking at the
-       * type of the accessible object which would be created for
-       * the parent type of GtkAssistant.
-       */
-      derived_type = g_type_parent (GTK_TYPE_ASSISTANT);
-
-      registry = atk_get_default_registry ();
-      factory = atk_registry_get_factory (registry,
-                                         derived_type);
-      derived_atk_type = atk_object_factory_get_accessible_type (factory);
-      if (g_type_is_a (derived_atk_type, GTK_TYPE_ACCESSIBLE))
-       {
-         atk_registry_set_factory_type (registry,
-                                        GTK_TYPE_ASSISTANT,
-                                        gtk_assistant_accessible_factory_get_type ());
-       }
-      first_time = FALSE;
-    }
-
-  return GTK_WIDGET_CLASS (gtk_assistant_parent_class)->get_accessible (widget);
 }
 
+/* buildable implementation */
 
 static GtkBuildableIface *parent_buildable_iface;