Index: gtkwidget.c
===================================================================
--- gtkwidget.c	(revision 21776)
+++ gtkwidget.c	(working copy)
@@ -53,6 +53,7 @@
 #include "gtkinvisible.h"
 #include "gtkbuildable.h"
 #include "gtkbuilderprivate.h"
+#include "gtkaction.h"
 #include "gtkalias.h"
 
 #define WIDGET_CLASS(w)	 GTK_WIDGET_GET_CLASS (w)
@@ -154,7 +155,9 @@ enum {
   PROP_HAS_TOOLTIP,
   PROP_TOOLTIP_MARKUP,
   PROP_TOOLTIP_TEXT,
-  PROP_WINDOW
+  PROP_WINDOW,
+  PROP_ACTION_CONTROLS_APPEARANCE,
+  PROP_ACTION
 };
 
 typedef	struct	_GtkStateData	 GtkStateData;
@@ -691,6 +694,39 @@ gtk_widget_class_init (GtkWidgetClass *k
 							GDK_TYPE_WINDOW,
 							GTK_PARAM_READABLE));
 
+
+  /**
+   * GtkWidget:action-controls-appearance:
+   *
+   * Whether the action this widget is a proxy for controls the
+   * appearance of this widget.
+   *
+   * Since: 2.16
+   */
+  g_object_class_install_property (gobject_class,
+				   PROP_ACTION_CONTROLS_APPEARANCE,
+				   g_param_spec_boolean ("action-controls-appearance",
+							 P_("Action Controls Appearance"),
+							 P_("Whether the controlling action modifies the widgets appearance"),
+							 TRUE,
+							 GTK_PARAM_READWRITE));
+
+  /**
+   * GtkWidget:action-controller:
+   *
+   * The action this widget is a proxy for
+   *
+   * Since: 2.16
+   */
+  g_object_class_install_property (gobject_class,
+				   PROP_ACTION,
+				   g_param_spec_object ("action-controller",
+ 							P_("Action Controller"),
+							P_("The action this widget is a proxy for"),
+							GTK_TYPE_ACTION,
+							GTK_PARAM_READWRITE));
+
+
   widget_signals[SHOW] =
     g_signal_new (I_("show"),
 		  G_TYPE_FROM_CLASS (gobject_class),
@@ -2516,6 +2552,13 @@ gtk_widget_set_property (GObject        
       gtk_widget_real_set_has_tooltip (widget, tmp, FALSE);
       gtk_widget_trigger_tooltip_query (widget);
       break;
+    case PROP_ACTION_CONTROLS_APPEARANCE:
+      gtk_widget_set_action_appearance_updates (widget, g_value_get_boolean (value));
+      break;
+    case PROP_ACTION:
+      gtk_widget_set_action (widget, (GtkAction *)g_value_get_object (value),
+			     gtk_widget_get_action_appearance_updates (widget));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2623,6 +2666,12 @@ gtk_widget_get_property (GObject        
     case PROP_WINDOW:
       g_value_set_object (value, gtk_widget_get_window (widget));
       break;
+    case PROP_ACTION_CONTROLS_APPEARANCE:
+      g_value_set_boolean (value, gtk_widget_get_action_appearance_updates (widget));
+      break;
+    case PROP_ACTION:
+      g_value_set_object (value, gtk_widget_get_action (widget));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
Index: gtkaction.c
===================================================================
--- gtkaction.c	(revision 21776)
+++ gtkaction.c	(working copy)
@@ -119,8 +119,10 @@ G_DEFINE_TYPE_WITH_CODE (GtkAction, gtk_
 						gtk_action_buildable_init))
 
 
-static GQuark      quark_gtk_action_proxy  = 0;
-static const gchar gtk_action_proxy_key[] = "gtk-action";
+static GQuark      quark_gtk_action_proxy               = 0;
+static GQuark      quark_gtk_action_update_appearances  = 0;
+static const gchar gtk_action_proxy_key[]               = "gtk-action";
+static const gchar gtk_action_update_appearances_key[]  = "gtk-action-appearance";
 
 static void gtk_action_finalize     (GObject *object);
 static void gtk_action_set_property (GObject         *object,
@@ -175,6 +177,7 @@ gtk_action_class_init (GtkActionClass *k
   GObjectClass *gobject_class;
 
   quark_gtk_action_proxy = g_quark_from_static_string (gtk_action_proxy_key);
+  quark_gtk_action_update_appearances = g_quark_from_static_string (gtk_action_update_appearances_key);
 
   gobject_class = G_OBJECT_CLASS (klass);
 
@@ -685,10 +688,15 @@ static void
 connect_proxy (GtkAction     *action, 
 	       GtkWidget     *proxy)
 {
+  gboolean update_appearance;
+
   g_object_ref (action);
   g_object_set_qdata_full (G_OBJECT (proxy), quark_gtk_action_proxy, action,
 			   g_object_unref);
 
+
+  update_appearance = gtk_widget_get_action_appearance_updates (proxy);
+
   /* 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);
@@ -698,7 +706,9 @@ connect_proxy (GtkAction     *action, 
     gtk_widget_show (proxy);
   else
     gtk_widget_hide (proxy);
-  gtk_widget_set_no_show_all (proxy, TRUE);
+
+  if (update_appearance)
+    gtk_widget_set_no_show_all (proxy, TRUE);
 
   if (GTK_IS_MENU_ITEM (proxy))
     {
@@ -711,63 +721,66 @@ connect_proxy (GtkAction     *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))
+      if (update_appearance)
 	{
-	  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))
+	  label = GTK_BIN (proxy)->child;
+	  
+	  /* make sure label is a label */
+	  if (label && !GTK_IS_LABEL (label))
 	    {
-	      gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy), NULL);
-	      image = NULL;
+	      gtk_container_remove (GTK_CONTAINER (proxy), label);
+	      label = NULL;
 	    }
-	  if (!image)
+	  
+	  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))
 	    {
-	      image = gtk_image_new ();
-	      gtk_widget_show (image);
-	      gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy),
-					     image);
+	      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->icon_name)
+		gtk_image_set_from_icon_name (GTK_IMAGE (image),
+					      action->private_data->icon_name, GTK_ICON_SIZE_MENU);
 	    }
 	  
-	  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->icon_name)
-	    gtk_image_set_from_icon_name (GTK_IMAGE (image),
-					  action->private_data->icon_name, GTK_ICON_SIZE_MENU);
+	  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);
 	}
-      
-      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))
     {
@@ -778,12 +791,16 @@ connect_proxy (GtkAction     *action, 
 		        "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 (update_appearance)
+	    g_object_set (proxy,
+			  "label", action->private_data->short_label,
+			  "use-underline", TRUE,
+			  "stock-id", action->private_data->stock_id,
+			  "icon-name", action->private_data->icon_name,
+			  NULL);
+
 	  g_signal_connect_object (proxy, "clicked",
 				   G_CALLBACK (gtk_action_activate), action,
 				   G_CONNECT_SWAPPED);
@@ -807,37 +824,42 @@ connect_proxy (GtkAction     *action, 
     }
   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 
+      
+      if (update_appearance)
 	{
-	  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))
+	  /* button specific synchronisers ... */
+	  if (gtk_button_get_use_stock (GTK_BUTTON (proxy)))
 	    {
-	      /* synchronise the label */
+	      /* synchronise stock-id */
 	      g_object_set (proxy,
-			    "label", action->private_data->short_label,
-			    "use-underline", TRUE,
+			    "label", action->private_data->stock_id,
 			    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_ICON_NAME))
-	    gtk_image_set_from_icon_name (GTK_IMAGE (image),
-					  action->private_data->icon_name, GTK_ICON_SIZE_MENU);
+	  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_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,
@@ -1060,6 +1082,37 @@ gtk_action_get_proxies (GtkAction *actio
   return action->private_data->proxies;
 }
 
+/**
+ * gtk_widget_set_action:
+ * @widget: a #GtkWidget
+ * @action: the #GtkAction to register widget as a proxy of.
+ * @update_appearance: whether to allow modifications to the widgets appearance.
+ *
+ * Connects @widget to @action's proxy list
+ *
+ * Since: 2.16
+ */
+void
+gtk_widget_set_action (GtkWidget *widget, 
+		       GtkAction *action,
+		       gboolean   update_appearance)
+{
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (action == NULL || GTK_IS_ACTION (action));
+
+  if (action)
+    {
+      g_object_set_qdata (G_OBJECT (widget), quark_gtk_action_update_appearances,
+			  GINT_TO_POINTER (update_appearance));
+      gtk_action_connect_proxy(action, widget);
+    }
+  else if ((action = gtk_widget_get_action (widget)) != NULL)
+    {
+      gtk_action_disconnect_proxy (action, widget);
+    }
+
+  g_object_notify (G_OBJECT (widget), "action-controller");
+}
 
 /**
  * gtk_widget_get_action:
@@ -1082,6 +1135,72 @@ gtk_widget_get_action (GtkWidget *widget
 }
 
 
+
+/**
+ * gtk_widget_set_action_appearance_updates:
+ * @widget: a #GtkWidget
+ * @update_appearance: whether to allow modifications to the widgets appearance.
+ *
+ * Sets whether the widget's appearance will be modified by the action
+ * that controlls it, call this before calling gtk_widget_set_action() if
+ * you dont want to lose your widget's appearance.
+ *
+ * Since: 2.16
+ */
+void
+gtk_widget_set_action_appearance_updates (GtkWidget *widget, 
+					  gboolean   update_appearance)
+{
+  gboolean updates;
+  GtkAction *action;
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  /* We are working with a default TRUE qdata here... */
+  update_appearance = !update_appearance;
+
+  updates = GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (widget), quark_gtk_action_update_appearances));
+
+  if (updates != update_appearance)
+    {
+      g_object_ref (G_OBJECT (widget));
+      
+      if ((action = gtk_widget_get_action (widget)) != NULL)
+	gtk_widget_set_action (widget, NULL, FALSE);
+
+      g_object_set_qdata (G_OBJECT (widget), quark_gtk_action_update_appearances,
+			  GINT_TO_POINTER (update_appearance));
+
+      if (action)
+	gtk_widget_set_action (widget, action, update_appearance);
+
+      g_object_unref (G_OBJECT (widget));
+
+      g_object_notify (G_OBJECT (widget), "action-controls-appearance");
+    }
+}
+
+
+/**
+ * gtk_widget_get_action_appearance_updates:
+ * @widget: a #GtkWidget
+ *
+ * Checks whether the widget's appearance will be modified by the action
+ * that controlls it.
+ *
+ * Returns: whether the appearance of @widget will be controlled by its controlling action.
+ *
+ * Since: 2.16
+ */
+gboolean
+gtk_widget_get_action_appearance_updates (GtkWidget *widget)
+{
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+  /* We are working with a default TRUE qdata here... */
+  return !GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (widget), quark_gtk_action_update_appearances));
+}
+
+
 /**
  * gtk_action_get_name:
  * @action: the action object
@@ -1339,11 +1458,14 @@ 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_widget_get_action_appearance_updates (proxy))
+	continue;
+
       if (GTK_IS_MENU_ITEM (proxy))
 	{
 	  child = GTK_BIN (proxy)->child;
@@ -1353,7 +1475,7 @@ gtk_action_set_label (GtkAction	  *actio
 				 action->private_data->label);
 	}
     }
-  
+
   g_object_notify (G_OBJECT (action), "label");
   
   /* if short_label is unset, set short_label=label */
@@ -1383,7 +1505,10 @@ gtk_action_set_short_label (GtkAction	*a
   for (p = action->private_data->proxies; p; p = p->next)
     {
       proxy = (GtkWidget *)p->data;
-
+      
+      if (!gtk_widget_get_action_appearance_updates (proxy))
+	continue;
+      
       if (GTK_IS_TOOL_BUTTON (proxy))
 	gtk_tool_button_set_label (GTK_TOOL_BUTTON (proxy),
 				   action->private_data->short_label);
@@ -1391,11 +1516,11 @@ gtk_action_set_short_label (GtkAction	*a
 	       !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),
@@ -1505,6 +1629,9 @@ gtk_action_set_stock_id (GtkAction   *ac
     {
       proxy = (GtkWidget *)p->data;
       
+      if (!gtk_widget_get_action_appearance_updates (proxy))
+	continue;
+      
       if (GTK_IS_IMAGE_MENU_ITEM (proxy))
 	{
 	  image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
@@ -1550,7 +1676,7 @@ gtk_action_set_icon_name (GtkAction   *a
   GSList *p;
   GtkWidget *proxy, *image;
   gchar *tmp;
-  
+
   tmp = action->private_data->icon_name;
   action->private_data->icon_name = g_strdup (icon_name);
   g_free (tmp);
@@ -1558,7 +1685,10 @@ gtk_action_set_icon_name (GtkAction   *a
   for (p = action->private_data->proxies; p; p = p->next)
     {
       proxy = (GtkWidget *)p->data;
-      
+	
+      if (!gtk_widget_get_action_appearance_updates (proxy))
+	continue;
+
       if (GTK_IS_IMAGE_MENU_ITEM (proxy))
 	{
 	  image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
@@ -1586,7 +1716,6 @@ gtk_action_set_icon_name (GtkAction   *a
 					  action->private_data->icon_name, GTK_ICON_SIZE_MENU);
 	}
     }
-  
   g_object_notify (G_OBJECT (action), "icon-name");
 }
 
Index: gtkaction.h
===================================================================
--- gtkaction.h	(revision 21776)
+++ gtkaction.h	(working copy)
@@ -110,12 +110,20 @@ void         gtk_action_connect_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);
 
+void         gtk_widget_set_action             (GtkWidget     *widget,
+						GtkAction     *action,
+						gboolean       update_appearance);
+GtkAction   *gtk_widget_get_action             (GtkWidget     *widget);
+void         gtk_widget_set_action_appearance_updates (GtkWidget *widget,
+						       gboolean   update_appearance);
+gboolean     gtk_widget_get_action_appearance_updates (GtkWidget *widget);
+
+
 /* protected ... for use by child actions */
 void         gtk_action_block_activate_from    (GtkAction     *action,
 						GtkWidget     *proxy);
