Index: gtk/gtkactivatable.c
===================================================================
--- gtk/gtkactivatable.c	(revision 0)
+++ gtk/gtkactivatable.c	(revision 0)
@@ -0,0 +1,310 @@
+/* gtkactivatable.c
+ * Copyright (C) 2008 Tristan Van Berkom <tristan.van.berkom@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gtk-activatable
+ * @Short_Description: An interface for activatable widgets.
+ *
+ * Activatable widgets can be connected to a #GtkAction and reflects
+ * the state of its action - a #GtkActivatable can also provide feedback
+ * through its action, as they are responsible for activating their 
+ * related actions.
+ */
+
+#include "config.h"
+#include "gtkactivatable.h"
+#include "gtkactiongroup.h"
+#include "gtktypeutils.h"
+#include "gtkprivate.h"
+#include "gtkintl.h"
+#include "gtkalias.h"
+
+
+static void gtk_activatable_class_init (gpointer g_iface);
+
+GType
+gtk_activatable_get_type (void)
+{
+  static GType activatable_type = 0;
+
+  if (!activatable_type)
+    activatable_type =
+      g_type_register_static_simple (G_TYPE_INTERFACE, I_("GtkActivatable"),
+				     sizeof (GtkActivatableIface),
+				     (GClassInitFunc) gtk_activatable_class_init,
+				     0, NULL, 0);
+
+  return activatable_type;
+}
+
+static void
+gtk_activatable_class_init (gpointer g_iface)
+{
+  /**
+   * GtkActivatable:related-action:
+   * 
+   * The action that this activatable will activate and receive
+   * updates from for various states and possibly appearance.
+   *
+   * <note><para>#GtkActivatable implementors need to handle the this property and 
+   * call gtk_activatable_do_set_related_action() when it changes.</para></note>
+   *
+   * Since: 2.16
+   */
+  g_object_interface_install_property (g_iface,
+				       g_param_spec_object ("related-action",
+							    P_("Related Action"),
+							    P_("The action this activatable will activate and receive updates from"),
+							    GTK_TYPE_ACTION,
+							    GTK_PARAM_READWRITE));
+
+  /**
+   * GtkActivatable:use-action-appearance:
+   * 
+   * Whether this activatable should reset its layout
+   * and appearance when setting the related action or when
+   * the action changes appearance.
+   *
+   * See the #GtkAction documentation directly to find which properties
+   * should be ignored by the #GtkActivatable when this property is %FALSE.
+   *
+   * <note><para>#GtkActivatable implementors need to handle this property
+   * and call gtk_activatable_reset() to update the activatable widget if needed.</para></note>
+   *
+   * Since: 2.16
+   */
+  g_object_interface_install_property (g_iface,
+				       g_param_spec_boolean ("use-action-appearance",
+							     P_("Use Action Appearance"),
+							     P_("Whether to use the related actions appearance properties"),
+							     TRUE,
+							     GTK_PARAM_READWRITE));
+
+
+}
+
+
+/**
+ * gtk_activatable_update:
+ * @activatable: a #GtkActivatable
+ * @action: the related #GtkAction
+ * @property_name: the name of the action property to update from, or %NULL
+ *
+ * This is called internally to update @activatable when @action's properties
+ * change. When implementing #GtkActivatable you must implement this method
+ * to synchonize your action.
+ *
+ * Since: 2.16
+ **/
+void
+gtk_activatable_update (GtkActivatable *activatable,
+			GtkAction      *action,
+			const gchar    *property_name)
+{
+  GtkActivatableIface *iface;
+
+  g_return_if_fail (GTK_IS_ACTIVATABLE (activatable));
+
+  iface = GTK_ACTIVATABLE_GET_IFACE (activatable);
+  if (iface->update)
+    iface->update (activatable, action, property_name);
+  else
+    g_critical ("GtkActivatable->update() unimplemented for type %s", 
+		g_type_name (G_OBJECT_TYPE (activatable)));
+}
+
+/**
+ * gtk_activatable_reset:
+ * @activatable: a #GtkActivatable
+ * @action: the related #GtkAction
+ *
+ * This is called when connecting an action or when toggling #GtkActivatable:use-action-appearance
+ * with a connected action. When implementing #GtkActivatable you must implement this method
+ * to synchronize all relavent properties.
+ *
+ * <note><para>#GtkActivatable implementors also need to call this when the #GtkActivatable:use-action-appearance
+ * property changes if an action is connected.</para></note>
+ *
+ * Since: 2.16
+ **/
+void
+gtk_activatable_reset (GtkActivatable *activatable,
+		       GtkAction      *action)
+{
+  GtkActivatableIface *iface;
+
+  g_return_if_fail (GTK_IS_ACTIVATABLE (activatable));
+
+  iface = GTK_ACTIVATABLE_GET_IFACE (activatable);
+  if (iface->reset)
+    iface->reset (activatable, action);
+  else
+    g_critical ("GtkActivatable->reset() unimplemented for type %s", 
+		g_type_name (G_OBJECT_TYPE (activatable)));
+}
+
+
+/**
+ * gtk_activatable_set_related_action:
+ * @activatable: a #GtkActivatable
+ * @action: the #GtkAction to set
+ *
+ * Sets the related action on the @activatable object.
+ *
+ * <note><para>#GtkActivatable implementors need to handle the #GtkActivatable:related-action
+ * property and call gtk_activatable_do_set_related_action() when it changes.</para></note>
+ *
+ * Since: 2.16
+ **/
+void
+gtk_activatable_set_related_action (GtkActivatable *activatable,
+				    GtkAction      *action)
+{
+  g_return_if_fail (GTK_IS_ACTIVATABLE (activatable));
+  g_return_if_fail (action == NULL || GTK_IS_ACTION (action));
+
+  g_object_set (activatable, "related-action", action, NULL);
+}
+
+static void
+gtk_activatable_action_notify (GtkAction      *action,
+			       GParamSpec     *pspec,
+			       GtkActivatable *activatable)
+{
+  gtk_activatable_update (activatable, action, pspec->name);
+}
+
+/**
+ * gtk_activatable_do_set_related_action:
+ * @activatable: a #GtkActivatable
+ * @action: the #GtkAction to set
+ * 
+ * This is a utility function for #GtkActivatable implementors.
+ * 
+ * When implementing #GtkActivatable you must call this when
+ * handling changes of the #GtkActivatable:related-action, and
+ * you must also use this to break references in #GObject->dispose().
+ *
+ * This function takes care of connecting to the notify signal
+ * of the related action, managing a reference on the action and
+ * registering the #GtkActivatable on the action's proxy list.
+ *
+ * <note><para>Be careful to call this before setting the local
+ * copy of the #GtkAction property, since this function uses 
+ * gtk_activatable_get_action() to retrieve the previous action</para></note>
+ */
+void
+gtk_activatable_do_set_related_action (GtkActivatable *activatable,
+				       GtkAction      *action)
+{
+  GtkAction *prev_action;
+
+  prev_action = gtk_activatable_get_related_action (activatable);
+  
+  if (prev_action)
+    {
+      g_signal_handlers_disconnect_by_func (prev_action, gtk_activatable_action_notify, activatable);
+
+      _gtk_action_remove_from_proxy_list (prev_action, GTK_WIDGET (activatable));
+
+      g_object_unref (prev_action);
+    }
+
+  if (action)
+    {
+      g_object_ref (action);
+
+      g_signal_connect (G_OBJECT (action), "notify", G_CALLBACK (gtk_activatable_action_notify), activatable);
+
+      _gtk_action_add_to_proxy_list (action, GTK_WIDGET (activatable));
+
+      gtk_activatable_reset (activatable, action);
+    }
+}
+
+/**
+ * gtk_activatable_get_related_action:
+ * @activatable: a #GtkActivatable
+ *
+ * Gets the related #GtkAction for @activatable.
+ *
+ * Returns: the related #GtkAction if one is set.
+ *
+ * Since: 2.16
+ **/
+GtkAction *
+gtk_activatable_get_related_action (GtkActivatable *activatable)
+{
+  GtkAction *action;
+
+  g_return_val_if_fail (GTK_IS_ACTIVATABLE (activatable), NULL);
+
+  g_object_get (activatable, "related-action", &action, NULL);
+
+  /* g_object_get() gives us a ref... */
+  if (action)
+    g_object_unref (action);
+
+  return action;
+}
+
+/**
+ * gtk_activatable_set_use_action_appearance:
+ * @activatable: a #GtkActivatable
+ * @use_appearance: whether to use the actions appearance
+ *
+ * Sets whether this activatable should reset its layout and appearance 
+ * when setting the related action or when the action changes appearance 
+ *
+ * <note><para>#GtkActivatable implementors need to handle the #GtkActivatable:use-action-appearance
+ * property and call gtk_activatable_reset() to update @activatable if needed.</para></note>
+ *
+ * Since: 2.16
+ **/
+void
+gtk_activatable_set_use_action_appearance  (GtkActivatable *activatable,
+					    gboolean        use_appearance)
+{
+  g_object_set (activatable, "use-action-appearance", use_appearance, NULL);
+}
+
+/**
+ * gtk_activatable_get_use_action_appearance:
+ * @activatable: a #GtkActivatable
+ *
+ * Gets whether this activatable should reset its layout
+ * and appearance when setting the related action or when
+ * the action changes appearance.
+ *
+ * Returns: whether @activatable uses its actions appearance.
+ *
+ * Since: 2.16
+ **/
+gboolean
+gtk_activatable_get_use_action_appearance  (GtkActivatable *activatable)
+{
+  gboolean use_appearance;
+
+  g_object_get (activatable, "use-action-appearance", &use_appearance, NULL);  
+
+  return use_appearance;
+}
+
+#define __GTK_ACTIVATABLE_C__
+#include "gtkaliasdef.c"
Index: gtk/gtkactivatable.h
===================================================================
--- gtk/gtkactivatable.h	(revision 0)
+++ gtk/gtkactivatable.h	(revision 0)
@@ -0,0 +1,75 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2008 Tristan Van Berkom <tristan.van.berkom@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_ACTIVATABLE_H__
+#define __GTK_ACTIVATABLE_H__
+
+#include <gtk/gtkaction.h>
+#include <gtk/gtktypeutils.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_ACTIVATABLE            (gtk_activatable_get_type ())
+#define GTK_ACTIVATABLE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ACTIVATABLE, GtkActivatable))
+#define GTK_ACTIVATABLE_CLASS(obj)      (G_TYPE_CHECK_CLASS_CAST ((obj), GTK_TYPE_ACTIVATABLE, GtkActivatableIface))
+#define GTK_IS_ACTIVATABLE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ACTIVATABLE))
+#define GTK_ACTIVATABLE_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_ACTIVATABLE, GtkActivatableIface))
+
+
+typedef struct _GtkActivatable      GtkActivatable; /* Dummy typedef */
+typedef struct _GtkActivatableIface GtkActivatableIface;
+
+struct _GtkActivatableIface
+{
+  GTypeInterface g_iface;
+
+  /* virtual table */
+  void   (* update)  (GtkActivatable *, GtkAction *, const gchar *);
+  void   (* reset)   (GtkActivatable *, GtkAction *);
+};
+
+
+GType      gtk_activatable_get_type                   (void) G_GNUC_CONST;
+
+void       gtk_activatable_update                     (GtkActivatable *activatable,
+						       GtkAction      *action,
+						       const gchar    *property_name);
+
+void       gtk_activatable_reset                      (GtkActivatable *activatable,
+						       GtkAction      *action);
+
+void       gtk_activatable_set_related_action         (GtkActivatable *activatable,
+						       GtkAction      *action);
+GtkAction *gtk_activatable_get_related_action         (GtkActivatable *activatable);
+
+void       gtk_activatable_set_use_action_appearance  (GtkActivatable *activatable,
+						       gboolean        use_appearance);
+gboolean   gtk_activatable_get_use_action_appearance  (GtkActivatable *activatable);
+
+/* For use in activatable implementations */
+void       gtk_activatable_do_set_related_action      (GtkActivatable *activatable,
+						       GtkAction      *action);
+
+G_END_DECLS
+
+#endif /* __GTK_ACTIVATABLE_H__ */
Index: gtk/gtkwidget.h
===================================================================
--- gtk/gtkwidget.h	(revision 22083)
+++ gtk/gtkwidget.h	(working copy)
@@ -146,6 +146,7 @@ typedef struct _GtkWidgetShapeInfo GtkWi
 typedef struct _GtkClipboard	   GtkClipboard;
 typedef struct _GtkTooltip         GtkTooltip;
 typedef struct _GtkWindow          GtkWindow;
+typedef struct _GtkActionGroup     GtkActionGroup;
 typedef void     (*GtkCallback)        (GtkWidget        *widget,
 					gpointer	  data);
 
Index: gtk/gtktogglebutton.c
===================================================================
--- gtk/gtktogglebutton.c	(revision 22083)
+++ gtk/gtktogglebutton.c	(working copy)
@@ -29,6 +29,8 @@
 #include "gtkmain.h"
 #include "gtkmarshalers.h"
 #include "gtktogglebutton.h"
+#include "gtktoggleaction.h"
+#include "gtkactivatable.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
 #include "gtkalias.h"
@@ -67,9 +69,20 @@ static void gtk_toggle_button_get_proper
 					     GParamSpec           *pspec);
 static void gtk_toggle_button_update_state  (GtkButton            *button);
 
-static guint toggle_button_signals[LAST_SIGNAL] = { 0 };
 
-G_DEFINE_TYPE (GtkToggleButton, gtk_toggle_button, GTK_TYPE_BUTTON)
+static void gtk_toggle_button_activatable_interface_init (GtkActivatableIface  *iface);
+static void gtk_toggle_button_activatable_update         (GtkActivatable       *activatable,
+							  GtkAction            *action,
+							  const gchar          *property_name);
+static void gtk_toggle_button_activatable_reset          (GtkActivatable       *activatable,
+							  GtkAction            *action);
+
+static GtkActivatableIface *parent_activatable_iface;
+static guint                toggle_button_signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE_WITH_CODE (GtkToggleButton, gtk_toggle_button, GTK_TYPE_BUTTON,
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
+						gtk_toggle_button_activatable_interface_init))
 
 static void
 gtk_toggle_button_class_init (GtkToggleButtonClass *class)
@@ -139,6 +152,50 @@ gtk_toggle_button_init (GtkToggleButton 
 }
 
 
+static void 
+gtk_toggle_button_activatable_interface_init (GtkActivatableIface  *iface)
+{
+  parent_activatable_iface = g_type_interface_peek_parent (iface);
+  iface->update = gtk_toggle_button_activatable_update;
+  iface->reset = gtk_toggle_button_activatable_reset;
+}
+
+static void
+gtk_toggle_button_activatable_update (GtkActivatable   *activatable,
+				      GtkAction        *action,
+				      const gchar      *property_name)
+{
+  GtkToggleButton *button;
+
+  parent_activatable_iface->update (activatable, action, property_name);
+
+  button = GTK_TOGGLE_BUTTON (activatable);
+
+  if (strcmp (property_name, "active") == 0)
+    {
+      gtk_action_block_activate (action);
+      gtk_toggle_button_set_active (button, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
+      gtk_action_unblock_activate (action);
+    }
+
+}
+
+static void
+gtk_toggle_button_activatable_reset (GtkActivatable   *activatable,
+				     GtkAction        *action)
+{
+  GtkToggleButton *button;
+
+  parent_activatable_iface->reset (activatable, action);
+
+  button = GTK_TOGGLE_BUTTON (activatable);
+
+  gtk_action_block_activate (action);
+  gtk_toggle_button_set_active (button, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
+  gtk_action_unblock_activate (action);
+}
+
+
 GtkWidget*
 gtk_toggle_button_new (void)
 {
@@ -441,6 +498,8 @@ gtk_toggle_button_clicked (GtkButton *bu
   gtk_toggle_button_update_state (button);
 
   g_object_notify (G_OBJECT (toggle_button), "active");
+
+  GTK_BUTTON_CLASS (gtk_toggle_button_parent_class)->clicked (button);
 }
 
 static void
Index: gtk/gtktoggleaction.c
===================================================================
--- gtk/gtktoggleaction.c	(revision 22083)
+++ gtk/gtktoggleaction.c	(working copy)
@@ -54,11 +54,6 @@ enum {
 G_DEFINE_TYPE (GtkToggleAction, gtk_toggle_action, GTK_TYPE_ACTION)
 
 static void gtk_toggle_action_activate     (GtkAction       *action);
-static void gtk_toggle_action_real_toggled (GtkToggleAction *action);
-static void connect_proxy                  (GtkAction       *action,
-					    GtkWidget       *proxy);
-static void disconnect_proxy               (GtkAction       *action,
-					    GtkWidget       *proxy);
 static void set_property                   (GObject         *object,
 					    guint            prop_id,
 					    const GValue    *value,
@@ -87,16 +82,22 @@ gtk_toggle_action_class_init (GtkToggleA
   gobject_class->get_property = get_property;
 
   action_class->activate = gtk_toggle_action_activate;
-  action_class->connect_proxy = connect_proxy;
-  action_class->disconnect_proxy = disconnect_proxy;
 
   action_class->menu_item_type = GTK_TYPE_CHECK_MENU_ITEM;
   action_class->toolbar_item_type = GTK_TYPE_TOGGLE_TOOL_BUTTON;
 
   action_class->create_menu_item = create_menu_item;
 
-  klass->toggled = gtk_toggle_action_real_toggled;
+  klass->toggled = NULL;
 
+  /**
+   * GtkToggleAction:draw-as-radio:
+   *
+   * Whether the proxies for this action look like radio action proxies.
+   *
+   * This is an appearance property and thus only applies if 
+   * #GtkActivatable:use-action-appearance is %TRUE.
+   */
   g_object_class_install_property (gobject_class,
                                    PROP_DRAW_AS_RADIO,
                                    g_param_spec_boolean ("draw-as-radio",
@@ -232,64 +233,6 @@ gtk_toggle_action_activate (GtkAction *a
   gtk_toggle_action_toggled (toggle_action);
 }
 
-static void
-gtk_toggle_action_real_toggled (GtkToggleAction *action)
-{
-  GSList *slist;
-
-  g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
-
-  for (slist = gtk_action_get_proxies (GTK_ACTION (action)); slist; slist = slist->next)
-    {
-      GtkWidget *proxy = slist->data;
-
-      gtk_action_block_activate_from (GTK_ACTION (action), proxy);
-      if (GTK_IS_CHECK_MENU_ITEM (proxy))
-	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (proxy),
-					action->private_data->active);
-      else if (GTK_IS_TOGGLE_TOOL_BUTTON (proxy))
-	gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (proxy),
-					   action->private_data->active);
-      else if (GTK_IS_TOGGLE_BUTTON (proxy))
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (proxy),
-				      action->private_data->active);
-      else {
-	g_warning ("Don't know how to toggle `%s' widgets",
-		   G_OBJECT_TYPE_NAME (proxy));
-      }
-      gtk_action_unblock_activate_from (GTK_ACTION (action), proxy);
-    }
-}
-
-static void
-connect_proxy (GtkAction *action, 
-	       GtkWidget *proxy)
-{
-  GtkToggleAction *toggle_action;
-
-  toggle_action = GTK_TOGGLE_ACTION (action);
-
-  /* do this before hand, so that we don't call the "activate" handler */
-  if (GTK_IS_CHECK_MENU_ITEM (proxy))
-    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (proxy),
-				    toggle_action->private_data->active);
-  else if (GTK_IS_TOGGLE_TOOL_BUTTON (proxy))
-    gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (proxy),
-				       toggle_action->private_data->active);
-  else if (GTK_IS_TOGGLE_BUTTON (proxy))
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (proxy),
-				  toggle_action->private_data->active);
-
-  GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
-}
-
-static void
-disconnect_proxy (GtkAction *action, 
-		  GtkWidget *proxy)
-{
-  GTK_ACTION_CLASS (parent_class)->disconnect_proxy (action, proxy);
-}
-
 /**
  * gtk_toggle_action_toggled:
  * @action: the action object
Index: gtk/gtkcheckmenuitem.c
===================================================================
--- gtk/gtkcheckmenuitem.c	(revision 22083)
+++ gtk/gtkcheckmenuitem.c	(working copy)
@@ -27,6 +27,8 @@
 #include "config.h"
 #include "gtkcheckmenuitem.h"
 #include "gtkaccellabel.h"
+#include "gtkactivatable.h"
+#include "gtktoggleaction.h"
 #include "gtkmarshalers.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
@@ -53,19 +55,28 @@ static void gtk_check_menu_item_draw_ind
 						      GdkRectangle          *area);
 static void gtk_real_check_menu_item_draw_indicator  (GtkCheckMenuItem      *check_menu_item,
 						      GdkRectangle          *area);
-static void gtk_check_menu_item_set_property (GObject         *object,
-					      guint            prop_id,
-					      const GValue    *value,
-					      GParamSpec      *pspec);
-static void gtk_check_menu_item_get_property (GObject         *object,
-					      guint            prop_id,
-					      GValue          *value,
-					      GParamSpec      *pspec);
-
-
-static guint check_menu_item_signals[LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (GtkCheckMenuItem, gtk_check_menu_item, GTK_TYPE_MENU_ITEM)
+static void gtk_check_menu_item_set_property         (GObject               *object,
+						      guint                  prop_id,
+						      const GValue          *value,
+						      GParamSpec            *pspec);
+static void gtk_check_menu_item_get_property         (GObject               *object,
+						      guint                  prop_id,
+						      GValue                *value,
+						      GParamSpec            *pspec);
+
+static void gtk_check_menu_item_activatable_interface_init (GtkActivatableIface  *iface);
+static void gtk_check_menu_item_activatable_update         (GtkActivatable       *activatable,
+							    GtkAction            *action,
+							    const gchar          *property_name);
+static void gtk_check_menu_item_activatable_reset          (GtkActivatable       *activatable,
+							    GtkAction            *action);
+
+static GtkActivatableIface *parent_activatable_iface;
+static guint                check_menu_item_signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE_WITH_CODE (GtkCheckMenuItem, gtk_check_menu_item, GTK_TYPE_MENU_ITEM,
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
+						gtk_check_menu_item_activatable_interface_init))
 
 static void
 gtk_check_menu_item_class_init (GtkCheckMenuItemClass *klass)
@@ -107,8 +118,7 @@ gtk_check_menu_item_class_init (GtkCheck
   
   gtk_widget_class_install_style_property (widget_class,
                                            g_param_spec_int ("indicator-size",
-                                                             P_("Indicator Size")
-,
+                                                             P_("Indicator Size"),
                                                              P_("Size of check or radio indicator"),
                                                              0,
                                                              G_MAXINT,
@@ -134,6 +144,61 @@ gtk_check_menu_item_class_init (GtkCheck
 		  G_TYPE_NONE, 0);
 }
 
+static void 
+gtk_check_menu_item_activatable_interface_init (GtkActivatableIface  *iface)
+{
+  parent_activatable_iface = g_type_interface_peek_parent (iface);
+  iface->update = gtk_check_menu_item_activatable_update;
+  iface->reset = gtk_check_menu_item_activatable_reset;
+}
+
+static void 
+gtk_check_menu_item_activatable_update (GtkActivatable       *activatable,
+					GtkAction            *action,
+					const gchar          *property_name)
+{
+  GtkCheckMenuItem *check_menu_item;
+
+  check_menu_item = GTK_CHECK_MENU_ITEM (activatable);
+
+  parent_activatable_iface->update (activatable, action, property_name);
+
+  if (strcmp (property_name, "active") == 0)
+    {
+      gtk_action_block_activate (action);
+      gtk_check_menu_item_set_active (check_menu_item, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
+      gtk_action_unblock_activate (action);
+    }
+
+  if (!gtk_activatable_get_use_action_appearance (activatable))
+    return;
+
+  if (strcmp (property_name, "draw-as-radio") == 0)
+    gtk_check_menu_item_set_draw_as_radio (check_menu_item, 
+					   gtk_toggle_action_get_draw_as_radio (GTK_TOGGLE_ACTION (action)));
+}
+
+static void 
+gtk_check_menu_item_activatable_reset (GtkActivatable       *activatable,
+				       GtkAction            *action)
+{
+  GtkCheckMenuItem *check_menu_item;
+
+  check_menu_item = GTK_CHECK_MENU_ITEM (activatable);
+
+  parent_activatable_iface->reset (activatable, action);
+
+  gtk_action_block_activate (action);
+  gtk_check_menu_item_set_active (check_menu_item, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
+  gtk_action_unblock_activate (action);
+  
+  if (!gtk_activatable_get_use_action_appearance (activatable))
+    return;
+
+  gtk_check_menu_item_set_draw_as_radio (check_menu_item, 
+					 gtk_toggle_action_get_draw_as_radio (GTK_TOGGLE_ACTION (action)));
+}
+
 GtkWidget*
 gtk_check_menu_item_new (void)
 {
@@ -351,6 +416,8 @@ gtk_check_menu_item_activate (GtkMenuIte
   gtk_check_menu_item_toggled (check_menu_item);
   gtk_widget_queue_draw (GTK_WIDGET (check_menu_item));
 
+  GTK_MENU_ITEM_CLASS (gtk_check_menu_item_parent_class)->activate (menu_item);
+
   g_object_notify (G_OBJECT (check_menu_item), "active");
 }
 
Index: gtk/gtkrecentchooserdefault.c
===================================================================
--- gtk/gtkrecentchooserdefault.c	(revision 22083)
+++ gtk/gtkrecentchooserdefault.c	(working copy)
@@ -65,6 +65,7 @@
 #include "gtktooltip.h"
 #include "gtktypebuiltins.h"
 #include "gtkvbox.h"
+#include "gtkactivatable.h"
 
 #include "gtkrecentmanager.h"
 #include "gtkrecentfilter.h"
@@ -76,7 +77,15 @@
 #include "gtkprivate.h"
 #include "gtkalias.h"
 
-
+enum 
+{
+  PROP_0,
+
+  /* activatable properties */
+  PROP_ACTIVATABLE_RELATED_ACTION,
+  PROP_ACTIVATABLE_USE_ACTION_APPEARANCE
+};
+
 
 struct _GtkRecentChooserDefault
 {
@@ -274,13 +283,20 @@ static gboolean recent_view_query_toolti
                                                    GtkTooltip       *tooltip,
                                                    gpointer          user_data);
 
-
+static void gtk_recent_chooser_activatable_iface_init (GtkActivatableIface  *iface);
+static void gtk_recent_chooser_activatable_update     (GtkActivatable       *activatable,
+						       GtkAction            *action,
+						       const gchar          *property_name);
+static void gtk_recent_chooser_activatable_reset      (GtkActivatable       *activatable,
+						       GtkAction            *action);
 
 G_DEFINE_TYPE_WITH_CODE (GtkRecentChooserDefault,
 			 _gtk_recent_chooser_default,
 			 GTK_TYPE_VBOX,
 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_RECENT_CHOOSER,
-				 		gtk_recent_chooser_iface_init))
+				 		gtk_recent_chooser_iface_init)
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
+				 		gtk_recent_chooser_activatable_iface_init))
 
 
 
@@ -302,6 +318,14 @@ gtk_recent_chooser_iface_init (GtkRecent
   iface->list_filters = gtk_recent_chooser_default_list_filters;
 }
 
+static void 
+gtk_recent_chooser_activatable_iface_init (GtkActivatableIface  *iface)
+
+{  
+  iface->update = gtk_recent_chooser_activatable_update;
+  iface->reset  = gtk_recent_chooser_activatable_reset;
+}
+
 static void
 _gtk_recent_chooser_default_class_init (GtkRecentChooserDefaultClass *klass)
 {
@@ -318,6 +342,9 @@ _gtk_recent_chooser_default_class_init (
   widget_class->show_all = gtk_recent_chooser_default_show_all;
   
   _gtk_recent_chooser_install_properties (gobject_class);
+
+  g_object_class_override_property (gobject_class, PROP_ACTIVATABLE_RELATED_ACTION, "related-action");
+  g_object_class_override_property (gobject_class, PROP_ACTIVATABLE_USE_ACTION_APPEARANCE, "use-action-appearance");
 }
 
 static void
@@ -528,6 +555,12 @@ gtk_recent_chooser_default_set_property 
     case GTK_RECENT_CHOOSER_PROP_FILTER:
       set_current_filter (impl, g_value_get_object (value));
       break;
+    case PROP_ACTIVATABLE_RELATED_ACTION:
+      _gtk_recent_chooser_set_related_action (GTK_RECENT_CHOOSER (impl), g_value_get_object (value));
+      break;
+    case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE: 
+      _gtk_recent_chooser_set_use_action_appearance (GTK_RECENT_CHOOSER (impl), g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -571,6 +604,12 @@ gtk_recent_chooser_default_get_property 
     case GTK_RECENT_CHOOSER_PROP_FILTER:
       g_value_set_object (value, impl->current_filter);
       break;
+    case PROP_ACTIVATABLE_RELATED_ACTION:
+      g_value_set_object (value, _gtk_recent_chooser_get_related_action (GTK_RECENT_CHOOSER (impl)));
+      break;
+    case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE: 
+      g_value_set_boolean (value, _gtk_recent_chooser_get_use_action_appearance (GTK_RECENT_CHOOSER (impl)));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1909,6 +1948,41 @@ set_recent_manager (GtkRecentChooserDefa
     }
 }
 
+static void 
+gtk_recent_chooser_activatable_update (GtkActivatable       *activatable,
+				       GtkAction            *action,
+				       const gchar          *property_name)
+{
+  if (strcmp (property_name, "visible") == 0)
+    {
+      if (gtk_action_is_visible (action))
+	gtk_widget_show (GTK_WIDGET (activatable));
+      else
+	gtk_widget_hide (GTK_WIDGET (activatable));
+    }
+
+  if (strcmp (property_name, "sensitive") == 0)
+    gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
+
+  _gtk_recent_chooser_activatable_update (activatable, action, property_name);
+}
+
+
+static void 
+gtk_recent_chooser_activatable_reset (GtkActivatable       *activatable,
+				      GtkAction            *action)
+{
+  if (gtk_action_is_visible (action))
+    gtk_widget_show (GTK_WIDGET (activatable));
+  else
+    gtk_widget_hide (GTK_WIDGET (activatable));
+
+  gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
+
+  _gtk_recent_chooser_activatable_reset (activatable, action);
+}
+
+
 GtkWidget *
 _gtk_recent_chooser_default_new (GtkRecentManager *manager)
 {
Index: gtk/gtkrecentchooserprivate.h
===================================================================
--- gtk/gtkrecentchooserprivate.h	(revision 22083)
+++ gtk/gtkrecentchooserprivate.h	(working copy)
@@ -25,17 +25,30 @@
 
 #include "gtkrecentmanager.h"
 #include "gtkrecentchooser.h"
+#include "gtkactivatable.h"
 
 G_BEGIN_DECLS
 
-GtkRecentManager *_gtk_recent_chooser_get_recent_manager (GtkRecentChooser  *chooser);
-GList *           _gtk_recent_chooser_get_items          (GtkRecentChooser  *chooser,
-                                                          GtkRecentFilter   *filter,
-                                                          GtkRecentSortFunc  func,
-                                                          gpointer           data);
-
-void              _gtk_recent_chooser_item_activated     (GtkRecentChooser  *chooser);
-void              _gtk_recent_chooser_selection_changed  (GtkRecentChooser  *chooser);
+GtkRecentManager *_gtk_recent_chooser_get_recent_manager     (GtkRecentChooser  *chooser);
+GList *           _gtk_recent_chooser_get_items              (GtkRecentChooser  *chooser,
+							      GtkRecentFilter   *filter,
+							      GtkRecentSortFunc  func,
+							      gpointer           data);
+
+void              _gtk_recent_chooser_item_activated         (GtkRecentChooser  *chooser);
+void              _gtk_recent_chooser_selection_changed      (GtkRecentChooser  *chooser);
+
+void              _gtk_recent_chooser_activatable_update     (GtkActivatable       *activatable,
+							      GtkAction            *action,
+							      const gchar          *property_name);
+void              _gtk_recent_chooser_activatable_reset      (GtkActivatable       *activatable,
+							      GtkAction            *action);
+void              _gtk_recent_chooser_set_related_action     (GtkRecentChooser     *recent_chooser, 
+							      GtkAction            *action);
+GtkAction        *_gtk_recent_chooser_get_related_action     (GtkRecentChooser     *recent_chooser);
+void              _gtk_recent_chooser_set_use_action_appearance (GtkRecentChooser  *recent_chooser, 
+								 gboolean           use_appearance);
+gboolean          _gtk_recent_chooser_get_use_action_appearance (GtkRecentChooser  *recent_chooser);
 
 G_END_DECLS
 
Index: gtk/gtktoggletoolbutton.c
===================================================================
--- gtk/gtktoggletoolbutton.c	(revision 22083)
+++ gtk/gtktoggletoolbutton.c	(working copy)
@@ -1,4 +1,4 @@
-/* gtktoggletoolbutton.c
+ /* gtktoggletoolbutton.c
  *
  * Copyright (C) 2002 Anders Carlsson <andersca@gnome.org>
  * Copyright (C) 2002 James Henstridge <james@daa.com.au>
@@ -27,6 +27,8 @@
 #include "gtkstock.h"
 #include "gtkintl.h"
 #include "gtkradiotoolbutton.h"
+#include "gtktoggleaction.h"
+#include "gtkactivatable.h"
 #include "gtkprivate.h"
 #include "gtkalias.h"
 
@@ -67,9 +69,20 @@ static void button_toggled      (GtkWidg
 static void menu_item_activated (GtkWidget           *widget,
 				 GtkToggleToolButton *button);
 
-static guint         toggle_signals[LAST_SIGNAL] = { 0 };
 
-G_DEFINE_TYPE (GtkToggleToolButton, gtk_toggle_tool_button, GTK_TYPE_TOOL_BUTTON)
+static void gtk_toggle_tool_button_activatable_interface_init (GtkActivatableIface  *iface);
+static void gtk_toggle_tool_button_activatable_update         (GtkActivatable       *activatable,
+							       GtkAction            *action,
+							       const gchar          *property_name);
+static void gtk_toggle_tool_button_activatable_reset          (GtkActivatable       *activatable,
+							       GtkAction            *action);
+
+static GtkActivatableIface *parent_activatable_iface;
+static guint                toggle_signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE_WITH_CODE (GtkToggleToolButton, gtk_toggle_tool_button, GTK_TYPE_TOOL_BUTTON,
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
+						gtk_toggle_tool_button_activatable_interface_init))
 
 static void
 gtk_toggle_tool_button_class_init (GtkToggleToolButtonClass *klass)
@@ -292,6 +305,49 @@ button_toggled (GtkWidget           *wid
     }
 }
 
+static void 
+gtk_toggle_tool_button_activatable_interface_init (GtkActivatableIface  *iface)
+{
+  parent_activatable_iface = g_type_interface_peek_parent (iface);
+  iface->update = gtk_toggle_tool_button_activatable_update;
+  iface->reset = gtk_toggle_tool_button_activatable_reset;
+}
+
+static void
+gtk_toggle_tool_button_activatable_update (GtkActivatable  *activatable,
+					   GtkAction       *action,
+					   const gchar     *property_name)
+{
+  GtkToggleToolButton *button;
+
+  parent_activatable_iface->update (activatable, action, property_name);
+
+  button = GTK_TOGGLE_TOOL_BUTTON (activatable);
+
+  if (strcmp (property_name, "active") == 0)
+    {
+      gtk_action_block_activate (action);
+      gtk_toggle_tool_button_set_active (button, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
+      gtk_action_unblock_activate (action);
+    }
+}
+
+static void
+gtk_toggle_tool_button_activatable_reset (GtkActivatable  *activatable,
+					  GtkAction       *action)
+{
+  GtkToggleToolButton *button;
+
+  parent_activatable_iface->reset (activatable, action);
+
+  button = GTK_TOGGLE_TOOL_BUTTON (activatable);
+
+  gtk_action_block_activate (action);
+  gtk_toggle_tool_button_set_active (button, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
+  gtk_action_unblock_activate (action);
+}
+
+
 /**
  * gtk_toggle_tool_button_new:
  * 
Index: gtk/gtk.h
===================================================================
--- gtk/gtk.h	(revision 22083)
+++ gtk/gtk.h	(working copy)
@@ -37,6 +37,7 @@
 #include <gtk/gtkaccessible.h>
 #include <gtk/gtkaction.h>
 #include <gtk/gtkactiongroup.h>
+#include <gtk/gtkactivatable.h>
 #include <gtk/gtkadjustment.h>
 #include <gtk/gtkalignment.h>
 #include <gtk/gtkarrow.h>
Index: gtk/gtk.symbols
===================================================================
--- gtk/gtk.symbols	(revision 22083)
+++ gtk/gtk.symbols	(working copy)
@@ -144,33 +144,64 @@ gtk_accessible_get_type G_GNUC_CONST
 #if IN_HEADER(__GTK_ACTION_H__)
 #if IN_FILE(__GTK_ACTION_C__)
 gtk_action_activate
+gtk_action_block_activate
+#ifndef GTK_DISABLE_DEPRECATED
 gtk_action_block_activate_from
+#endif
 gtk_action_connect_accelerator
+#ifndef GTK_DISABLE_DEPRECATED
 gtk_action_connect_proxy
+#endif
 gtk_action_create_icon
 gtk_action_create_menu_item
 gtk_action_create_tool_item
 gtk_action_create_menu
 gtk_action_disconnect_accelerator
+#ifndef GTK_DISABLE_DEPRECATED
 gtk_action_disconnect_proxy
+#endif
 gtk_action_get_accel_closure
 gtk_action_get_accel_path
+gtk_action_get_gicon
+gtk_action_get_group
+gtk_action_get_label
 gtk_action_get_name
 gtk_action_get_proxies
+#ifndef GTK_DISABLE_DEPRECATED
 gtk_widget_get_action
+#endif
+gtk_action_get_icon_name
+gtk_action_get_is_important
 gtk_action_get_sensitive
+gtk_action_get_short_label
+gtk_action_get_stock_id
+gtk_action_get_tooltip
 gtk_action_get_type G_GNUC_CONST
 gtk_action_get_visible
+gtk_action_get_visible_horizontal
+gtk_action_get_visible_vertical
 gtk_action_is_sensitive
 gtk_action_is_visible
 gtk_action_new
 gtk_action_set_accel_group
 gtk_action_set_accel_path
+gtk_action_set_gicon
+gtk_action_set_icon_name
+gtk_action_set_is_important
+gtk_action_set_label
 gtk_action_set_sensitive
+gtk_action_set_short_label
+gtk_action_set_stock_id
+gtk_action_set_tooltip
 gtk_action_set_visible
+gtk_action_set_visible_horizontal
+gtk_action_set_visible_vertical
+gtk_action_unblock_activate
+#ifndef GTK_DISABLE_DEPRECATED
 gtk_action_unblock_activate_from
 #endif
 #endif
+#endif
 
 #if IN_HEADER(__GTK_ACTION_GROUP_H__)
 #if IN_FILE(__GTK_ACTION_GROUP_C__)
@@ -198,6 +229,18 @@ gtk_action_group_translate_string
 #endif
 #endif
 
+#if IN_HEADER(__GTK_ACTIVATABLE_H__)
+#if IN_FILE(__GTK_ACTIVATABLE_C__)
+gtk_activatable_do_set_related_action
+gtk_activatable_get_related_action
+gtk_activatable_get_type G_GNUC_CONST
+gtk_activatable_get_use_action_appearance
+gtk_activatable_set_related_action
+gtk_activatable_set_use_action_appearance
+gtk_activatable_update
+#endif
+#endif
+
 #if IN_HEADER(__GTK_ADJUSTMENT_H__)
 #if IN_FILE(__GTK_ADJUSTMENT_C__)
 gtk_adjustment_changed
Index: gtk/gtktoolbutton.c
===================================================================
--- gtk/gtktoolbutton.c	(revision 22083)
+++ gtk/gtktoolbutton.c	(working copy)
@@ -32,6 +32,7 @@
 #include "gtkvbox.h"
 #include "gtkintl.h"
 #include "gtktoolbar.h"
+#include "gtkactivatable.h"
 #include "gtkprivate.h"
 #include "gtkalias.h"
 
@@ -77,11 +78,14 @@ static void gtk_tool_button_style_set   
 					    GtkStyle           *prev_style);
 
 static void gtk_tool_button_construct_contents (GtkToolItem *tool_item);
-      
-static GObjectClass *parent_class = NULL;
-static guint         toolbutton_signals[LAST_SIGNAL] = { 0 };
 
-#define GTK_TOOL_BUTTON_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_TOOL_BUTTON, GtkToolButtonPrivate))
+static void gtk_tool_button_activatable_interface_init (GtkActivatableIface  *iface);
+static void gtk_tool_button_activatable_update         (GtkActivatable       *activatable,
+							GtkAction            *action,
+							const gchar          *property_name);
+static void gtk_tool_button_activatable_reset          (GtkActivatable       *activatable,
+							GtkAction            *action);
+
 
 struct _GtkToolButtonPrivate
 {
@@ -97,19 +101,37 @@ struct _GtkToolButtonPrivate
   guint contents_invalid : 1;
 };
 
+static GObjectClass        *parent_class = NULL;
+static GtkActivatableIface *parent_activatable_iface;
+static guint                toolbutton_signals[LAST_SIGNAL] = { 0 };
+
+#define GTK_TOOL_BUTTON_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_TOOL_BUTTON, GtkToolButtonPrivate))
+
 GType
 gtk_tool_button_get_type (void)
 {
   static GType type = 0;
-
+  
   if (!type)
-    type = g_type_register_static_simple (GTK_TYPE_TOOL_ITEM,
-					  I_("GtkToolButton"),
-					  sizeof (GtkToolButtonClass),
-					  (GClassInitFunc) gtk_tool_button_class_init,
-					  sizeof (GtkToolButton),
-					  (GInstanceInitFunc) gtk_tool_button_init,
-					  0);
+    {
+      static const GInterfaceInfo activatable_info =
+      {
+        (GInterfaceInitFunc) gtk_tool_button_activatable_interface_init,
+        (GInterfaceFinalizeFunc) NULL,
+        NULL
+      };
+
+      type = g_type_register_static_simple (GTK_TYPE_TOOL_ITEM,
+					    I_("GtkToolButton"),
+					    sizeof (GtkToolButtonClass),
+					    (GClassInitFunc) gtk_tool_button_class_init,
+					    sizeof (GtkToolButton),
+					    (GInstanceInitFunc) gtk_tool_button_init,
+					    0);
+
+      g_type_add_interface_static (type, GTK_TYPE_ACTIVATABLE,
+                                   &activatable_info);
+    }
   return type;
 }
 
@@ -666,6 +688,13 @@ static void
 button_clicked (GtkWidget     *widget,
 		GtkToolButton *button)
 {
+  GtkAction *action;
+
+  action = gtk_activatable_get_related_action (GTK_ACTIVATABLE (button));
+  
+  if (action)
+    gtk_action_activate (action);
+
   g_signal_emit_by_name (button, "clicked");
 }
 
@@ -698,6 +727,120 @@ gtk_tool_button_style_set (GtkWidget *wi
   gtk_tool_button_update_icon_spacing (GTK_TOOL_BUTTON (widget));
 }
 
+static void 
+gtk_tool_button_activatable_interface_init (GtkActivatableIface  *iface)
+{
+  parent_activatable_iface = g_type_interface_peek_parent (iface);
+  iface->update = gtk_tool_button_activatable_update;
+  iface->reset = gtk_tool_button_activatable_reset;
+}
+
+static void
+gtk_tool_button_activatable_update (GtkActivatable       *activatable,
+				    GtkAction            *action,
+				    const gchar          *property_name)
+{
+  GtkToolButton *button;
+  GtkWidget *image;
+
+  parent_activatable_iface->update (activatable, action, property_name);
+
+  if (!gtk_activatable_get_use_action_appearance (activatable))
+    return;
+
+  button = GTK_TOOL_BUTTON (activatable);
+  
+  if (strcmp (property_name, "short-label") == 0)
+    {
+      if (!gtk_action_get_stock_id (action) &&
+	  !gtk_action_get_icon_name (action))
+	{
+	  gtk_tool_button_set_use_underline (button, TRUE);
+	  gtk_tool_button_set_label (button, gtk_action_get_short_label (action));
+	}
+    }
+  else if (strcmp (property_name, "stock-id") == 0)
+    {
+      if (gtk_action_get_stock_id (action))
+	{	
+	  gtk_tool_button_set_label (button, NULL);
+	  gtk_tool_button_set_icon_name (button, NULL);
+	}
+      gtk_tool_button_set_stock_id (button, gtk_action_get_stock_id (action));
+    }
+  else if (strcmp (property_name, "gicon") == 0)
+    {
+      const gchar *stock_id = gtk_action_get_stock_id (action);
+      GIcon *icon = gtk_action_get_gicon (action);
+      GtkIconSize icon_size = GTK_ICON_SIZE_BUTTON;
+
+      if ((stock_id && gtk_icon_factory_lookup_default (stock_id)) || !icon)
+	image = NULL;
+      else 
+	{   
+	  image = gtk_tool_button_get_icon_widget (button);
+	  icon_size = gtk_tool_item_get_icon_size (GTK_TOOL_ITEM (button));
+
+	  if (!image)
+	    image = gtk_image_new ();
+	}
+
+      gtk_tool_button_set_icon_widget (button, image);
+      gtk_image_set_from_gicon (GTK_IMAGE (image), icon, icon_size);
+
+    }
+  else if (strcmp (property_name, "icon-name") == 0)
+    {
+      if (gtk_action_get_icon_name (action))
+	{	
+	  gtk_tool_button_set_label (button, NULL);
+	  gtk_tool_button_set_stock_id (button, NULL);
+	}
+      gtk_tool_button_set_icon_name (button, gtk_action_get_icon_name (action));
+    }
+}
+
+static void
+gtk_tool_button_activatable_reset (GtkActivatable       *activatable,
+				    GtkAction            *action)
+{
+  GtkToolButton *button;
+  GIcon         *icon;
+
+  parent_activatable_iface->reset (activatable, action);
+
+  if (!gtk_activatable_get_use_action_appearance (activatable))
+    return;
+
+  button = GTK_TOOL_BUTTON (activatable);
+  
+  gtk_tool_button_set_label (button, NULL);
+  gtk_tool_button_set_stock_id (button, NULL);
+  gtk_tool_button_set_icon_name (button, NULL);
+  gtk_tool_button_set_use_underline (button, TRUE);
+  
+  if (gtk_action_get_stock_id (action))
+    gtk_tool_button_set_stock_id (button, gtk_action_get_stock_id (action));
+  else if ((icon = gtk_action_get_gicon (action)) != NULL)
+    {
+      GtkIconSize icon_size = gtk_tool_item_get_icon_size (GTK_TOOL_ITEM (button));
+      GtkWidget  *image = gtk_tool_button_get_icon_widget (button);
+      
+      if (!image)
+	{
+	  image = gtk_image_new ();
+	  gtk_widget_show (image);
+	  gtk_tool_button_set_icon_widget (button, image);
+	}
+
+      gtk_image_set_from_gicon (GTK_IMAGE (image), icon, icon_size);
+    }
+  else if (gtk_action_get_icon_name (action))
+    gtk_tool_button_set_icon_name (button, gtk_action_get_icon_name (action));
+  else
+    gtk_tool_button_set_label (button, gtk_action_get_short_label (action));
+}
+
 /**
  * gtk_tool_button_new_from_stock:
  * @stock_id: the name of the stock item 
Index: gtk/gtkbutton.c
===================================================================
--- gtk/gtkbutton.c	(revision 22083)
+++ gtk/gtkbutton.c	(working copy)
@@ -36,6 +36,7 @@
 #include "gtkvbox.h"
 #include "gtkstock.h"
 #include "gtkiconfactory.h"
+#include "gtkactivatable.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
 #include "gtkalias.h"
@@ -69,7 +70,11 @@ enum {
   PROP_FOCUS_ON_CLICK,
   PROP_XALIGN,
   PROP_YALIGN,
-  PROP_IMAGE_POSITION
+  PROP_IMAGE_POSITION,
+
+  /* activatable properties */
+  PROP_ACTIVATABLE_RELATED_ACTION,
+  PROP_ACTIVATABLE_USE_ACTION_APPEARANCE
 };
 
 #define GTK_BUTTON_GET_PRIVATE(o)       (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_BUTTON, GtkButtonPrivate))
@@ -80,14 +85,17 @@ struct _GtkButtonPrivate
   gfloat          xalign;
   gfloat          yalign;
   GtkWidget      *image;
-  guint           align_set      : 1;
-  guint           image_is_stock : 1;
-  guint           has_grab       : 1;
+  guint           align_set             : 1;
+  guint           image_is_stock        : 1;
+  guint           has_grab              : 1;
+  guint           use_action_appearance : 1;
   guint32         grab_time;
   GtkPositionType image_position;
+  GtkAction      *action;
 };
 
 static void gtk_button_destroy        (GtkObject          *object);
+static void gtk_button_dispose        (GObject            *object);
 static void gtk_button_set_property   (GObject            *object,
                                        guint               prop_id,
                                        const GValue       *value,
@@ -124,6 +132,7 @@ static gint gtk_button_leave_notify   (G
 				       GdkEventCrossing   *event);
 static void gtk_real_button_pressed   (GtkButton          *button);
 static void gtk_real_button_released  (GtkButton          *button);
+static void gtk_real_button_clicked   (GtkButton          *button);
 static void gtk_real_button_activate  (GtkButton          *button);
 static void gtk_button_update_state   (GtkButton          *button);
 static void gtk_button_add            (GtkContainer       *container,
@@ -142,9 +151,22 @@ static void gtk_button_grab_notify     (
 					gboolean               was_grabbed);
 
 
+static void gtk_button_activatable_interface_init (GtkActivatableIface  *iface);
+static void gtk_button_activatable_update         (GtkActivatable       *activatable,
+						   GtkAction            *action,
+						   const gchar          *property_name);
+static void gtk_button_activatable_reset          (GtkActivatable       *activatable,
+						   GtkAction            *action);
+static void gtk_button_set_related_action         (GtkButton            *button, 
+						   GtkAction            *action);
+static void gtk_button_set_use_action_appearance  (GtkButton            *button, 
+						   gboolean              use_appearance);
+
 static guint button_signals[LAST_SIGNAL] = { 0 };
 
-G_DEFINE_TYPE (GtkButton, gtk_button, GTK_TYPE_BIN)
+G_DEFINE_TYPE_WITH_CODE (GtkButton, gtk_button, GTK_TYPE_BIN,
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
+						gtk_button_activatable_interface_init))
 
 static void
 gtk_button_class_init (GtkButtonClass *klass)
@@ -159,7 +181,8 @@ gtk_button_class_init (GtkButtonClass *k
   widget_class = (GtkWidgetClass*) klass;
   container_class = (GtkContainerClass*) klass;
   
-  gobject_class->constructor = gtk_button_constructor;
+  gobject_class->constructor  = gtk_button_constructor;
+  gobject_class->dispose      = gtk_button_dispose;
   gobject_class->set_property = gtk_button_set_property;
   gobject_class->get_property = gtk_button_get_property;
 
@@ -188,7 +211,7 @@ gtk_button_class_init (GtkButtonClass *k
 
   klass->pressed = gtk_real_button_pressed;
   klass->released = gtk_real_button_released;
-  klass->clicked = NULL;
+  klass->clicked = gtk_real_button_clicked;
   klass->enter = gtk_button_update_state;
   klass->leave = gtk_button_update_state;
   klass->activate = gtk_real_button_activate;
@@ -303,6 +326,9 @@ gtk_button_class_init (GtkButtonClass *k
                                                       GTK_POS_LEFT,
                                                       GTK_PARAM_READWRITE));
 
+  g_object_class_override_property (gobject_class, PROP_ACTIVATABLE_RELATED_ACTION, "related-action");
+  g_object_class_override_property (gobject_class, PROP_ACTIVATABLE_USE_ACTION_APPEARANCE, "use-action-appearance");
+
   /**
    * GtkButton::pressed:
    * @button: the object that received the signal
@@ -521,6 +547,7 @@ gtk_button_init (GtkButton *button)
   priv->align_set = 0;
   priv->image_is_stock = TRUE;
   priv->image_position = GTK_POS_LEFT;
+  priv->use_action_appearance = TRUE;
 }
 
 static void
@@ -600,6 +627,20 @@ gtk_button_add (GtkContainer *container,
   GTK_CONTAINER_CLASS (gtk_button_parent_class)->add (container, widget);
 }
 
+static void 
+gtk_button_dispose (GObject *object)
+{
+  GtkButton *button = GTK_BUTTON (object);
+  GtkButtonPrivate *priv = GTK_BUTTON_GET_PRIVATE (button);
+
+  if (priv->action)
+    {
+      gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (button), NULL);
+      priv->action = NULL;
+    }
+  G_OBJECT_CLASS (gtk_button_parent_class)->dispose (object);
+}
+
 static void
 gtk_button_set_property (GObject         *object,
                          guint            prop_id,
@@ -638,6 +679,12 @@ gtk_button_set_property (GObject        
     case PROP_IMAGE_POSITION:
       gtk_button_set_image_position (button, g_value_get_enum (value));
       break;
+    case PROP_ACTIVATABLE_RELATED_ACTION:
+      gtk_button_set_related_action (button, g_value_get_object (value));
+      break;
+    case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE:
+      gtk_button_set_use_action_appearance (button, g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -682,12 +729,168 @@ gtk_button_get_property (GObject        
     case PROP_IMAGE_POSITION:
       g_value_set_enum (value, priv->image_position);
       break;
+    case PROP_ACTIVATABLE_RELATED_ACTION:
+      g_value_set_object (value, priv->action);
+      break;
+    case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE:
+      g_value_set_boolean (value, priv->use_action_appearance);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
     }
 }
 
+static void 
+gtk_button_activatable_interface_init (GtkActivatableIface  *iface)
+{
+  iface->update = gtk_button_activatable_update;
+  iface->reset = gtk_button_activatable_reset;
+}
+
+static void
+activatable_update_stock_id (GtkButton *button,
+			     GtkAction *action)
+{
+  if (!gtk_button_get_use_stock (button))
+    return;
+
+  gtk_button_set_label (button, gtk_action_get_stock_id (action));
+}
+
+static void
+activatable_update_short_label (GtkButton *button,
+				GtkAction *action)
+{
+  GtkWidget *image;
+
+  if (gtk_button_get_use_stock (button))
+    return;
+
+  image = gtk_button_get_image (button);
+
+  /* Dont touch custom child... */
+  if (GTK_IS_IMAGE (image) ||
+      GTK_BIN (button)->child == NULL || 
+      GTK_IS_LABEL (GTK_BIN (button)->child))
+    {
+      gtk_button_set_label (button, gtk_action_get_short_label (action));
+      gtk_button_set_use_underline (button, TRUE);
+    }
+}
+
+static void
+activatable_update_icon_name (GtkButton *button,
+			      GtkAction *action)
+{
+  GtkWidget *image;
+	      
+  if (gtk_button_get_use_stock (button))
+    return;
+
+  image = gtk_button_get_image (button);
+
+  if (GTK_IS_IMAGE (image) &&
+      (gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY ||
+       gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_ICON_NAME))
+    gtk_image_set_from_icon_name (GTK_IMAGE (image),
+				  gtk_action_get_icon_name (action), GTK_ICON_SIZE_MENU);
+}
+
+static void
+activatable_update_gicon (GtkButton *button,
+			  GtkAction *action)
+{
+  GtkWidget *image = gtk_button_get_image (button);
+  GIcon *icon = gtk_action_get_gicon (action);
+  
+  if (GTK_IS_IMAGE (image) &&
+      (gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY ||
+       gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_GICON))
+    gtk_image_set_from_gicon (GTK_IMAGE (image), icon, GTK_ICON_SIZE_BUTTON);
+}
+
+static void 
+gtk_button_activatable_update (GtkActivatable       *activatable,
+			       GtkAction            *action,
+			       const gchar          *property_name)
+{
+  GtkButtonPrivate *priv = GTK_BUTTON_GET_PRIVATE (activatable);
+
+  if (strcmp (property_name, "visible") == 0)
+    {
+      if (gtk_action_is_visible (action))
+	gtk_widget_show (GTK_WIDGET (activatable));
+      else
+	gtk_widget_hide (GTK_WIDGET (activatable));
+    }
+  else if (strcmp (property_name, "sensitive") == 0)
+    gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
+
+  if (!priv->use_action_appearance)
+    return;
+
+  if (strcmp (property_name, "stock-id") == 0)
+    activatable_update_stock_id (GTK_BUTTON (activatable), action);
+  else if (strcmp (property_name, "gicon") == 0)
+    activatable_update_gicon (GTK_BUTTON (activatable), action);
+  else if (strcmp (property_name, "short-label") == 0)
+    activatable_update_short_label (GTK_BUTTON (activatable), action);
+  else if (strcmp (property_name, "icon-name") == 0)
+    activatable_update_icon_name (GTK_BUTTON (activatable), action);
+}
+
+static void 
+gtk_button_activatable_reset (GtkActivatable       *activatable,
+			       GtkAction            *action)
+{
+  GtkButtonPrivate *priv = GTK_BUTTON_GET_PRIVATE (activatable);
+
+  if (gtk_action_is_visible (action))
+    gtk_widget_show (GTK_WIDGET (activatable));
+  else
+    gtk_widget_hide (GTK_WIDGET (activatable));
+  
+  gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
+  
+  if (priv->use_action_appearance)
+    {
+      activatable_update_stock_id (GTK_BUTTON (activatable), action);
+      activatable_update_short_label (GTK_BUTTON (activatable), action);
+      activatable_update_gicon (GTK_BUTTON (activatable), action);
+      activatable_update_icon_name (GTK_BUTTON (activatable), action);
+    }
+}
+
+static void
+gtk_button_set_related_action (GtkButton   *button, 
+			       GtkAction   *action)
+{
+  GtkButtonPrivate *priv = GTK_BUTTON_GET_PRIVATE (button);
+
+  if (priv->action == action)
+    return;
+
+  gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (button), action);
+
+  priv->action = action;
+}
+
+static void
+gtk_button_set_use_action_appearance (GtkButton   *button, 
+				      gboolean     use_appearance)
+{
+  GtkButtonPrivate *priv = GTK_BUTTON_GET_PRIVATE (button);
+
+  if (priv->use_action_appearance != use_appearance)
+    {
+      priv->use_action_appearance = use_appearance;
+      
+      if (priv->action && use_appearance)
+	gtk_activatable_reset (GTK_ACTIVATABLE (button), priv->action);
+    }
+}
+
 GtkWidget*
 gtk_button_new (void)
 {
@@ -1494,6 +1697,15 @@ gtk_real_button_released (GtkButton *but
     }
 }
 
+static void 
+gtk_real_button_clicked (GtkButton  *button)
+{
+  GtkButtonPrivate *priv = GTK_BUTTON_GET_PRIVATE (button);
+
+  if (priv->action)
+    gtk_action_activate (priv->action);
+}
+
 static gboolean
 button_activate_timeout (gpointer data)
 {
Index: gtk/gtkaction.c
===================================================================
--- gtk/gtkaction.c	(revision 22083)
+++ gtk/gtkaction.c	(working copy)
@@ -47,6 +47,7 @@
 #include "gtktoolbar.h"
 #include "gtkprivate.h"
 #include "gtkbuildable.h"
+#include "gtkactivatable.h"
 #include "gtkalias.h"
 
 
@@ -71,6 +72,8 @@ struct _GtkActionPrivate 
   guint is_important       : 1;
   guint hide_if_empty      : 1;
   guint visible_overflown  : 1;
+  guint recursion_guard    : 1;
+  guint activate_blocked   : 1;
 
   /* accelerator */
   guint          accel_count;
@@ -120,10 +123,6 @@ G_DEFINE_TYPE_WITH_CODE (GtkAction, gtk_
 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
 						gtk_action_buildable_init))
 
-
-static GQuark      quark_gtk_action_proxy  = 0;
-static const gchar gtk_action_proxy_key[] = "gtk-action";
-
 static void gtk_action_finalize     (GObject *object);
 static void gtk_action_set_property (GObject         *object,
 				     guint            prop_id,
@@ -135,26 +134,6 @@ static void gtk_action_get_property (GOb
 				     GParamSpec      *pspec);
 static void gtk_action_set_action_group (GtkAction	*action,
 					 GtkActionGroup *action_group);
-static void gtk_action_set_is_important (GtkAction	*action,
-					 gboolean        is_important);
-static void gtk_action_set_label        (GtkAction	*action,
-					 const gchar    *label);
-static void gtk_action_set_short_label  (GtkAction	*action,
-					 const gchar    *label);
-static void gtk_action_set_visible_horizontal (GtkAction *action,
-					       gboolean   visible_horizontal);
-static void gtk_action_set_visible_vertical   (GtkAction *action,
-					       gboolean   visible_vertical);
-static void gtk_action_set_tooltip      (GtkAction	*action,
-					 const gchar    *tooltip);
-static void gtk_action_set_stock_id     (GtkAction	*action,
-					 const gchar    *stock_id);
-static void gtk_action_set_icon_name     (GtkAction	*action,
-					 const gchar    *icon_name);
-static void gtk_action_sync_tooltip     (GtkAction      *action,
-					 GtkWidget      *proxy);
-static void gtk_action_set_gicon        (GtkAction *action,
-                                         GIcon     *icon);
 
 static GtkWidget *create_menu_item    (GtkAction *action);
 static GtkWidget *create_tool_item    (GtkAction *action);
@@ -162,7 +141,7 @@ static void       connect_proxy       (G
 				       GtkWidget *proxy);
 static void       disconnect_proxy    (GtkAction *action,
 				       GtkWidget *proxy);
-
+ 
 static void       closure_accel_activate (GClosure     *closure,
 					  GValue       *return_value,
 					  guint         n_param_values,
@@ -178,8 +157,6 @@ gtk_action_class_init (GtkActionClass *k
 {
   GObjectClass *gobject_class;
 
-  quark_gtk_action_proxy = g_quark_from_static_string (gtk_action_proxy_key);
-
   gobject_class = G_OBJECT_CLASS (klass);
 
   gobject_class->finalize     = gtk_action_finalize;
@@ -188,14 +165,13 @@ gtk_action_class_init (GtkActionClass *k
 
   klass->activate = NULL;
 
-  klass->create_menu_item = create_menu_item;
-  klass->create_tool_item = create_tool_item;
-  klass->create_menu = NULL;
-  klass->connect_proxy = connect_proxy;
-  klass->disconnect_proxy = disconnect_proxy;
-
-  klass->menu_item_type = GTK_TYPE_IMAGE_MENU_ITEM;
+  klass->create_menu_item  = create_menu_item;
+  klass->create_tool_item  = create_tool_item;
+  klass->create_menu       = NULL;
+  klass->menu_item_type    = GTK_TYPE_IMAGE_MENU_ITEM;
   klass->toolbar_item_type = GTK_TYPE_TOOL_BUTTON;
+  klass->connect_proxy    = connect_proxy;
+  klass->disconnect_proxy = disconnect_proxy;
 
   g_object_class_install_property (gobject_class,
 				   PROP_NAME,
@@ -212,6 +188,9 @@ gtk_action_class_init (GtkActionClass *k
    * The label used for menu items and buttons that activate
    * this action. If the label is %NULL, GTK+ uses the stock 
    * label specified via the stock-id property.
+   *
+   * This is an appearance property and thus only applies if 
+   * #GtkActivatable:use-action-appearance is %TRUE.
    */
   g_object_class_install_property (gobject_class,
 				   PROP_LABEL,
@@ -221,6 +200,15 @@ gtk_action_class_init (GtkActionClass *k
 							   "that activate this action."),
 							NULL,
 							GTK_PARAM_READWRITE));
+
+  /** 
+   * GtkAction:short-label:
+   *
+   * A shorter label that may be used on toolbar buttons.
+   *
+   * This is an appearance property and thus only applies if 
+   * #GtkActivatable:use-action-appearance is %TRUE.
+   */
   g_object_class_install_property (gobject_class,
 				   PROP_SHORT_LABEL,
 				   g_param_spec_string ("short-label",
@@ -235,6 +224,15 @@ gtk_action_class_init (GtkActionClass *k
 							P_("A tooltip for this action."),
 							NULL,
 							GTK_PARAM_READWRITE));
+
+  /** 
+   * GtkAction:stock-id:
+   *
+   * The stock icon displayed in widgets representing this action.
+   *
+   * This is an appearance property and thus only applies if 
+   * #GtkActivatable:use-action-appearance is %TRUE.
+   */
   g_object_class_install_property (gobject_class,
 				   PROP_STOCK_ID,
 				   g_param_spec_string ("stock-id",
@@ -251,6 +249,9 @@ gtk_action_class_init (GtkActionClass *k
    * Note that the stock icon is preferred, if the #GtkAction:stock-id 
    * property holds the id of an existing stock icon.
    *
+   * This is an appearance property and thus only applies if 
+   * #GtkActivatable:use-action-appearance is %TRUE.
+   *
    * Since: 2.16
    */
   g_object_class_install_property (gobject_class,
@@ -269,6 +270,9 @@ gtk_action_class_init (GtkActionClass *k
    * property holds the id of an existing stock icon, and the #GIcon is
    * preferred if the #GtkAction:gicon property is set. 
    *
+   * This is an appearance property and thus only applies if 
+   * #GtkActivatable:use-action-appearance is %TRUE.
+   *
    * Since: 2.10
    */
   g_object_class_install_property (gobject_class,
@@ -385,6 +389,7 @@ gtk_action_init (GtkAction *action)
   action->private_data->visible_overflown  = TRUE;
   action->private_data->is_important = FALSE;
   action->private_data->hide_if_empty = TRUE;
+  action->private_data->activate_blocked = FALSE;
 
   action->private_data->sensitive = TRUE;
   action->private_data->visible = TRUE;
@@ -638,12 +643,30 @@ static void
 remove_proxy (GtkAction *action,
 	      GtkWidget *proxy)
 {
-  if (GTK_IS_MENU_ITEM (proxy))
-    gtk_action_disconnect_accelerator (action);
-  
   action->private_data->proxies = g_slist_remove (action->private_data->proxies, proxy);
 }
 
+static void
+connect_proxy (GtkAction *action,
+	       GtkWidget *proxy)
+{
+  action->private_data->proxies = g_slist_prepend (action->private_data->proxies, proxy);
+
+  if (action->private_data->action_group)
+    _gtk_action_group_emit_connect_proxy (action->private_data->action_group, action, proxy);
+
+}
+
+static void
+disconnect_proxy (GtkAction *action,
+		  GtkWidget *proxy)
+{
+  remove_proxy (action, proxy);
+
+  if (action->private_data->action_group)
+    _gtk_action_group_emit_disconnect_proxy (action->private_data->action_group, action, proxy);
+}
+
 /**
  * _gtk_action_sync_menu_visible:
  * @action: a #GtkAction, or %NULL to determine the action from @proxy
@@ -674,7 +697,7 @@ _gtk_action_sync_menu_visible (GtkAction
   g_return_if_fail (action == NULL || GTK_IS_ACTION (action));
 
   if (action == NULL)
-    action = g_object_get_qdata (G_OBJECT (proxy), quark_gtk_action_proxy);
+    action = gtk_activatable_get_related_action (GTK_ACTIVATABLE (proxy));
 
   if (action)
     {
@@ -689,257 +712,6 @@ _gtk_action_sync_menu_visible (GtkAction
     gtk_widget_hide (proxy);
 }
 
-gboolean _gtk_menu_is_empty (GtkWidget *menu);
-
-static gboolean
-gtk_action_create_menu_proxy (GtkToolItem *tool_item, 
-			      GtkAction   *action)
-{
-  GtkWidget *menu_item;
-  
-  if (action->private_data->visible_overflown)
-    {
-      menu_item = gtk_action_create_menu_item (action);
-
-      g_object_ref_sink (menu_item);
-      
-      gtk_tool_item_set_proxy_menu_item (tool_item, 
-					 "gtk-action-menu-item", menu_item);
-      g_object_unref (menu_item);
-    }
-  else
-    gtk_tool_item_set_proxy_menu_item (tool_item, 
-				       "gtk-action-menu-item", NULL);
-
-  return TRUE;
-}
-
-static void
-connect_proxy (GtkAction     *action, 
-	       GtkWidget     *proxy)
-{
-  g_object_ref (action);
-  g_object_set_qdata_full (G_OBJECT (proxy), quark_gtk_action_proxy, action,
-			   g_object_unref);
-
-  /* add this widget to the list of proxies */
-  action->private_data->proxies = g_slist_prepend (action->private_data->proxies, proxy);
-  g_object_weak_ref (G_OBJECT (proxy), (GWeakNotify)remove_proxy, action);
-  
-  gtk_widget_set_sensitive (proxy, gtk_action_is_sensitive (action));
-  if (gtk_action_is_visible (action))
-    gtk_widget_show (proxy);
-  else
-    gtk_widget_hide (proxy);
-  gtk_widget_set_no_show_all (proxy, TRUE);
-
-  if (GTK_IS_MENU_ITEM (proxy))
-    {
-      GtkWidget *label;
-      /* menu item specific synchronisers ... */
-      
-      if (action->private_data->accel_quark)
- 	{
-	  gtk_action_connect_accelerator (action);
- 	  gtk_menu_item_set_accel_path (GTK_MENU_ITEM (proxy),
- 					g_quark_to_string (action->private_data->accel_quark));
- 	}
-      
-      label = GTK_BIN (proxy)->child;
-
-      /* make sure label is a label */
-      if (label && !GTK_IS_LABEL (label))
-	{
-	  gtk_container_remove (GTK_CONTAINER (proxy), label);
-	  label = NULL;
-	}
-
-      if (!label)
-	label = g_object_new (GTK_TYPE_ACCEL_LABEL,
-			      "use-underline", TRUE,
-			      "xalign", 0.0,
-			      "visible", TRUE,
-			      "parent", proxy,
-			      NULL);
-      
-      if (GTK_IS_ACCEL_LABEL (label) && action->private_data->accel_quark)
-	g_object_set (label,
-		      "accel-closure", action->private_data->accel_closure,
-		      NULL);
-
-      gtk_label_set_label (GTK_LABEL (label), action->private_data->label);
-
-      if (GTK_IS_IMAGE_MENU_ITEM (proxy))
-	{
-	  GtkWidget *image;
-
-	  image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
-	  if (image && !GTK_IS_IMAGE (image))
-	    {
-	      gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy), NULL);
-	      image = NULL;
-	    }
-	  if (!image)
-	    {
-	      image = gtk_image_new ();
-	      gtk_widget_show (image);
-	      gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy),
-					     image);
-	    }
-	  
-	  if (action->private_data->stock_id &&
-	      gtk_icon_factory_lookup_default (action->private_data->stock_id))
-	    gtk_image_set_from_stock (GTK_IMAGE (image),
-				      action->private_data->stock_id, GTK_ICON_SIZE_MENU);
-	  else if (action->private_data->gicon)
-	    gtk_image_set_from_gicon (GTK_IMAGE (image),
-	                              action->private_data->gicon, GTK_ICON_SIZE_MENU);
-	  else if (action->private_data->icon_name)
-	    gtk_image_set_from_icon_name (GTK_IMAGE (image),
-					  action->private_data->icon_name, GTK_ICON_SIZE_MENU);
-          else
-            gtk_image_clear (GTK_IMAGE (image));
-	}
-      
-      if (gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy)) == NULL)
-	g_signal_connect_object (proxy, "activate",
-				 G_CALLBACK (gtk_action_activate), action,
-				 G_CONNECT_SWAPPED);
-
-    }
-  else if (GTK_IS_TOOL_ITEM (proxy))
-    {
-      /* toolbar button specific synchronisers ... */
-      if (GTK_IS_TOOL_BUTTON (proxy))
-	{
-          GtkWidget *image;
-          GtkIconSize icon_size;
-
-	  g_object_set (proxy,
-		        "visible-horizontal", action->private_data->visible_horizontal,
-		        "visible-vertical", action->private_data->visible_vertical,
-		        "is-important", action->private_data->is_important,
-			"label", action->private_data->short_label,
-			"use-underline", TRUE,
-			"stock-id", action->private_data->stock_id,
-			"icon-name", action->private_data->icon_name,
-			NULL);
-           
-          if (action->private_data->stock_id &&
-	      gtk_icon_factory_lookup_default (action->private_data->stock_id))
-            {
-              /* use the stock icon */
-              gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (proxy), NULL);
-            }
-          else if (action->private_data->gicon)
-            {
-              icon_size = gtk_tool_item_get_icon_size (GTK_TOOL_ITEM (proxy));
-              image = gtk_tool_button_get_icon_widget (GTK_TOOL_BUTTON (proxy));
-              if (!image)
-                {
-                  image = gtk_image_new ();
-	          gtk_widget_show (image);
-                  gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (proxy), 
-                                                   image);
-                }
-
-              gtk_image_set_from_gicon (GTK_IMAGE (image),
-                                        action->private_data->gicon, 
-                                        icon_size);
-            }
-
-	  g_signal_connect_object (proxy, "clicked",
-				   G_CALLBACK (gtk_action_activate), action,
-				   G_CONNECT_SWAPPED);
-        }
-      else 
-        {
-           g_object_set (proxy,
-	 	         "visible-horizontal", action->private_data->visible_horizontal,
-		         "visible-vertical", action->private_data->visible_vertical,
-		         "is-important", action->private_data->is_important,
-		         NULL);
-       }
-
-      gtk_action_sync_tooltip (action, proxy);
-
-      g_signal_connect_object (proxy, "create-menu-proxy",
-			       G_CALLBACK (gtk_action_create_menu_proxy),
-			       action, 0);
-
-      gtk_tool_item_rebuild_menu (GTK_TOOL_ITEM (proxy));
-    }
-  else if (GTK_IS_BUTTON (proxy))
-    {
-      /* button specific synchronisers ... */
-      if (gtk_button_get_use_stock (GTK_BUTTON (proxy)))
-	{
-	  /* synchronise stock-id */
-	  g_object_set (proxy,
-			"label", action->private_data->stock_id,
-			NULL);
-	}
-      else 
-	{
-	  GtkWidget *image;
-
-	  image = gtk_button_get_image (GTK_BUTTON (proxy));
-
-	  if (GTK_IS_IMAGE (image) ||
-	      GTK_BIN (proxy)->child == NULL || 
-	      GTK_IS_LABEL (GTK_BIN (proxy)->child))
-	    {
-	      /* synchronise the label */
-	      g_object_set (proxy,
-			    "label", action->private_data->short_label,
-			    "use-underline", TRUE,
-			    NULL);
-	    }
-
-	  if (GTK_IS_IMAGE (image) &&
-              (gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY ||
-	       gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_GICON))
-            gtk_image_set_from_gicon (GTK_IMAGE (image),
-                                      action->private_data->gicon, GTK_ICON_SIZE_MENU);
-          else if (GTK_IS_IMAGE (image) &&
-                   (gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY ||
-                    gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_ICON_NAME))
-            gtk_image_set_from_icon_name (GTK_IMAGE (image),
-                                          action->private_data->icon_name, GTK_ICON_SIZE_MENU);
-	}
-      /* we leave the button alone if there is a custom child */
-      g_signal_connect_object (proxy, "clicked",
-			       G_CALLBACK (gtk_action_activate), action,
-			       G_CONNECT_SWAPPED);
-    }
-
-  if (action->private_data->action_group)
-    _gtk_action_group_emit_connect_proxy (action->private_data->action_group, action, proxy);
-}
-
-static void
-disconnect_proxy (GtkAction *action, 
-		  GtkWidget *proxy)
-{
-  g_object_set_qdata (G_OBJECT (proxy), quark_gtk_action_proxy, NULL);
-
-  g_object_weak_unref (G_OBJECT (proxy), (GWeakNotify)remove_proxy, action);
-  remove_proxy (action, proxy);
-
-  /* disconnect the activate handler */
-  g_signal_handlers_disconnect_by_func (proxy,
-					G_CALLBACK (gtk_action_activate),
-					action);
-
-  /* toolbar button specific synchronisers ... */
-  g_signal_handlers_disconnect_by_func (proxy,
-					G_CALLBACK (gtk_action_create_menu_proxy),
-					action);
-
-  if (action->private_data->action_group)
-    _gtk_action_group_emit_disconnect_proxy (action->private_data->action_group, action, proxy);
-}
-
 void
 _gtk_action_emit_activate (GtkAction *action)
 {
@@ -977,11 +749,43 @@ gtk_action_activate (GtkAction *action)
 {
   g_return_if_fail (GTK_IS_ACTION (action));
   
-  if (gtk_action_is_sensitive (action))
+  if (action->private_data->activate_blocked == FALSE &&
+      gtk_action_is_sensitive (action))
     _gtk_action_emit_activate (action);
 }
 
 /**
+ * gtk_action_block_activate:
+ *
+ * Disable activation signals from the action 
+ *
+ * This is needed when updating the state of your proxy
+ * #GtkActivatable widget could result in calling gtk_action_activate(),
+ * this is a convenience function to avoid recursing in those
+ * cases (updating toggle state for instance).
+ */
+void
+gtk_action_block_activate (GtkAction *action)
+{
+  g_return_if_fail (GTK_IS_ACTION (action));
+
+  action->private_data->activate_blocked = TRUE;
+}
+
+/**
+ * gtk_action_unblock_activate:
+ *
+ * Reenable activation signals from the action 
+ */
+void
+gtk_action_unblock_activate (GtkAction *action)
+{
+  g_return_if_fail (GTK_IS_ACTION (action));
+
+  action->private_data->activate_blocked = FALSE;
+}
+
+/**
  * gtk_action_create_icon:
  * @action: the action object
  * @icon_size: the size of the icon that should be created.
@@ -1028,7 +832,8 @@ gtk_action_create_menu_item (GtkAction *
 
   menu_item = GTK_ACTION_GET_CLASS (action)->create_menu_item (action);
 
-  GTK_ACTION_GET_CLASS (action)->connect_proxy (action, menu_item);
+  gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (menu_item), TRUE);
+  gtk_activatable_set_related_action (GTK_ACTIVATABLE (menu_item), action);
 
   return menu_item;
 }
@@ -1052,11 +857,51 @@ gtk_action_create_tool_item (GtkAction *
 
   button = GTK_ACTION_GET_CLASS (action)->create_tool_item (action);
 
-  GTK_ACTION_GET_CLASS (action)->connect_proxy (action, button);
+  gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (button), TRUE);
+  gtk_activatable_set_related_action (GTK_ACTIVATABLE (button), action);
 
   return button;
 }
 
+void
+_gtk_action_add_to_proxy_list (GtkAction     *action,
+			       GtkWidget     *proxy)
+{
+  g_return_if_fail (GTK_IS_ACTION (action));
+  g_return_if_fail (GTK_IS_WIDGET (proxy));
+ 
+  GTK_ACTION_GET_CLASS (action)->connect_proxy (action, proxy);
+}
+
+void
+_gtk_action_remove_from_proxy_list (GtkAction     *action,
+				    GtkWidget     *proxy)
+{
+  g_return_if_fail (GTK_IS_ACTION (action));
+  g_return_if_fail (GTK_IS_WIDGET (proxy));
+
+  GTK_ACTION_GET_CLASS (action)->disconnect_proxy (action, proxy);
+}
+
+
+/**
+ * gtk_action_get_group:
+ * @action: the action object
+ *
+ * Gets the #GtkActionGroup that this @action is in.
+ *
+ * Returns: the #GtkActionGroup
+ *
+ * Since: 2.16
+ */
+GtkActionGroup *
+gtk_action_get_group (GtkAction *action)
+{
+  g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
+
+  return action->private_data->action_group;
+}
+
 /**
  * gtk_action_connect_proxy:
  * @action: the action object
@@ -1071,22 +916,20 @@ gtk_action_create_tool_item (GtkAction *
  * first.
  *
  * Since: 2.4
+ *
+ * Deprecated 2.16: Use gtk_activatable_set_related_action() instead.
  */
 void
 gtk_action_connect_proxy (GtkAction *action,
 			  GtkWidget *proxy)
 {
-  GtkAction *prev_action;
-
   g_return_if_fail (GTK_IS_ACTION (action));
   g_return_if_fail (GTK_IS_WIDGET (proxy));
+  g_return_if_fail (GTK_IS_ACTIVATABLE (proxy));
 
-  prev_action = g_object_get_qdata (G_OBJECT (proxy), quark_gtk_action_proxy);
-
-  if (prev_action)
-    GTK_ACTION_GET_CLASS (action)->disconnect_proxy (prev_action, proxy);
+  gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (proxy), TRUE);
 
-  GTK_ACTION_GET_CLASS (action)->connect_proxy (action, proxy);
+  gtk_activatable_set_related_action (GTK_ACTIVATABLE (proxy), action);
 }
 
 /**
@@ -1098,6 +941,8 @@ gtk_action_connect_proxy (GtkAction *act
  * Does <emphasis>not</emphasis> destroy the widget, however.
  *
  * Since: 2.4
+ *
+ * Deprecated 2.16: Use gtk_activatable_set_related_action() instead.
  */
 void
 gtk_action_disconnect_proxy (GtkAction *action,
@@ -1106,9 +951,7 @@ gtk_action_disconnect_proxy (GtkAction *
   g_return_if_fail (GTK_IS_ACTION (action));
   g_return_if_fail (GTK_IS_WIDGET (proxy));
 
-  g_return_if_fail (g_object_get_qdata (G_OBJECT (proxy), quark_gtk_action_proxy) == action);
-
-  GTK_ACTION_GET_CLASS (action)->disconnect_proxy (action, proxy);
+  gtk_activatable_set_related_action (GTK_ACTIVATABLE (proxy), NULL);
 }
 
 /**
@@ -1143,16 +986,18 @@ gtk_action_get_proxies (GtkAction *actio
  *  %NULL, if it is not attached to an action.
  *
  * Since: 2.10
+ *
+ * Deprecated 2.16: Use gtk_activatable_get_related_action() instead.
  */
 GtkAction*
 gtk_widget_get_action (GtkWidget *widget)
 {
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+  g_return_val_if_fail (GTK_IS_ACTIVATABLE (widget), NULL);
   
-  return g_object_get_qdata (G_OBJECT (widget), quark_gtk_action_proxy);
+  return gtk_activatable_get_related_action (GTK_ACTIVATABLE (widget));
 }
 
-
 /**
  * gtk_action_get_name:
  * @action: the action object
@@ -1215,22 +1060,6 @@ gtk_action_get_sensitive (GtkAction *act
   return action->private_data->sensitive;
 }
 
-void
-_gtk_action_sync_sensitive (GtkAction *action)
-{
-  GSList *p;
-  GtkWidget *proxy;
-  gboolean sensitive;
-
-  sensitive = gtk_action_is_sensitive (action);
-
-  for (p = action->private_data->proxies; p; p = p->next)
-    {
-      proxy = (GtkWidget *)p->data;
-      gtk_widget_set_sensitive (proxy, sensitive);
-    }      
-}
-
 /**
  * gtk_action_set_sensitive:
  * @action: the action object
@@ -1255,8 +1084,6 @@ gtk_action_set_sensitive (GtkAction *act
     {
       action->private_data->sensitive = sensitive;
 
-      _gtk_action_sync_sensitive (action);
-
       g_object_notify (G_OBJECT (action), "sensitive");
     }
 }
@@ -1304,36 +1131,6 @@ gtk_action_get_visible (GtkAction *actio
   return action->private_data->visible;
 }
 
-void
-_gtk_action_sync_visible (GtkAction *action)
-{
-  GSList *p;
-  GtkWidget *proxy;
-  GtkWidget *menu;
-  gboolean visible;
-
-  visible = gtk_action_is_visible (action);
-    
-  for (p = action->private_data->proxies; p; p = p->next)
-    {
-      proxy = (GtkWidget *)p->data;
-
-      if (GTK_IS_MENU_ITEM (proxy))
-	{
-	  menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy));
-	  
-	  _gtk_action_sync_menu_visible (action, proxy, _gtk_menu_is_empty (menu));
-	}
-      else
-	{
-	  if (visible)
-	    gtk_widget_show (proxy);
-	  else
-	    gtk_widget_hide (proxy);
-	}
-    } 
-}
-
 /**
  * gtk_action_set_visible:
  * @action: the action object
@@ -1358,46 +1155,74 @@ gtk_action_set_visible (GtkAction *actio
     {
       action->private_data->visible = visible;
 
-      _gtk_action_sync_visible (action);
-
       g_object_notify (G_OBJECT (action), "visible");
     }
 }
 
-static void 
+
+/**
+ * gtk_action_set_is_important:
+ * @action: the action object
+ * @is_important: %TRUE to make the action important
+ * 
+ * Sets whether the action is important, this attribute is used
+ * primarily by toolbar items.
+ *
+ * Since: 2.16
+ **/
+void 
 gtk_action_set_is_important (GtkAction *action,
 			     gboolean   is_important)
 {
-  GSList *p;
-  GtkWidget *proxy;
+  g_return_if_fail (GTK_IS_ACTION (action));
 
   is_important = is_important != FALSE;
   
   if (action->private_data->is_important != is_important)
     {
       action->private_data->is_important = is_important;
-
-      for (p = action->private_data->proxies; p; p = p->next)
-	{
-	  proxy = (GtkWidget *)p->data;
-
-	  if (GTK_IS_TOOL_ITEM (proxy))
-	    gtk_tool_item_set_is_important (GTK_TOOL_ITEM (proxy),
-					    is_important);
-	}
       
       g_object_notify (G_OBJECT (action), "is-important");
     }  
 }
 
-static void 
+
+/**
+ * gtk_action_get_is_important:
+ * @action: a #GtkAction
+ *
+ * Checks whether @action is important or not
+ * 
+ * Returns: whether @action is important
+ *
+ * Since: 2.16
+ */
+gboolean 
+gtk_action_get_is_important (GtkAction *action)
+{
+  g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
+
+  return action->private_data->is_important;
+}
+
+
+/**
+ * gtk_action_set_label:
+ * @action: a #GtkAction
+ * @label: the label text to set
+ *
+ * Sets the label of @action.
+ *
+ * Since: 2.16
+ */
+void 
 gtk_action_set_label (GtkAction	  *action,
 		      const gchar *label)
 {
-  GSList *p;
-  GtkWidget *proxy, *child;
   gchar *tmp;
   
+  g_return_if_fail (GTK_IS_ACTION (action));
+
   tmp = action->private_data->label;
   action->private_data->label = g_strdup (label);
   g_free (tmp);
@@ -1410,21 +1235,7 @@ gtk_action_set_label (GtkAction	  *actio
       if (gtk_stock_lookup (action->private_data->stock_id, &stock_item))
 	action->private_data->label = g_strdup (stock_item.label);
     }
-  
-  for (p = action->private_data->proxies; p; p = p->next)
-    {
-      proxy = (GtkWidget *)p->data;
-      
-      if (GTK_IS_MENU_ITEM (proxy))
-	{
-	  child = GTK_BIN (proxy)->child;
-	  
-	  if (GTK_IS_LABEL (child))
-	    gtk_label_set_label (GTK_LABEL (child), 
-				 action->private_data->label);
-	}
-    }
-  
+
   g_object_notify (G_OBJECT (action), "label");
   
   /* if short_label is unset, set short_label=label */
@@ -1435,12 +1246,38 @@ gtk_action_set_label (GtkAction	  *actio
     }
 }
 
-static void 
-gtk_action_set_short_label (GtkAction	*action,
+/**
+ * gtk_action_get_label:
+ * @action: a #GtkAction
+ *
+ * Gets the label text of @action.
+ *
+ * Returns: the label text
+ *
+ * Since: 2.16
+ */
+G_CONST_RETURN gchar * 
+gtk_action_get_label (GtkAction *action)
+{
+  g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
+
+  return action->private_data->label;
+}
+
+
+/**
+ * gtk_action_set_short_label:
+ * @action: a #GtkAction
+ * @label: the label text to set
+ *
+ * Sets a shorter label on @action.
+ *
+ * Since: 2.16
+ */
+void 
+gtk_action_set_short_label (GtkAction   *action,
 			    const gchar *label)
 {
-  GSList *p;
-  GtkWidget *proxy, *child;
   gchar *tmp;
 
   tmp = action->private_data->short_label;
@@ -1451,153 +1288,177 @@ gtk_action_set_short_label (GtkAction	*a
   if (!action->private_data->short_label_set)
     action->private_data->short_label = g_strdup (action->private_data->label);
 
-  for (p = action->private_data->proxies; p; p = p->next)
-    {
-      proxy = (GtkWidget *)p->data;
+  g_object_notify (G_OBJECT (action), "short-label");
+}
 
-      if (GTK_IS_TOOL_BUTTON (proxy))
-	gtk_tool_button_set_label (GTK_TOOL_BUTTON (proxy),
-				   action->private_data->short_label);
-      else if (GTK_IS_BUTTON (proxy) &&
-	       !gtk_button_get_use_stock (GTK_BUTTON (proxy)))
-	{
-	  GtkWidget *image;
-
-	  child = GTK_BIN (proxy)->child;
-
-	  image = gtk_button_get_image (GTK_BUTTON (proxy));
-
-	  if (GTK_IS_IMAGE (image) ||
-	      child == NULL || GTK_IS_LABEL (child))
-	    gtk_button_set_label (GTK_BUTTON (proxy),
-				  action->private_data->short_label);
-	}
-    }
+/**
+ * gtk_action_get_short_label:
+ * @action: a #GtkAction
+ * @label: the label text to set
+ *
+ * Sets a shorter label on @action.
+ *
+ * Since: 2.16
+ */
+G_CONST_RETURN gchar * 
+gtk_action_get_short_label (GtkAction *action)
+{
+  g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
 
-  g_object_notify (G_OBJECT (action), "short-label");
+  return action->private_data->short_label;
 }
 
-static void 
+
+/**
+ * gtk_action_set_visible_horizontal:
+ * @action: a #GtkAction
+ * @visible_horizontal: whether the action is visible horizontally
+ *
+ * Sets whether @action is visible when horizontal
+ *
+ * Since: 2.16
+ */
+void 
 gtk_action_set_visible_horizontal (GtkAction *action,
 				   gboolean   visible_horizontal)
 {
-  GSList *p;
-  GtkWidget *proxy;
+  g_return_if_fail (GTK_IS_ACTION (action));
 
   visible_horizontal = visible_horizontal != FALSE;
   
   if (action->private_data->visible_horizontal != visible_horizontal)
     {
       action->private_data->visible_horizontal = visible_horizontal;
-
-      for (p = action->private_data->proxies; p; p = p->next)
-	{
-	  proxy = (GtkWidget *)p->data;
-
-	  if (GTK_IS_TOOL_ITEM (proxy))
-	    gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (proxy),
-						  visible_horizontal);
-	}
       
       g_object_notify (G_OBJECT (action), "visible-horizontal");
     }  
 }
 
-static void 
+/**
+ * gtk_action_get_visible_horizontal:
+ * @action: a #GtkAction
+ *
+ * Checks whether @action is visible when horizontal
+ * 
+ * Returns: whether @action is visible when horizontal
+ *
+ * Since: 2.16
+ */
+gboolean 
+gtk_action_get_visible_horizontal (GtkAction *action)
+{
+  g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
+
+  return action->private_data->visible_horizontal;
+}
+
+/**
+ * gtk_action_set_visible_vertical:
+ * @action: a #GtkAction
+ * @visible_vertical: whether the action is visible vertically
+ *
+ * Sets whether @action is visible when vertical 
+ *
+ * Since: 2.16
+ */
+void 
 gtk_action_set_visible_vertical (GtkAction *action,
 				 gboolean   visible_vertical)
 {
-  GSList *p;
-  GtkWidget *proxy;
+  g_return_if_fail (GTK_IS_ACTION (action));
 
   visible_vertical = visible_vertical != FALSE;
   
   if (action->private_data->visible_vertical != visible_vertical)
     {
       action->private_data->visible_vertical = visible_vertical;
-
-      for (p = action->private_data->proxies; p; p = p->next)
-	{
-	  proxy = (GtkWidget *)p->data;
-
-	  if (GTK_IS_TOOL_ITEM (proxy))
-	    gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (proxy),
-						visible_vertical);
-	}
       
       g_object_notify (G_OBJECT (action), "visible-vertical");
     }  
 }
 
-static void 
-gtk_action_sync_tooltip (GtkAction *action,
-			 GtkWidget *proxy)
+/**
+ * gtk_action_get_visible_vertical:
+ * @action: a #GtkAction
+ *
+ * Checks whether @action is visible when horizontal
+ * 
+ * Returns: whether @action is visible when horizontal
+ *
+ * Since: 2.16
+ */
+gboolean 
+gtk_action_get_visible_vertical (GtkAction *action)
 {
-  gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (proxy),
-				  action->private_data->tooltip);
+  g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
+
+  return action->private_data->visible_vertical;
 }
 
-static void 
+/**
+ * gtk_action_set_tooltip:
+ * @action: a #GtkAction
+ * @tooltip: the tooltip text
+ *
+ * Sets the tooltip text on @action
+ *
+ * Since: 2.16
+ */
+void 
 gtk_action_set_tooltip (GtkAction   *action,
 			const gchar *tooltip)
 {
-  GSList *p;
-  GtkWidget *proxy;
   gchar *tmp;
 
+  g_return_if_fail (GTK_IS_ACTION (action));
+
   tmp = action->private_data->tooltip;
   action->private_data->tooltip = g_strdup (tooltip);
   g_free (tmp);
 
-  for (p = action->private_data->proxies; p; p = p->next)
-    {
-      proxy = (GtkWidget *)p->data;
+  g_object_notify (G_OBJECT (action), "tooltip");
+}
 
-      if (GTK_IS_TOOL_ITEM (proxy))
-        gtk_action_sync_tooltip (action, proxy);
-    }
 
-  g_object_notify (G_OBJECT (action), "tooltip");
+/**
+ * gtk_action_get_tooltip:
+ * @action: a #GtkAction
+ *
+ * Gets the tooltip text of @action.
+ *
+ * Returns: the tooltip text
+ *
+ * Since: 2.16
+ */
+G_CONST_RETURN gchar * 
+gtk_action_get_tooltip (GtkAction *action)
+{
+  g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
+
+  return action->private_data->tooltip;
 }
 
-static void 
+/**
+ * gtk_action_set_stock_id:
+ * @action: a #GtkAction
+ * @tooltip: the tooltip text
+ *
+ * Sets the stock id on @action
+ *
+ * Since: 2.16
+ */
+void 
 gtk_action_set_stock_id (GtkAction   *action,
 			 const gchar *stock_id)
 {
-  GSList *p;
-  GtkWidget *proxy, *image;
   gchar *tmp;
-  
+
+  g_return_if_fail (GTK_IS_ACTION (action));
+
   tmp = action->private_data->stock_id;
   action->private_data->stock_id = g_strdup (stock_id);
   g_free (tmp);
 
-  for (p = action->private_data->proxies; p; p = p->next)
-    {
-      proxy = (GtkWidget *)p->data;
-      
-      if (GTK_IS_IMAGE_MENU_ITEM (proxy))
-	{
-	  image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
-	  
-	  if (GTK_IS_IMAGE (image))
-	    gtk_image_set_from_stock (GTK_IMAGE (image),
-				      action->private_data->stock_id, GTK_ICON_SIZE_MENU);
-	} 
-      else if (GTK_IS_TOOL_BUTTON (proxy))
-	{
-          gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (proxy), NULL);
-	  gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (proxy),
-					action->private_data->stock_id);
-	}
-      else if (GTK_IS_BUTTON (proxy) &&
-	       gtk_button_get_use_stock (GTK_BUTTON (proxy)))
-	{
-	  gtk_button_set_label (GTK_BUTTON (proxy),
-				action->private_data->stock_id);
-	}
-    }
-
   g_object_notify (G_OBJECT (action), "stock-id");
   
   /* update label and short_label if appropriate */
@@ -1615,62 +1476,79 @@ gtk_action_set_stock_id (GtkAction   *ac
     }
 }
 
-static void 
+/**
+ * gtk_action_get_stock_id:
+ * @action: a #GtkAction
+ *
+ * Gets the stock id of @action.
+ *
+ * Returns: the stock id
+ *
+ * Since: 2.16
+ */
+G_CONST_RETURN gchar * 
+gtk_action_get_stock_id (GtkAction *action)
+{
+  g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
+
+  return action->private_data->stock_id;
+}
+
+/**
+ * gtk_action_set_icon_name:
+ * @action: a #GtkAction
+ * @tooltip: the icon name to set
+ *
+ * Sets the icon name on @action
+ *
+ * Since: 2.16
+ */
+void 
 gtk_action_set_icon_name (GtkAction   *action,
 			  const gchar *icon_name)
 {
-  GSList *p;
-  GtkWidget *proxy, *image;
   gchar *tmp;
-  
+
+  g_return_if_fail (GTK_IS_ACTION (action));
+
   tmp = action->private_data->icon_name;
   action->private_data->icon_name = g_strdup (icon_name);
   g_free (tmp);
 
-  for (p = action->private_data->proxies; p; p = p->next)
-    {
-      proxy = (GtkWidget *)p->data;
-      
-      if (GTK_IS_IMAGE_MENU_ITEM (proxy))
-	{
-	  image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
-	  
-	  if (GTK_IS_IMAGE (image) &&
-	      (gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY ||
-	       gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_ICON_NAME))
-	    gtk_image_set_from_icon_name (GTK_IMAGE (image),
-					  action->private_data->icon_name, GTK_ICON_SIZE_MENU);
-	} 
-      else if (GTK_IS_TOOL_BUTTON (proxy))
-	{
-	  gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (proxy),
-					 action->private_data->icon_name);
-	}
-      else if (GTK_IS_BUTTON (proxy) &&
-	       !gtk_button_get_use_stock (GTK_BUTTON (proxy)))
-	{
-	  image = gtk_button_get_image (GTK_BUTTON (proxy));
-	  
-	  if (GTK_IS_IMAGE (image) &&
-	      (gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY ||
-	       gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_ICON_NAME))
-	    gtk_image_set_from_icon_name (GTK_IMAGE (image),
-					  action->private_data->icon_name, GTK_ICON_SIZE_MENU);
-	}
-    }
-  
   g_object_notify (G_OBJECT (action), "icon-name");
 }
 
-static void
+/**
+ * gtk_action_get_icon_name:
+ * @action: a #GtkAction
+ *
+ * Gets the icon name of @action.
+ *
+ * Returns: the icon name
+ *
+ * Since: 2.16
+ */
+G_CONST_RETURN gchar * 
+gtk_action_get_icon_name (GtkAction *action)
+{
+  g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
+
+  return action->private_data->icon_name;
+}
+
+/**
+ * gtk_action_set_gicon:
+ * @action: a #GtkAction
+ * @icon: the #GIcon to set
+ *
+ * Sets the icon of @action.
+ *
+ * Since: 2.16
+ */
+void
 gtk_action_set_gicon (GtkAction *action,
                       GIcon     *icon)
 {
-  GSList *p;
-  GtkWidget *proxy, *image;
-  GtkIconSize icon_size;
-  gboolean has_stock_icon;
-  
   if (action->private_data->gicon)
     g_object_unref (action->private_data->gicon);
 
@@ -1679,52 +1557,28 @@ gtk_action_set_gicon (GtkAction *action,
   if (action->private_data->gicon)
     g_object_ref (action->private_data->gicon);
 
-  if (action->private_data->stock_id &&
-      gtk_icon_factory_lookup_default (action->private_data->stock_id))
-    has_stock_icon = TRUE;
-  else
-    has_stock_icon = FALSE;
-
-  for (p = action->private_data->proxies; p; p = p->next)
-    {
-      proxy = (GtkWidget *)p->data;
-  
-      if (GTK_IS_IMAGE_MENU_ITEM (proxy) && !has_stock_icon)
-        {
-          image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
-          gtk_image_set_from_gicon (GTK_IMAGE (image), icon, GTK_ICON_SIZE_MENU);
-        } 
-      else if (GTK_IS_TOOL_BUTTON (proxy))
-        {
-          if (has_stock_icon || !icon)
-            image = NULL;
-          else 
-            {   
-              image = gtk_tool_button_get_icon_widget (GTK_TOOL_BUTTON (proxy));
-              icon_size = gtk_tool_item_get_icon_size (GTK_TOOL_ITEM (proxy));
-
-              if (!image)
-                image = gtk_image_new ();
-            }
-
-          gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (proxy), image);
-          gtk_image_set_from_gicon (GTK_IMAGE (image), icon, icon_size);
-        }
-      else if (GTK_IS_BUTTON (proxy) && 
-               !gtk_button_get_use_stock (GTK_BUTTON (proxy)))
-        {
-          image = gtk_button_get_image (GTK_BUTTON (proxy));
-	  if (GTK_IS_IMAGE (image) &&
-              (gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY ||
-	       gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_GICON))
-            gtk_image_set_from_gicon (GTK_IMAGE (image), icon, GTK_ICON_SIZE_BUTTON);
-        }
-    }
-  
   g_object_notify (G_OBJECT (action), "gicon");
 }
 
 /**
+ * gtk_action_get_gicon:
+ * @action: a #GtkAction
+ *
+ * Gets the gicon of @action.
+ *
+ * Returns: The action's #GIcon if one is set.
+ *
+ * Since: 2.16
+ */
+GIcon *
+gtk_action_get_gicon (GtkAction *action)
+{
+  g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
+
+  return action->private_data->gicon;
+}
+
+/**
  * gtk_action_block_activate_from:
  * @action: the action object
  * @proxy: a proxy widget
@@ -1736,6 +1590,9 @@ gtk_action_set_gicon (GtkAction *action,
  * This function is intended for use by action implementations.
  * 
  * Since: 2.4
+ *
+ * Deprecated 2.16: activatables are now responsible for activating the
+ * action directly so this doesnt apply anymore.
  */
 void
 gtk_action_block_activate_from (GtkAction *action, 
@@ -1759,6 +1616,9 @@ gtk_action_block_activate_from (GtkActio
  * This function is intended for use by action implementations.
  * 
  * Since: 2.4
+ *
+ * Deprecated 2.16: activatables are now responsible for activating the
+ * action directly so this doesnt apply anymore.
  */
 void
 gtk_action_unblock_activate_from (GtkAction *action, 
Index: gtk/gtkaction.h
===================================================================
--- gtk/gtkaction.h	(revision 22083)
+++ gtk/gtkaction.h	(working copy)
@@ -46,8 +46,8 @@ G_BEGIN_DECLS
 #define GTK_IS_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ACTION))
 #define GTK_ACTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_ACTION, GtkActionClass))
 
-typedef struct _GtkAction      GtkAction;
-typedef struct _GtkActionClass GtkActionClass;
+typedef struct _GtkAction        GtkAction;
+typedef struct _GtkActionClass   GtkActionClass;
 typedef struct _GtkActionPrivate GtkActionPrivate;
 
 struct _GtkAction
@@ -105,22 +105,46 @@ GtkWidget *  gtk_action_create_icon     
 GtkWidget *  gtk_action_create_menu_item       (GtkAction     *action);
 GtkWidget *  gtk_action_create_tool_item       (GtkAction     *action);
 GtkWidget *  gtk_action_create_menu            (GtkAction     *action);
-void         gtk_action_connect_proxy          (GtkAction     *action,
-						GtkWidget     *proxy);
-void         gtk_action_disconnect_proxy       (GtkAction     *action,
-						GtkWidget     *proxy);
 GSList *     gtk_action_get_proxies            (GtkAction     *action);
-GtkAction *  gtk_widget_get_action             (GtkWidget     *widget);
 void         gtk_action_connect_accelerator    (GtkAction     *action);
 void         gtk_action_disconnect_accelerator (GtkAction     *action);
 G_CONST_RETURN gchar *gtk_action_get_accel_path (GtkAction     *action);
 GClosure    *gtk_action_get_accel_closure      (GtkAction     *action);
 
-/* protected ... for use by child actions */
-void         gtk_action_block_activate_from    (GtkAction     *action,
-						GtkWidget     *proxy);
-void         gtk_action_unblock_activate_from  (GtkAction     *action,
-						GtkWidget     *proxy);
+
+void                  gtk_action_set_label               (GtkAction      *action,
+							  const gchar    *label);
+G_CONST_RETURN gchar *gtk_action_get_label               (GtkAction      *action);
+void                  gtk_action_set_short_label         (GtkAction      *action,
+							  const gchar    *short_label);
+G_CONST_RETURN gchar *gtk_action_get_short_label         (GtkAction      *action);
+void                  gtk_action_set_tooltip             (GtkAction      *action,
+							  const gchar    *tooltip);
+G_CONST_RETURN gchar *gtk_action_get_tooltip             (GtkAction      *action);
+void                  gtk_action_set_stock_id            (GtkAction      *action,
+							  const gchar    *stock_id);
+G_CONST_RETURN gchar *gtk_action_get_stock_id            (GtkAction      *action);
+void                  gtk_action_set_gicon               (GtkAction      *action,
+							  GIcon          *icon);
+GIcon                *gtk_action_get_gicon               (GtkAction      *action);
+void                  gtk_action_set_icon_name           (GtkAction      *action,
+							  const gchar    *icon_name);
+G_CONST_RETURN gchar *gtk_action_get_icon_name           (GtkAction      *action);
+void                  gtk_action_set_visible_horizontal  (GtkAction      *action,
+							  gboolean        visible_horizontal);
+gboolean              gtk_action_get_visible_horizontal  (GtkAction      *action);
+void                  gtk_action_set_visible_vertical    (GtkAction      *action,
+							  gboolean        visible_vertical);
+gboolean              gtk_action_get_visible_vertical    (GtkAction      *action);
+void                  gtk_action_set_is_important        (GtkAction      *action,
+							  gboolean        is_important);
+gboolean              gtk_action_get_is_important        (GtkAction      *action);
+
+
+/* protected ... for use by child activatable proxies */
+void         gtk_action_block_activate         (GtkAction     *action);
+void         gtk_action_unblock_activate       (GtkAction     *action);
+GtkActionGroup *gtk_action_get_group           (GtkAction     *action);
 void         _gtk_action_emit_activate         (GtkAction     *action);
 
 /* protected ... for use by action groups */
@@ -128,11 +152,26 @@ void         gtk_action_set_accel_path  
 						const gchar   *accel_path);
 void         gtk_action_set_accel_group        (GtkAction     *action,
 						GtkAccelGroup *accel_group);
-void         _gtk_action_sync_sensitive        (GtkAction     *action);
-void         _gtk_action_sync_visible          (GtkAction     *action);
 void         _gtk_action_sync_menu_visible     (GtkAction     *action,
 						GtkWidget     *proxy,
 						gboolean       empty);
+void         _gtk_action_add_to_proxy_list     (GtkAction     *action,
+						GtkWidget     *proxy);
+void         _gtk_action_remove_from_proxy_list(GtkAction     *action,
+						GtkWidget     *proxy);
+
+#ifndef GTK_DISABLE_DEPRECATED
+GtkAction   *gtk_widget_get_action             (GtkWidget     *widget);
+void         gtk_action_connect_proxy          (GtkAction     *action,
+						GtkWidget     *proxy);
+void         gtk_action_disconnect_proxy       (GtkAction     *action,
+						GtkWidget     *proxy);
+void         gtk_action_block_activate_from    (GtkAction     *action,
+						GtkWidget     *proxy);
+void         gtk_action_unblock_activate_from  (GtkAction     *action,
+						GtkWidget     *proxy);
+#endif /* GTK_DISABLE_DEPRECATED */
+
 
 G_END_DECLS
 
Index: gtk/gtkrecentchoosermenu.c
===================================================================
--- gtk/gtkrecentchoosermenu.c	(revision 22083)
+++ gtk/gtkrecentchoosermenu.c	(working copy)
@@ -42,6 +42,7 @@
 #include "gtkimage.h"
 #include "gtklabel.h"
 #include "gtktooltip.h"
+#include "gtkactivatable.h"
 #include "gtktypebuiltins.h"
 #include "gtkprivate.h"
 #include "gtkalias.h"
@@ -86,10 +87,14 @@ struct _GtkRecentChooserMenuPrivate
 
 enum {
   PROP_0,
+  PROP_SHOW_NUMBERS,
 
-  PROP_SHOW_NUMBERS
+  /* activatable properties */
+  PROP_ACTIVATABLE_RELATED_ACTION,
+  PROP_ACTIVATABLE_USE_ACTION_APPEARANCE
 };
 
+
 #define FALLBACK_ICON_SIZE 	32
 #define FALLBACK_ITEM_LIMIT 	10
 #define DEFAULT_LABEL_WIDTH     30
@@ -155,11 +160,18 @@ static void     item_activate_cb   (GtkW
 static void     manager_changed_cb (GtkRecentManager *manager,
 				    gpointer          user_data);
 
+static void gtk_recent_chooser_activatable_iface_init (GtkActivatableIface  *iface);
+static void gtk_recent_chooser_activatable_update     (GtkActivatable       *activatable,
+						       GtkAction            *action,
+						       const gchar          *property_name);
+
 G_DEFINE_TYPE_WITH_CODE (GtkRecentChooserMenu,
 			 gtk_recent_chooser_menu,
 			 GTK_TYPE_MENU,
 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_RECENT_CHOOSER,
-				 		gtk_recent_chooser_iface_init))
+				 		gtk_recent_chooser_iface_init)
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
+				 		gtk_recent_chooser_activatable_iface_init))
 
 
 static void
@@ -179,6 +191,13 @@ gtk_recent_chooser_iface_init (GtkRecent
   iface->list_filters = gtk_recent_chooser_menu_list_filters;
 }
 
+static void 
+gtk_recent_chooser_activatable_iface_init (GtkActivatableIface  *iface)
+
+{  
+  iface->update = gtk_recent_chooser_activatable_update;
+}
+
 static void
 gtk_recent_chooser_menu_class_init (GtkRecentChooserMenuClass *klass)
 {
@@ -208,6 +227,10 @@ gtk_recent_chooser_menu_class_init (GtkR
 							 FALSE,
 							 GTK_PARAM_READWRITE));
   
+
+  g_object_class_override_property (gobject_class, PROP_ACTIVATABLE_RELATED_ACTION, "related-action");
+  g_object_class_override_property (gobject_class, PROP_ACTIVATABLE_USE_ACTION_APPEARANCE, "use-action-appearance");
+
   g_type_class_add_private (klass, sizeof (GtkRecentChooserMenuPrivate));
 }
 
@@ -376,6 +399,12 @@ gtk_recent_chooser_menu_set_property (GO
     case GTK_RECENT_CHOOSER_PROP_FILTER:
       gtk_recent_chooser_menu_set_current_filter (menu, g_value_get_object (value));
       break;
+    case PROP_ACTIVATABLE_RELATED_ACTION:
+      _gtk_recent_chooser_set_related_action (GTK_RECENT_CHOOSER (menu), g_value_get_object (value));
+      break;
+    case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE: 
+      _gtk_recent_chooser_set_use_action_appearance (GTK_RECENT_CHOOSER (menu), g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -423,6 +452,12 @@ gtk_recent_chooser_menu_get_property (GO
     case GTK_RECENT_CHOOSER_PROP_FILTER:
       g_value_set_object (value, priv->current_filter);
       break;
+    case PROP_ACTIVATABLE_RELATED_ACTION:
+      g_value_set_object (value, _gtk_recent_chooser_get_related_action (GTK_RECENT_CHOOSER (menu)));
+      break;
+    case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE: 
+      g_value_set_boolean (value, _gtk_recent_chooser_get_use_action_appearance (GTK_RECENT_CHOOSER (menu)));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1131,6 +1166,18 @@ gtk_recent_chooser_menu_set_show_tips (G
   gtk_container_foreach (GTK_CONTAINER (menu), foreach_set_shot_tips, menu);
 }
 
+static void 
+gtk_recent_chooser_activatable_update (GtkActivatable       *activatable,
+				       GtkAction            *action,
+				       const gchar          *property_name)
+{
+  if (property_name == NULL || strcmp (property_name, "sensitive") == 0)
+    gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
+
+  _gtk_recent_chooser_activatable_update (activatable, action, property_name);
+}
+
+
 /*
  * Public API
  */
Index: gtk/gtkradioaction.c
===================================================================
--- gtk/gtkradioaction.c	(revision 22083)
+++ gtk/gtkradioaction.c	(working copy)
@@ -324,6 +324,8 @@ gtk_radio_action_activate (GtkAction *ac
 	  if (tmp_action->private_data->active && (tmp_action != toggle_action)) 
 	    {
 	      toggle_action->private_data->active = !toggle_action->private_data->active;
+
+	      g_object_notify (G_OBJECT (action), "active");
 	      break;
 	    }
 	}
@@ -331,6 +333,7 @@ gtk_radio_action_activate (GtkAction *ac
   else
     {
       toggle_action->private_data->active = !toggle_action->private_data->active;
+      g_object_notify (G_OBJECT (action), "active");
 
       tmp_list = radio_action->private_data->group;
       while (tmp_list)
Index: gtk/gtkrecentchooser.c
===================================================================
--- gtk/gtkrecentchooser.c	(revision 22083)
+++ gtk/gtkrecentchooser.c	(working copy)
@@ -24,6 +24,8 @@
 #include "gtkrecentchooser.h"
 #include "gtkrecentchooserprivate.h"
 #include "gtkrecentmanager.h"
+#include "gtkrecentaction.h"
+#include "gtkactivatable.h"
 #include "gtkintl.h"
 #include "gtktypebuiltins.h"
 #include "gtkprivate.h"
@@ -39,7 +41,14 @@ enum
   LAST_SIGNAL
 };
 
-static void gtk_recent_chooser_class_init (gpointer g_iface);
+static void     gtk_recent_chooser_class_init         (gpointer          g_iface);
+static gboolean recent_chooser_has_show_numbers       (GtkRecentChooser *chooser);
+
+static GQuark      quark_gtk_related_action               = 0;
+static GQuark      quark_gtk_use_action_appearance        = 0;
+static const gchar gtk_related_action_key[]               = "gtk-related-action";
+static const gchar gtk_use_action_appearance_key[]        = "gtk-use-action-appearance";
+
 
 static guint chooser_signals[LAST_SIGNAL] = { 0, };
 
@@ -66,6 +75,9 @@ static void
 gtk_recent_chooser_class_init (gpointer g_iface)
 {
   GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
+
+  quark_gtk_related_action        = g_quark_from_static_string (gtk_related_action_key);
+  quark_gtk_use_action_appearance = g_quark_from_static_string (gtk_use_action_appearance_key);
   
   /**
    * GtkRecentChooser::selection-changed
@@ -575,6 +587,25 @@ gtk_recent_chooser_get_show_tips (GtkRec
   return show_tips;
 }
 
+static gboolean
+recent_chooser_has_show_numbers (GtkRecentChooser *chooser)
+{
+  GParamSpec *pspec;
+  
+  /* This is the result of a minor screw up: the "show-numbers" property
+   * was removed from the GtkRecentChooser interface, but the accessors
+   * remained in the interface API; now we need to check whether the
+   * implementation of the RecentChooser interface has a "show-numbers"
+   * boolean property installed before accessing it, and avoid an
+   * assertion failure using a more graceful warning.  This should really
+   * go away as soon as we can break API and remove these accessors.
+   */
+  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (chooser),
+		  			"show-numbers");
+
+  return (pspec && pspec->value_type == G_TYPE_BOOLEAN);
+}
+
 /**
  * gtk_recent_chooser_set_show_numbers:
  * @chooser: a #GtkRecentChooser
@@ -590,25 +621,13 @@ void
 gtk_recent_chooser_set_show_numbers (GtkRecentChooser *chooser,
 				     gboolean          show_numbers)
 {
-  GParamSpec *pspec;
-  
   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
 
-  /* This is the result of a minor screw up: the "show-numbers" property
-   * was removed from the GtkRecentChooser interface, but the accessors
-   * remained in the interface API; now we need to check whether the
-   * implementation of the RecentChooser interface has a "show-numbers"
-   * boolean property installed before accessing it, and avoid an
-   * assertion failure using a more graceful warning.  This should really
-   * go away as soon as we can break API and remove these accessors.
-   */
-  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (chooser),
-		  			"show-numbers");
-  if (!pspec || pspec->value_type != G_TYPE_BOOLEAN)
+  if (!recent_chooser_has_show_numbers (chooser))
     {
       g_warning ("Choosers of type `%s' do not support showing numbers",
 		 G_OBJECT_TYPE_NAME (chooser));
-
+      
       return;
     }
   
@@ -1074,5 +1093,105 @@ _gtk_recent_chooser_selection_changed (G
   g_signal_emit (chooser, chooser_signals[SELECTION_CHANGED], 0);
 }
 
+void
+_gtk_recent_chooser_activatable_update (GtkActivatable *activatable,
+					GtkAction      *action,
+					const gchar    *property_name)
+{
+  GtkRecentChooser *recent_chooser = GTK_RECENT_CHOOSER (activatable);
+  GtkRecentChooser *action_chooser = GTK_RECENT_CHOOSER (action);
+  GtkRecentAction  *recent_action  = GTK_RECENT_ACTION (action);
+
+  if (strcmp (property_name, "show-numbers") == 0 && recent_chooser_has_show_numbers (recent_chooser))
+      gtk_recent_chooser_set_show_numbers (recent_chooser, 
+					   gtk_recent_action_get_show_numbers (recent_action));
+  else if (strcmp (property_name, "show-private") == 0)
+    gtk_recent_chooser_set_show_private (recent_chooser, gtk_recent_chooser_get_show_private (action_chooser));
+  else if (strcmp (property_name, "show-not-found") == 0)
+    gtk_recent_chooser_set_show_not_found (recent_chooser, gtk_recent_chooser_get_show_not_found (action_chooser));
+  else if (strcmp (property_name, "show-tips") == 0)
+    gtk_recent_chooser_set_show_tips (recent_chooser, gtk_recent_chooser_get_show_tips (action_chooser));
+  else if (strcmp (property_name, "show-icons") == 0)
+    gtk_recent_chooser_set_show_icons (recent_chooser, gtk_recent_chooser_get_show_icons (action_chooser));
+  else if (strcmp (property_name, "limit") == 0)
+    gtk_recent_chooser_set_limit (recent_chooser, gtk_recent_chooser_get_limit (action_chooser));
+  else if (strcmp (property_name, "local-only") == 0)
+    gtk_recent_chooser_set_local_only (recent_chooser, gtk_recent_chooser_get_local_only (action_chooser));
+  else if (strcmp (property_name, "sort-type") == 0)
+    gtk_recent_chooser_set_sort_type (recent_chooser, gtk_recent_chooser_get_sort_type (action_chooser));
+  else if (strcmp (property_name, "filter") == 0)
+    gtk_recent_chooser_set_filter (recent_chooser, gtk_recent_chooser_get_filter (action_chooser));
+}
+
+void
+_gtk_recent_chooser_activatable_reset (GtkActivatable *activatable,
+				       GtkAction      *action)
+{
+  GtkRecentChooser *recent_chooser = GTK_RECENT_CHOOSER (activatable);
+  GtkRecentChooser *action_chooser = GTK_RECENT_CHOOSER (action);
+
+  if (recent_chooser_has_show_numbers (recent_chooser))
+    gtk_recent_chooser_set_show_numbers (recent_chooser, 
+					 gtk_recent_action_get_show_numbers (GTK_RECENT_ACTION (action)));
+  gtk_recent_chooser_set_show_private (recent_chooser, gtk_recent_chooser_get_show_private (action_chooser));
+  gtk_recent_chooser_set_show_not_found (recent_chooser, gtk_recent_chooser_get_show_not_found (action_chooser));
+  gtk_recent_chooser_set_show_tips (recent_chooser, gtk_recent_chooser_get_show_tips (action_chooser));
+  gtk_recent_chooser_set_show_icons (recent_chooser, gtk_recent_chooser_get_show_icons (action_chooser));
+  gtk_recent_chooser_set_limit (recent_chooser, gtk_recent_chooser_get_limit (action_chooser));
+  gtk_recent_chooser_set_local_only (recent_chooser, gtk_recent_chooser_get_local_only (action_chooser));
+  gtk_recent_chooser_set_sort_type (recent_chooser, gtk_recent_chooser_get_sort_type (action_chooser));
+  gtk_recent_chooser_set_filter (recent_chooser, gtk_recent_chooser_get_filter (action_chooser));
+}
+
+void
+_gtk_recent_chooser_set_related_action (GtkRecentChooser *recent_chooser, 
+					GtkAction        *action)
+{
+  GtkAction *prev_action;
+
+  prev_action = g_object_get_qdata (G_OBJECT (recent_chooser), quark_gtk_related_action);
+
+  if (prev_action == action)
+    return;
+
+  gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (recent_chooser), action);
+  g_object_set_qdata (G_OBJECT (recent_chooser), quark_gtk_related_action, action);
+}
+
+GtkAction *
+_gtk_recent_chooser_get_related_action (GtkRecentChooser *recent_chooser)
+{
+  return g_object_get_qdata (G_OBJECT (recent_chooser), quark_gtk_related_action);
+}
+
+/* The default for use-action-appearance is TRUE, so we try to set the
+ * qdata backwards for this case.
+ */
+void
+_gtk_recent_chooser_set_use_action_appearance (GtkRecentChooser *recent_chooser, 
+					       gboolean          use_appearance)
+{
+  GtkAction *action;
+  gboolean   use_action_appearance;
+
+  action                = g_object_get_qdata (G_OBJECT (recent_chooser), quark_gtk_related_action);
+  use_action_appearance = !GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (recent_chooser), quark_gtk_related_action));
+
+  if (use_action_appearance != use_appearance)
+    {
+
+      g_object_set_qdata (G_OBJECT (recent_chooser), quark_gtk_related_action, !GINT_TO_POINTER (use_appearance));
+
+      if (action && use_appearance)
+	gtk_activatable_reset (GTK_ACTIVATABLE (recent_chooser), action);
+    }
+}
+
+gboolean
+_gtk_recent_chooser_get_use_action_appearance (GtkRecentChooser *recent_chooser)
+{
+  return !GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (recent_chooser), quark_gtk_related_action));
+}
+
 #define __GTK_RECENT_CHOOSER_C__
 #include "gtkaliasdef.c"
Index: gtk/gtkactiongroup.c
===================================================================
--- gtk/gtkactiongroup.c	(revision 22083)
+++ gtk/gtkactiongroup.c	(working copy)
@@ -626,8 +626,8 @@ cb_set_action_sensitivity (const gchar *
 {
   /* Minor optimization, the action_groups state only affects actions 
    * that are themselves sensitive */
-  if (gtk_action_get_sensitive (action))
-    _gtk_action_sync_sensitive (action);
+  g_object_notify (G_OBJECT (action), "sensitive");
+
 }
 
 /**
@@ -691,8 +691,7 @@ cb_set_action_visiblity (const gchar *na
 {
   /* Minor optimization, the action_groups state only affects actions 
    * that are themselves visible */
-  if (gtk_action_get_visible (action))
-    _gtk_action_sync_visible (action);
+  g_object_notify (G_OBJECT (action), "visible");
 }
 
 /**
Index: gtk/gtkactiongroup.h
===================================================================
--- gtk/gtkactiongroup.h	(revision 22083)
+++ gtk/gtkactiongroup.h	(working copy)
@@ -47,7 +47,6 @@ G_BEGIN_DECLS
 #define GTK_IS_ACTION_GROUP_CLASS(vtable)  (G_TYPE_CHECK_CLASS_TYPE ((vtable), GTK_TYPE_ACTION_GROUP))
 #define GTK_ACTION_GROUP_GET_CLASS(inst)   (G_TYPE_INSTANCE_GET_CLASS ((inst), GTK_TYPE_ACTION_GROUP, GtkActionGroupClass))
 
-typedef struct _GtkActionGroup        GtkActionGroup;
 typedef struct _GtkActionGroupPrivate GtkActionGroupPrivate;
 typedef struct _GtkActionGroupClass   GtkActionGroupClass;
 typedef struct _GtkActionEntry        GtkActionEntry;
Index: gtk/Makefile.am
===================================================================
--- gtk/Makefile.am	(revision 22083)
+++ gtk/Makefile.am	(working copy)
@@ -148,6 +148,7 @@ gtk_public_h_sources =          \
 	gtkaccessible.h		\
 	gtkaction.h		\
 	gtkactiongroup.h	\
+	gtkactivatable.h	\
 	gtkadjustment.h		\
 	gtkalignment.h		\
 	gtkarrow.h		\
@@ -397,6 +398,7 @@ gtk_base_c_sources =            \
 	gtkaccessible.c		\
 	gtkaction.c		\
 	gtkactiongroup.c	\
+	gtkactivatable.c	\
 	gtkadjustment.c		\
 	gtkalignment.c		\
 	gtkarrow.c		\
Index: gtk/gtkmenuitem.c
===================================================================
--- gtk/gtkmenuitem.c	(revision 22083)
+++ gtk/gtkmenuitem.c	(working copy)
@@ -37,9 +37,16 @@
 #include "gtkseparatormenuitem.h"
 #include "gtkprivate.h"
 #include "gtkbuildable.h"
+#include "gtkactivatable.h"
 #include "gtkintl.h"
 #include "gtkalias.h"
 
+
+typedef struct {
+  GtkAction *action;
+  gboolean   use_action_appearance;
+} GtkMenuItemPrivate;
+
 enum {
   ACTIVATE,
   ACTIVATE_ITEM,
@@ -54,10 +61,15 @@ enum {
   PROP_SUBMENU,
   PROP_ACCEL_PATH,
   PROP_LABEL,
-  PROP_USE_UNDERLINE
+  PROP_USE_UNDERLINE,
+
+  /* activatable properties */
+  PROP_ACTIVATABLE_RELATED_ACTION,
+  PROP_ACTIVATABLE_USE_ACTION_APPEARANCE
 };
 
 
+static void gtk_menu_item_dispose        (GObject          *object);
 static void gtk_menu_item_set_property   (GObject          *object,
 					  guint             prop_id,
 					  const GValue     *value,
@@ -85,6 +97,7 @@ static void gtk_menu_item_parent_set    
 
 static void gtk_real_menu_item_select               (GtkItem     *item);
 static void gtk_real_menu_item_deselect             (GtkItem     *item);
+static void gtk_real_menu_item_activate             (GtkMenuItem *item);
 static void gtk_real_menu_item_activate_item        (GtkMenuItem *item);
 static void gtk_real_menu_item_toggle_size_request  (GtkMenuItem *menu_item,
 						     gint        *requisition);
@@ -120,13 +133,30 @@ static void gtk_menu_item_buildable_add_
 						    GObject             *child,
 						    const gchar         *type);
 
+static void gtk_menu_item_activatable_interface_init (GtkActivatableIface  *iface);
+static void gtk_menu_item_activatable_update         (GtkActivatable       *activatable,
+						      GtkAction            *action,
+						      const gchar          *property_name);
+static void gtk_menu_item_activatable_reset          (GtkActivatable       *activatable,
+						      GtkAction            *action);
+static void gtk_menu_item_set_related_action         (GtkMenuItem          *menu_item, 
+						      GtkAction            *action);
+static void gtk_menu_item_set_use_action_appearance  (GtkMenuItem          *menu_item, 
+						      gboolean              use_appearance);
+
+
 static guint menu_item_signals[LAST_SIGNAL] = { 0 };
 
 static GtkBuildableIface *parent_buildable_iface;
 
 G_DEFINE_TYPE_WITH_CODE (GtkMenuItem, gtk_menu_item, GTK_TYPE_ITEM,
 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
-						gtk_menu_item_buildable_interface_init))
+						gtk_menu_item_buildable_interface_init)
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
+						gtk_menu_item_activatable_interface_init))
+
+#define GET_PRIVATE(object)  \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((object), GTK_TYPE_MENU_ITEM, GtkMenuItemPrivate))
 
 static void
 gtk_menu_item_class_init (GtkMenuItemClass *klass)
@@ -137,6 +167,7 @@ gtk_menu_item_class_init (GtkMenuItemCla
   GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
   GtkItemClass *item_class = GTK_ITEM_CLASS (klass);
 
+  gobject_class->dispose      = gtk_menu_item_dispose;
   gobject_class->set_property = gtk_menu_item_set_property;
   gobject_class->get_property = gtk_menu_item_get_property;
 
@@ -157,15 +188,15 @@ gtk_menu_item_class_init (GtkMenuItemCla
   
   container_class->forall = gtk_menu_item_forall;
 
-  item_class->select = gtk_real_menu_item_select;
-  item_class->deselect = gtk_real_menu_item_deselect;
+  item_class->select      = gtk_real_menu_item_select;
+  item_class->deselect    = gtk_real_menu_item_deselect;
 
-  klass->activate = NULL;
-  klass->activate_item = gtk_real_menu_item_activate_item;
-  klass->toggle_size_request = gtk_real_menu_item_toggle_size_request;
+  klass->activate             = gtk_real_menu_item_activate;
+  klass->activate_item        = gtk_real_menu_item_activate_item;
+  klass->toggle_size_request  = gtk_real_menu_item_toggle_size_request;
   klass->toggle_size_allocate = gtk_real_menu_item_toggle_size_allocate;
-  klass->set_label = gtk_real_menu_item_set_label;
-  klass->get_label = gtk_real_menu_item_get_label;
+  klass->set_label            = gtk_real_menu_item_set_label;
+  klass->get_label            = gtk_real_menu_item_get_label;
 
   klass->hide_on_activate = TRUE;
 
@@ -288,6 +319,9 @@ gtk_menu_item_class_init (GtkMenuItemCla
 							 FALSE,
 							 GTK_PARAM_READWRITE));
 
+  g_object_class_override_property (gobject_class, PROP_ACTIVATABLE_RELATED_ACTION, "related-action");
+  g_object_class_override_property (gobject_class, PROP_ACTIVATABLE_USE_ACTION_APPEARANCE, "use-action-appearance");
+
   gtk_widget_class_install_style_property_parser (widget_class,
 						  g_param_spec_enum ("selected-shadow-type",
 								     "Selected Shadow Type",
@@ -344,12 +378,19 @@ gtk_menu_item_class_init (GtkMenuItemCla
                                                              P_("The minimum desired width of the menu item in characters"),
                                                              0, G_MAXINT, 12,
                                                              GTK_PARAM_READABLE));
+
+  g_type_class_add_private (object_class, sizeof (GtkMenuItemPrivate));
 }
 
 static void
 gtk_menu_item_init (GtkMenuItem *menu_item)
 {
+  GtkMenuItemPrivate *priv = GET_PRIVATE (menu_item);
+
   GTK_WIDGET_SET_FLAGS (menu_item, GTK_NO_WINDOW);
+
+  priv->action = NULL;
+  priv->use_action_appearance = TRUE;
   
   menu_item->submenu = NULL;
   menu_item->toggle_size = 0;
@@ -399,6 +440,22 @@ gtk_menu_item_new_with_mnemonic (const g
 		       NULL);
 }
 
+static void
+gtk_menu_item_dispose (GObject *object)
+{
+  GtkMenuItem *menu_item = GTK_MENU_ITEM (object);
+  GtkMenuItemPrivate *priv = GET_PRIVATE (menu_item);
+
+  if (priv->action)
+    {
+      gtk_action_disconnect_accelerator (priv->action);
+      gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (menu_item), NULL);
+      
+      priv->action = NULL;
+    }
+  G_OBJECT_CLASS (gtk_menu_item_parent_class)->dispose (object);
+}
+
 static void 
 gtk_menu_item_set_property (GObject      *object,
 			    guint         prop_id,
@@ -424,7 +481,12 @@ gtk_menu_item_set_property (GObject     
     case PROP_USE_UNDERLINE:
       gtk_menu_item_set_use_underline (menu_item, g_value_get_boolean (value));
       break;
-
+    case PROP_ACTIVATABLE_RELATED_ACTION:
+      gtk_menu_item_set_related_action (menu_item, g_value_get_object (value));
+      break;
+    case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE:
+      gtk_menu_item_set_use_action_appearance (menu_item, g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -438,6 +500,7 @@ gtk_menu_item_get_property (GObject    *
 			    GParamSpec *pspec)
 {
   GtkMenuItem *menu_item = GTK_MENU_ITEM (object);
+  GtkMenuItemPrivate *priv = GET_PRIVATE (menu_item);
   
   switch (prop_id)
     {
@@ -456,7 +519,12 @@ gtk_menu_item_get_property (GObject    *
     case PROP_USE_UNDERLINE:
       g_value_set_boolean (value, gtk_menu_item_get_use_underline (menu_item));
       break;
-
+    case PROP_ACTIVATABLE_RELATED_ACTION:
+      g_value_set_object (value, priv->action);
+      break;
+    case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE:
+      g_value_set_boolean (value, priv->use_action_appearance);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -505,6 +573,136 @@ gtk_menu_item_buildable_add_child (GtkBu
     parent_buildable_iface->add_child (buildable, builder, child, type);
 }
 
+static void
+gtk_menu_item_activatable_interface_init (GtkActivatableIface *iface)
+{
+  iface->update = gtk_menu_item_activatable_update;
+  iface->reset = gtk_menu_item_activatable_reset;
+}
+
+static void 
+activatable_update_label (GtkMenuItem *menu_item, GtkAction *action)
+{
+  GtkWidget *child = GTK_BIN (menu_item)->child;
+	  
+  if (GTK_IS_LABEL (child))
+    {
+      const gchar *label;
+
+      label = gtk_action_get_label (action);
+      gtk_label_set_label (GTK_LABEL (child), label ? label : "");
+    }
+}
+
+gboolean _gtk_menu_is_empty (GtkWidget *menu);
+
+static void
+gtk_menu_item_activatable_update (GtkActivatable *activatable,
+				  GtkAction      *action,
+				  const gchar    *property_name)
+{
+  GtkMenuItem *menu_item = GTK_MENU_ITEM (activatable);
+  GtkMenuItemPrivate *priv = GET_PRIVATE (menu_item);
+
+  if (strcmp (property_name, "visible") == 0)
+    _gtk_action_sync_menu_visible (action, GTK_WIDGET (menu_item), 
+				   _gtk_menu_is_empty (gtk_menu_item_get_submenu (menu_item)));
+  else if (strcmp (property_name, "sensitive") == 0)
+    gtk_widget_set_sensitive (GTK_WIDGET (menu_item), gtk_action_is_sensitive (action));
+  else if (priv->use_action_appearance)
+    {
+      if (strcmp (property_name, "label") == 0)
+	activatable_update_label (menu_item, action);
+    }
+}
+
+static void
+gtk_menu_item_activatable_reset (GtkActivatable *activatable,
+				 GtkAction      *action)
+{
+  GtkMenuItem *menu_item = GTK_MENU_ITEM (activatable);
+  GtkMenuItemPrivate *priv = GET_PRIVATE (menu_item);
+
+  _gtk_action_sync_menu_visible (action, GTK_WIDGET (menu_item), 
+				 _gtk_menu_is_empty (gtk_menu_item_get_submenu (menu_item)));
+
+  gtk_widget_set_sensitive (GTK_WIDGET (menu_item), gtk_action_is_sensitive (action));
+
+  if (priv->use_action_appearance)
+    {
+      GtkWidget *label = GTK_BIN (menu_item)->child;
+	  
+      /* make sure label is a label */
+      if (label && !GTK_IS_LABEL (label))
+	{
+	  gtk_container_remove (GTK_CONTAINER (menu_item), label);
+	  label = NULL;
+	}
+	  
+      if (!label)
+	label = g_object_new (GTK_TYPE_ACCEL_LABEL,
+			      "use-underline", TRUE,
+			      "xalign", 0.0,
+			      "visible", TRUE,
+			      "parent", menu_item,
+			      NULL);
+      
+      if (GTK_IS_ACCEL_LABEL (label) && gtk_action_get_accel_path (action))
+	g_object_set (label,
+		      "accel-closure", gtk_action_get_accel_closure (action),
+		      NULL);
+      
+      activatable_update_label (menu_item, action);
+    }
+}
+
+static void
+gtk_menu_item_set_related_action (GtkMenuItem *menu_item, 
+				  GtkAction   *action)
+{
+    GtkMenuItemPrivate *priv = GET_PRIVATE (menu_item);
+
+    if (priv->action == action)
+      return;
+
+    if (priv->action)
+      {
+	gtk_action_disconnect_accelerator (priv->action);
+      }
+
+    if (action)
+      {
+	const gchar *accel_path;
+	
+	accel_path = gtk_action_get_accel_path (action);
+	if (accel_path)
+	  {
+	    gtk_action_connect_accelerator (action);
+	    gtk_menu_item_set_accel_path (menu_item, accel_path);
+	  }
+      }
+
+    gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (menu_item), action);
+
+    priv->action = action;
+}
+
+static void
+gtk_menu_item_set_use_action_appearance (GtkMenuItem *menu_item, 
+					 gboolean     use_appearance)
+{
+    GtkMenuItemPrivate *priv = GET_PRIVATE (menu_item);
+
+    if (priv->use_action_appearance != use_appearance)
+      {
+	priv->use_action_appearance = use_appearance;
+	
+	if (priv->action && use_appearance)
+	  gtk_activatable_reset (GTK_ACTIVATABLE (menu_item), priv->action);
+      }
+}
+
+
 /**
  * gtk_menu_item_set_submenu:
  * @menu_item: a #GtkMenuItem
@@ -629,7 +827,7 @@ void
 gtk_menu_item_activate (GtkMenuItem *menu_item)
 {
   g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
-  
+
   g_signal_emit (menu_item, menu_item_signals[ACTIVATE], 0);
 }
 
@@ -1142,13 +1340,27 @@ gtk_menu_item_mnemonic_activate (GtkWidg
   return TRUE;
 }
 
+static void 
+gtk_real_menu_item_activate (GtkMenuItem *menu_item)
+{
+  GtkMenuItemPrivate *priv;
+
+  priv = GET_PRIVATE (menu_item);
+
+  if (priv->action && gtk_menu_item_get_submenu (menu_item) == NULL)
+    gtk_action_activate (priv->action);
+}
+
+
 static void
 gtk_real_menu_item_activate_item (GtkMenuItem *menu_item)
 {
+  GtkMenuItemPrivate *priv;
   GtkWidget *widget;
 
   g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
 
+  priv   = GET_PRIVATE (menu_item);
   widget = GTK_WIDGET (menu_item);
   
   if (widget->parent &&
Index: gtk/gtkimagemenuitem.c
===================================================================
--- gtk/gtkimagemenuitem.c	(revision 22083)
+++ gtk/gtkimagemenuitem.c	(working copy)
@@ -34,6 +34,7 @@
 #include "gtkmenubar.h"
 #include "gtkcontainer.h"
 #include "gtkwindow.h"
+#include "gtkactivatable.h"
 #include "gtkprivate.h"
 #include "gtkalias.h"
 
@@ -70,6 +71,12 @@ static void gtk_image_menu_item_screen_c
 
 static void gtk_image_menu_item_recalculate          (GtkImageMenuItem *image_menu_item);
 
+static void gtk_image_menu_item_activatable_interface_init (GtkActivatableIface  *iface);
+static void gtk_image_menu_item_activatable_update         (GtkActivatable       *activatable,
+							    GtkAction            *action,
+							    const gchar          *property_name);
+static void gtk_image_menu_item_activatable_reset          (GtkActivatable       *activatable,
+							    GtkAction            *action);
 
 typedef struct {
   gchar          *label;
@@ -83,7 +90,12 @@ enum {
   PROP_ACCEL_GROUP
 };
 
-G_DEFINE_TYPE (GtkImageMenuItem, gtk_image_menu_item, GTK_TYPE_MENU_ITEM)
+static GtkActivatableIface *parent_activatable_iface;
+
+
+G_DEFINE_TYPE_WITH_CODE (GtkImageMenuItem, gtk_image_menu_item, GTK_TYPE_MENU_ITEM,
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
+						gtk_image_menu_item_activatable_interface_init))
 
 #define GET_PRIVATE(object)  \
   (G_TYPE_INSTANCE_GET_PRIVATE ((object), GTK_TYPE_IMAGE_MENU_ITEM, GtkImageMenuItemPrivate))
@@ -504,6 +516,131 @@ gtk_image_menu_item_forall (GtkContainer
     (* callback) (image_menu_item->image, callback_data);
 }
 
+
+static void 
+gtk_image_menu_item_activatable_interface_init (GtkActivatableIface  *iface)
+{
+  parent_activatable_iface = g_type_interface_peek_parent (iface);
+  iface->update = gtk_image_menu_item_activatable_update;
+  iface->reset = gtk_image_menu_item_activatable_reset;
+}
+
+static gboolean
+activatable_update_stock_id (GtkImageMenuItem *image_menu_item, GtkAction *action)
+{
+  GtkWidget   *image;
+  const gchar *stock_id  = gtk_action_get_stock_id (action);
+
+  image = gtk_image_menu_item_get_image (image_menu_item);
+	  
+  if (GTK_IS_IMAGE (image) &&
+      stock_id && gtk_icon_factory_lookup_default (stock_id))
+    {
+      gtk_image_set_from_stock (GTK_IMAGE (image), stock_id, GTK_ICON_SIZE_MENU);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+activatable_update_gicon (GtkImageMenuItem *image_menu_item, GtkAction *action)
+{
+  GtkWidget   *image;
+  GIcon       *icon = gtk_action_get_gicon (action);
+  const gchar *stock_id = gtk_action_get_stock_id (action);
+
+  image = gtk_image_menu_item_get_image (image_menu_item);
+
+  if (icon && GTK_IS_IMAGE (image) &&
+      !(stock_id && gtk_icon_factory_lookup_default (stock_id)))
+    {
+      gtk_image_set_from_gicon (GTK_IMAGE (image), icon, GTK_ICON_SIZE_MENU);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static void
+activatable_update_icon_name (GtkImageMenuItem *image_menu_item, GtkAction *action)
+{
+  GtkWidget   *image;
+  const gchar *icon_name = gtk_action_get_icon_name (action);
+
+  image = gtk_image_menu_item_get_image (image_menu_item);
+	  
+  if (GTK_IS_IMAGE (image) && icon_name &&
+      (gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY ||
+       gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_ICON_NAME))
+    {
+      gtk_image_set_from_icon_name (GTK_IMAGE (image), icon_name, GTK_ICON_SIZE_MENU);
+    }
+}
+
+static void 
+gtk_image_menu_item_activatable_update (GtkActivatable       *activatable,
+					GtkAction            *action,
+					const gchar          *property_name)
+{
+  GtkImageMenuItem *image_menu_item;
+  GtkWidget *image;
+  gboolean   use_appearance;
+
+  image_menu_item = GTK_IMAGE_MENU_ITEM (activatable);
+
+  parent_activatable_iface->update (activatable, action, property_name);
+
+  use_appearance = gtk_activatable_get_use_action_appearance (activatable);
+  if (!use_appearance)
+    return;
+
+  if (strcmp (property_name, "stock-id") == 0)
+    activatable_update_stock_id (image_menu_item, action);
+  else if (strcmp (property_name, "gicon") == 0)
+    activatable_update_gicon (image_menu_item, action);
+  else if (strcmp (property_name, "icon-name") == 0)
+    activatable_update_icon_name (image_menu_item, action);
+}
+
+static void 
+gtk_image_menu_item_activatable_reset (GtkActivatable       *activatable,
+				       GtkAction            *action)
+{
+  GtkImageMenuItem *image_menu_item;
+  GtkWidget *image;
+  gboolean   use_appearance;
+
+  image_menu_item = GTK_IMAGE_MENU_ITEM (activatable);
+
+  parent_activatable_iface->reset (activatable, action);
+
+  use_appearance = gtk_activatable_get_use_action_appearance (activatable);
+  if (!use_appearance)
+    return;
+
+  image = gtk_image_menu_item_get_image (image_menu_item);
+  if (image && !GTK_IS_IMAGE (image))
+    {
+      gtk_image_menu_item_set_image (image_menu_item, NULL);
+      image = NULL;
+    }
+  
+  if (!image)
+    {
+      image = gtk_image_new ();
+      gtk_widget_show (image);
+      gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (activatable),
+				     image);
+    }
+  
+  if (!activatable_update_stock_id (image_menu_item, action) &&
+      !activatable_update_gicon (image_menu_item, action))
+    activatable_update_icon_name (image_menu_item, action);
+
+}
+
+
 /**
  * gtk_image_menu_item_new:
  * @returns: a new #GtkImageMenuItem.
Index: gtk/gtktoolitem.c
===================================================================
--- gtk/gtktoolitem.c	(revision 22083)
+++ gtk/gtktoolitem.c	(working copy)
@@ -30,6 +30,7 @@
 #include "gtkmarshalers.h"
 #include "gtktoolshell.h"
 #include "gtkseparatormenuitem.h"
+#include "gtkactivatable.h"
 #include "gtkintl.h"
 #include "gtkmain.h"
 #include "gtkprivate.h"
@@ -69,7 +70,11 @@ enum {
   PROP_0,
   PROP_VISIBLE_HORIZONTAL,
   PROP_VISIBLE_VERTICAL,
-  PROP_IS_IMPORTANT
+  PROP_IS_IMPORTANT,
+
+  /* activatable properties */
+  PROP_ACTIVATABLE_RELATED_ACTION,
+  PROP_ACTIVATABLE_USE_ACTION_APPEARANCE
 };
 
 #define GTK_TOOL_ITEM_GET_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_TOOL_ITEM, GtkToolItemPrivate))
@@ -90,11 +95,15 @@ struct _GtkToolItemPrivate
   
   gchar *menu_item_id;
   GtkWidget *menu_item;
+
+  GtkAction *action;
+  gboolean   use_action_appearance;
 };
   
-static void gtk_tool_item_finalize    (GObject *object);
-static void gtk_tool_item_parent_set   (GtkWidget   *toolitem,
-				        GtkWidget   *parent);
+static void gtk_tool_item_finalize     (GObject         *object);
+static void gtk_tool_item_dispose      (GObject         *object);
+static void gtk_tool_item_parent_set   (GtkWidget       *toolitem,
+				        GtkWidget       *parent);
 static void gtk_tool_item_set_property (GObject         *object,
 					guint            prop_id,
 					const GValue    *value,
@@ -120,10 +129,22 @@ static gboolean gtk_tool_item_real_set_t
 
 static gboolean gtk_tool_item_create_menu_proxy (GtkToolItem *item);
 
+static void gtk_tool_item_activatable_interface_init (GtkActivatableIface  *iface);
+static void gtk_tool_item_activatable_update         (GtkActivatable       *activatable,
+						      GtkAction            *action,
+						      const gchar          *property_name);
+static void gtk_tool_item_activatable_reset          (GtkActivatable       *activatable,
+						      GtkAction            *action);
+static void gtk_tool_item_set_related_action         (GtkToolItem          *item, 
+						      GtkAction            *action);
+static void gtk_tool_item_set_use_action_appearance  (GtkToolItem          *item, 
+						      gboolean              use_appearance);
 
 static guint toolitem_signals[LAST_SIGNAL] = { 0 };
 
-G_DEFINE_TYPE (GtkToolItem, gtk_tool_item, GTK_TYPE_BIN)
+G_DEFINE_TYPE_WITH_CODE (GtkToolItem, gtk_tool_item, GTK_TYPE_BIN,
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
+						gtk_tool_item_activatable_interface_init))
 
 static void
 gtk_tool_item_class_init (GtkToolItemClass *klass)
@@ -136,8 +157,9 @@ gtk_tool_item_class_init (GtkToolItemCla
   
   object_class->set_property = gtk_tool_item_set_property;
   object_class->get_property = gtk_tool_item_get_property;
-  object_class->finalize = gtk_tool_item_finalize;
-  object_class->notify = gtk_tool_item_property_notify;
+  object_class->finalize     = gtk_tool_item_finalize;
+  object_class->dispose      = gtk_tool_item_dispose;
+  object_class->notify       = gtk_tool_item_property_notify;
 
   widget_class->realize       = gtk_tool_item_realize;
   widget_class->unrealize     = gtk_tool_item_unrealize;
@@ -172,6 +194,10 @@ gtk_tool_item_class_init (GtkToolItemCla
  							 FALSE,
  							 GTK_PARAM_READWRITE));
 
+  g_object_class_override_property (object_class, PROP_ACTIVATABLE_RELATED_ACTION, "related-action");
+  g_object_class_override_property (object_class, PROP_ACTIVATABLE_USE_ACTION_APPEARANCE, "use-action-appearance");
+
+
 /**
  * GtkToolItem::create-menu-proxy:
  * @tool_item: the object the signal was emitted on
@@ -276,6 +302,8 @@ gtk_tool_item_init (GtkToolItem *toolite
   toolitem->priv->visible_vertical = TRUE;
   toolitem->priv->homogeneous = FALSE;
   toolitem->priv->expand = FALSE;
+
+  toolitem->priv->use_action_appearance = TRUE;
 }
 
 static void
@@ -292,6 +320,20 @@ gtk_tool_item_finalize (GObject *object)
 }
 
 static void
+gtk_tool_item_dispose (GObject *object)
+{
+  GtkToolItem *item = GTK_TOOL_ITEM (object);
+
+  if (item->priv->action)
+    {
+      gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (item), NULL);      
+      item->priv->action = NULL;
+    }
+  G_OBJECT_CLASS (gtk_tool_item_parent_class)->dispose (object);
+}
+
+
+static void
 gtk_tool_item_parent_set (GtkWidget   *toolitem,
 			  GtkWidget   *prev_parent)
 {
@@ -318,6 +360,12 @@ gtk_tool_item_set_property (GObject     
     case PROP_IS_IMPORTANT:
       gtk_tool_item_set_is_important (toolitem, g_value_get_boolean (value));
       break;
+    case PROP_ACTIVATABLE_RELATED_ACTION:
+      gtk_tool_item_set_related_action (toolitem, g_value_get_object (value));
+      break;
+    case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE:
+      gtk_tool_item_set_use_action_appearance (toolitem, g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -343,6 +391,12 @@ gtk_tool_item_get_property (GObject    *
     case PROP_IS_IMPORTANT:
       g_value_set_boolean (value, toolitem->priv->is_important);
       break;
+    case PROP_ACTIVATABLE_RELATED_ACTION:
+      g_value_set_object (value, toolitem->priv->action);
+      break;
+    case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE:
+      g_value_set_boolean (value, toolitem->priv->use_action_appearance);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -503,9 +557,114 @@ gtk_tool_item_size_allocate (GtkWidget  
 static gboolean
 gtk_tool_item_create_menu_proxy (GtkToolItem *item)
 {
+  GtkWidget *menu_item;
+  gboolean visible_overflown;
+
+  if (item->priv->action)
+    {
+      g_object_get (item->priv->action, "visible-overflown", &visible_overflown, NULL);
+    
+      if (visible_overflown)
+	{
+	  menu_item = gtk_action_create_menu_item (item->priv->action);
+
+	  g_object_ref_sink (menu_item);
+      	  gtk_tool_item_set_proxy_menu_item (item, "gtk-action-menu-item", menu_item);
+	  g_object_unref (menu_item);
+	}
+      else
+	gtk_tool_item_set_proxy_menu_item (item, "gtk-action-menu-item", NULL);
+    }
+
   return FALSE;
 }
 
+static void 
+gtk_tool_item_activatable_interface_init (GtkActivatableIface  *iface)
+{
+  iface->update = gtk_tool_item_activatable_update;
+  iface->reset = gtk_tool_item_activatable_reset;
+}
+
+static void 
+gtk_tool_item_activatable_update (GtkActivatable       *activatable,
+				  GtkAction            *action,
+				  const gchar          *property_name)
+{
+  if (strcmp (property_name, "visible") == 0)
+    {
+      if (gtk_action_is_visible (action))
+	gtk_widget_show (GTK_WIDGET (activatable));
+      else
+	gtk_widget_hide (GTK_WIDGET (activatable));
+    }
+  else if (strcmp (property_name, "sensitive") == 0)
+    gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
+  else if (strcmp (property_name, "tooltip") == 0)
+    gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (activatable),
+				    gtk_action_get_tooltip (action));
+  else if (strcmp (property_name, "visible-horizontal") == 0)
+    gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (activatable),
+					  gtk_action_get_visible_horizontal (action));
+  else if (strcmp (property_name, "visible-vertical") == 0)
+    gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (activatable),
+					gtk_action_get_visible_vertical (action));
+  else if (strcmp (property_name, "is-important") == 0)
+    gtk_tool_item_set_is_important (GTK_TOOL_ITEM (activatable),
+				    gtk_action_get_is_important (action));
+}
+static void 
+gtk_tool_item_activatable_reset (GtkActivatable       *activatable,
+				 GtkAction            *action)
+{
+  if (gtk_action_is_visible (action))
+    gtk_widget_show (GTK_WIDGET (activatable));
+  else
+    gtk_widget_hide (GTK_WIDGET (activatable));
+  
+  gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
+  
+  gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (activatable),
+				  gtk_action_get_tooltip (action));
+  gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (activatable),
+					gtk_action_get_visible_horizontal (action));
+  gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (activatable),
+				      gtk_action_get_visible_vertical (action));
+  gtk_tool_item_set_is_important (GTK_TOOL_ITEM (activatable),
+				  gtk_action_get_is_important (action));
+}
+
+static void
+gtk_tool_item_set_related_action (GtkToolItem *item, 
+				  GtkAction   *action)
+{
+  if (item->priv->action == action)
+    return;
+
+  gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (item), action);
+
+  item->priv->action = action;
+
+  if (action)
+    {
+      gtk_tool_item_rebuild_menu (item);
+    }
+}
+
+static void
+gtk_tool_item_set_use_action_appearance (GtkToolItem *item, 
+					 gboolean     use_appearance)
+{
+  if (item->priv->use_action_appearance != use_appearance)
+    {
+      item->priv->use_action_appearance = use_appearance;
+      
+      if (item->priv->action && use_appearance)
+	gtk_activatable_reset (GTK_ACTIVATABLE (item), item->priv->action);
+    }
+}
+
+
 /**
  * gtk_tool_item_new:
  * 
Index: gtk/gtkradiomenuitem.c
===================================================================
--- gtk/gtkradiomenuitem.c	(revision 22083)
+++ gtk/gtkradiomenuitem.c	(working copy)
@@ -28,6 +28,7 @@
 #include "gtkaccellabel.h"
 #include "gtkmarshalers.h"
 #include "gtkradiomenuitem.h"
+#include "gtkactivatable.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
 #include "gtkalias.h"
@@ -420,9 +421,14 @@ gtk_radio_menu_item_activate (GtkMenuIte
   GtkRadioMenuItem *radio_menu_item = GTK_RADIO_MENU_ITEM (menu_item);
   GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (menu_item);
   GtkCheckMenuItem *tmp_menu_item;
+  GtkAction        *action;
   GSList *tmp_list;
   gint toggled;
 
+  action = gtk_activatable_get_related_action (GTK_ACTIVATABLE (menu_item));
+  if (action && gtk_menu_item_get_submenu (menu_item) == NULL)
+    gtk_action_activate (action);
+
   toggled = FALSE;
 
   if (check_menu_item->active)
@@ -467,7 +473,9 @@ gtk_radio_menu_item_activate (GtkMenuIte
     }
 
   if (toggled)
-    gtk_check_menu_item_toggled (check_menu_item);
+    {
+      gtk_check_menu_item_toggled (check_menu_item);
+    }
 
   gtk_widget_queue_draw (GTK_WIDGET (radio_menu_item));
 }
Index: gtk/gtkrecentaction.c
===================================================================
--- gtk/gtkrecentaction.c	(revision 22083)
+++ gtk/gtkrecentaction.c	(working copy)
@@ -42,7 +42,6 @@
 struct _GtkRecentActionPrivate
 {
   GtkRecentManager *manager;
-  guint manager_changed_id;
 
   guint show_numbers   : 1;
 
@@ -57,8 +56,8 @@ struct _GtkRecentActionPrivate
 
   GtkRecentSortType sort_type;
   GtkRecentSortFunc sort_func;
-  gpointer sort_data;
-  GDestroyNotify data_destroy;
+  gpointer          sort_data;
+  GDestroyNotify    data_destroy;
 
   GtkRecentFilter *current_filter;
 
@@ -213,7 +212,7 @@ gtk_recent_action_set_sort_func (GtkRece
   for (l = priv->choosers; l; l = l->next)
     {
       GtkRecentChooser *chooser_menu = l->data;
-
+      
       gtk_recent_chooser_set_sort_func (chooser_menu, priv->sort_func,
                                         priv->sort_data,
                                         priv->data_destroy);
@@ -225,7 +224,6 @@ set_current_filter (GtkRecentAction *act
                     GtkRecentFilter *filter)
 {
   GtkRecentActionPrivate *priv = action->priv;
-  GSList *l;
 
   g_object_ref (action);
 
@@ -237,13 +235,6 @@ set_current_filter (GtkRecentAction *act
   if (priv->current_filter)
     g_object_ref_sink (priv->current_filter);
 
-  for (l = priv->choosers; l; l = l->next)
-    {
-      GtkRecentChooser *chooser = l->data;
-
-      gtk_recent_chooser_set_filter (chooser, priv->current_filter);
-    }
-
   g_object_notify (G_OBJECT (action), "filter");
 
   g_object_unref (action);
@@ -338,21 +329,10 @@ gtk_recent_action_connect_proxy (GtkActi
   GtkRecentAction *recent_action = GTK_RECENT_ACTION (action);
   GtkRecentActionPrivate *priv = recent_action->priv;
 
+  /* it can only be a recent chooser implementor anyway... */
   if (GTK_IS_RECENT_CHOOSER (widget) &&
       !g_slist_find (priv->choosers, widget))
     {
-      g_object_set (G_OBJECT (widget),
-                    "show-private", priv->show_private,
-                    "show-not-found", priv->show_not_found,
-                    "show-tips", priv->show_tips,
-                    "show-icons", priv->show_icons,
-                    "show-numbers", priv->show_numbers,
-                    "limit", priv->limit,
-                    "sort-type", priv->sort_type,
-                    "filter", priv->current_filter,
-                    "local-only", priv->local_only,
-                    NULL);
-  
       if (priv->sort_func)
         {
           gtk_recent_chooser_set_sort_func (GTK_RECENT_CHOOSER (widget),
@@ -369,7 +349,8 @@ gtk_recent_action_connect_proxy (GtkActi
                                 action);
     }
 
-  GTK_ACTION_CLASS (gtk_recent_action_parent_class)->connect_proxy (action, widget);
+  if (GTK_ACTION_CLASS (gtk_recent_action_parent_class)->connect_proxy)
+    GTK_ACTION_CLASS (gtk_recent_action_parent_class)->connect_proxy (action, widget);
 }
 
 static void
@@ -385,7 +366,8 @@ gtk_recent_action_disconnect_proxy (GtkA
   if (g_slist_find (priv->choosers, widget))
     priv->choosers = g_slist_remove (priv->choosers, widget);
 
-  GTK_ACTION_CLASS (gtk_recent_action_parent_class)->disconnect_proxy (action, widget);
+  if (GTK_ACTION_CLASS (gtk_recent_action_parent_class)->disconnect_proxy)
+    GTK_ACTION_CLASS (gtk_recent_action_parent_class)->disconnect_proxy (action, widget);
 }
 
 static GtkWidget *
@@ -458,38 +440,15 @@ gtk_recent_action_create_tool_item (GtkA
 }
 
 static void
-manager_changed_cb (GtkRecentManager *manager,
-                    gpointer          user_data)
-{
-  /* do we need to propagate the signal to all the proxies? guess not */
-}
-
-static void
 set_recent_manager (GtkRecentAction  *action,
                     GtkRecentManager *manager)
 {
   GtkRecentActionPrivate *priv = action->priv;
 
-  if (priv->manager)
-    {
-      if (priv->manager_changed_id)
-        {
-          g_signal_handler_disconnect (priv->manager, priv->manager_changed_id);
-          priv->manager_changed_id = 0;
-        }
-
-      priv->manager = NULL;
-    }
-
   if (manager)
     priv->manager = NULL;
   else
     priv->manager = gtk_recent_manager_get_default ();
-
-  if (priv->manager)
-    priv->manager_changed_id = g_signal_connect (priv->manager, "changed",
-                                                 G_CALLBACK (manager_changed_cb),
-                                                 action);
 }
 
 static void
@@ -520,14 +479,6 @@ gtk_recent_action_dispose (GObject *gobj
   GtkRecentAction *action = GTK_RECENT_ACTION (gobject);
   GtkRecentActionPrivate *priv = action->priv;
 
-  if (priv->manager_changed_id)
-    {
-      if (priv->manager)
-        g_signal_handler_disconnect (priv->manager, priv->manager_changed_id);
-
-      priv->manager_changed_id = 0;
-    }
-
   if (priv->current_filter)
     {
       g_object_unref (priv->current_filter);
@@ -545,7 +496,6 @@ gtk_recent_action_set_property (GObject 
 {
   GtkRecentAction *action = GTK_RECENT_ACTION (gobject);
   GtkRecentActionPrivate *priv = action->priv;
-  GSList *l;
 
   switch (prop_id)
     {
@@ -574,33 +524,20 @@ gtk_recent_action_set_property (GObject 
       priv->sort_type = g_value_get_enum (value);
       break;
     case GTK_RECENT_CHOOSER_PROP_FILTER:
-      /* this already iterates over the choosers list */
       set_current_filter (action, g_value_get_object (value));
-      return;
+      break;
     case GTK_RECENT_CHOOSER_PROP_SELECT_MULTIPLE:
       g_warning ("%s: Choosers of type `%s' do not support selecting multiple items.",
                  G_STRFUNC,
                  G_OBJECT_TYPE_NAME (gobject));
       return;
     case GTK_RECENT_CHOOSER_PROP_RECENT_MANAGER:
-      /* this is a construct-only property; we set the recent-manager
-       * of the choosers with this value when we create them, so there's
-       * no need to iterate later.
-       */
       set_recent_manager (action, g_value_get_object (value));
-      return;
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
       return;
     }
-
-  /* propagate the properties to the proxies we have created */
-  for (l = priv->choosers; l != NULL; l = l->next)
-    {
-      GObject *proxy = l->data;
-
-      g_object_set_property (proxy, pspec->name, value);
-    }
 }
 
 static void
@@ -707,7 +644,6 @@ gtk_recent_action_init (GtkRecentAction 
   priv->current_filter = NULL;
 
   priv->manager = NULL;
-  priv->manager_changed_id = 0;
 }
 
 /**
Index: gtk/gtkrecentaction.h
===================================================================
--- gtk/gtkrecentaction.h	(revision 22083)
+++ gtk/gtkrecentaction.h	(working copy)
@@ -28,6 +28,7 @@
 
 #include <gtk/gtkaction.h>
 #include <gtk/gtkrecentmanager.h>
+#include <gtk/gtkrecentchooser.h>
 
 G_BEGIN_DECLS
 
