Re: Two insights about underline accelerators



On 14 Mar 2001, Owen Taylor wrote:

> [lots of stuff]

I've implemented this now. Here are some general comments about it.

I added an extra argument to gtk_label_set_accel_widget to select if
you want to emit "activate" (and "grab_focus" if overloaded) or just
"grab_focus". I had to do this, because for some label targets
"activate" doesn't make sence (like for a GtkEntry or a GtkNotebook page).

The functions:
 gtk_accel_group_lock_entry()
 gtk_accel_group_unlock_entry()
Are kinda broken as is, since their arguments now doesn't refer to a
unique GtkAccelEntry. These are not currently used at all according to 
my lxr search though.

There are still some questions on the order of accelerators, and exactly
how overloading works. In the patch accelerator groups attached to an
object are activated in this order: first all groups not allowing
conflicts, then all groups allowing conflicts, and then the default group.
This means:
* overloaded accelerators in different accelerator groups are not handled
  well. The group that happens to be first is the only one used.
* menu accelerators in the default accel group "application wide" can be
  overridden by label accelerators. I don't know if this is a problem.

For consistencys sake I renamed gtk_button_new_stock to
gtk_button_new_from_stock and gtk_button_new_accel to
gtk_button_new_with_accel. I also added
then new convinience functions gtk_check_button_new_with_accel and
gtk_label_new_with_accel. 

I didn't implement automatic association of labels with accelerator
widgets, because doing this an always emitting "activate" seems kinda
broken to me? What if the target found was an entry with
set_activates_default set? Then this could close the dialog or something.

gtk_button_from_stock() previosly set up the stock items accelerator too,
but when i removed the accel_group argument to the function i no longer
know where to install the accelerator. Shall i just ignore it, or install
a ::hierarchy_changed handler to automatically find the toplevel window of
the button and use gtk_window_get_default_accel_group()?

gtk_image_menu_item_new_from_stock() still takes an accel_group
argument. This is probably necessary, and is not normally a problem
because you use GtkItemFactory, which has a accel group.

I also found a  general accellabel bug or something. In the itemfactory
test in testgtk there are duplicated of the "Oval" and "Rectangle" in the
"Preferences->Shape" menu. When dynamically changing the accel key for
these the wrong item gets the accel label.

Here is the patch attached. It is kinda large, but I tried to place it in
a somewhat logical order. It starts with the accel group changes, then
using these in windows and lables and whatnot. Then comes the stock
imagemenuitem changes, then stock and imagemenuitem itemfactory changes
and at the end assorted changes to testgtk to test the new features.

Index: gtk/gtkaccelgroup.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkaccelgroup.h,v
retrieving revision 1.9
diff -u -p -r1.9 gtkaccelgroup.h
--- gtk/gtkaccelgroup.h	2000/08/30 00:33:36	1.9
+++ gtk/gtkaccelgroup.h	2001/03/16 14:15:19
@@ -67,6 +67,7 @@ struct _GtkAccelGroup
   guint	          lock_count;
   GdkModifierType modifier_mask;
   GSList         *attach_objects;
+  guint           allow_conflicts : 1;
 };
 
 struct _GtkAccelEntry
@@ -76,12 +77,15 @@ struct _GtkAccelEntry
   GtkAccelGroup		*accel_group;
   guint			 accelerator_key;
   GdkModifierType	 accelerator_mods;
-  
+
   GtkAccelFlags		 accel_flags;
   GtkObject		*object;
   guint			 signal_id;
-};
 
+  /* For extended signals */
+  guint                  extended_signal : 1;
+  gpointer               accel_data;
+};
 
 /* Accelerators
  */
@@ -98,7 +102,7 @@ guint	 gtk_accelerator_get_default_mod_m
 
 /* Accelerator Groups
  */
-GtkAccelGroup*  gtk_accel_group_new	      	(void);
+GtkAccelGroup*  gtk_accel_group_new	      	(gboolean allow_conflicts);
 GtkAccelGroup*  gtk_accel_group_get_default    	(void);
 GtkAccelGroup*  gtk_accel_group_ref	     	(GtkAccelGroup	*accel_group);
 void	        gtk_accel_group_unref	      	(GtkAccelGroup	*accel_group);
@@ -122,7 +126,8 @@ void		gtk_accel_group_detach		(GtkAccelG
  */
 GtkAccelEntry* 	gtk_accel_group_get_entry      	(GtkAccelGroup  *accel_group,
 						 guint           accel_key,
-						 GdkModifierType accel_mods);
+						 GdkModifierType accel_mods,
+						 GtkObject      *object);
 void		gtk_accel_group_lock_entry	(GtkAccelGroup	*accel_group,
 						 guint		 accel_key,
 						 GdkModifierType accel_mods);
Index: gtk/gtkaccelgroup.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkaccelgroup.c,v
retrieving revision 1.20
diff -u -p -r1.20 gtkaccelgroup.c
--- gtk/gtkaccelgroup.c	2000/10/25 22:34:11	1.20
+++ gtk/gtkaccelgroup.c	2001/03/16 14:15:19
@@ -71,8 +71,8 @@ gtk_accel_entries_equal (gconstpointer a
   const GtkAccelEntry *e1;
   const GtkAccelEntry *e2;
   
-  e1 = a;
-  e2 = b;
+  e1 = ((GSList *)a)->data;
+  e2 = ((GSList *)b)->data;
   
   return ((e1->accel_group == e2->accel_group) &&
 	  (e1->accelerator_key == e2->accelerator_key) &&
@@ -85,7 +85,7 @@ gtk_accel_entries_hash (gconstpointer a)
   const GtkAccelEntry *e;
   guint h;
   
-  e = a;
+  e = ((GSList *)a)->data;
   
   h = (gulong) e->accel_group;
   h ^= e->accelerator_key << 16;
@@ -96,7 +96,7 @@ gtk_accel_entries_hash (gconstpointer a)
 }
 
 GtkAccelGroup*
-gtk_accel_group_new (void)
+gtk_accel_group_new (gboolean allow_conflicts)
 {
   GtkAccelGroup *accel_group;
   
@@ -118,6 +118,7 @@ gtk_accel_group_new (void)
   accel_group->lock_count = 0;
   accel_group->modifier_mask = gtk_accelerator_get_default_mod_mask ();
   accel_group->attach_objects = NULL;
+  accel_group->allow_conflicts = allow_conflicts;
   
   return accel_group;
 }
@@ -126,7 +127,7 @@ GtkAccelGroup*
 gtk_accel_group_get_default (void)
 {
   if (!default_accel_group)
-    default_accel_group = gtk_accel_group_new ();
+    default_accel_group = gtk_accel_group_new (FALSE);
   
   return default_accel_group;
 }
@@ -238,36 +239,153 @@ gtk_accel_group_unlock (GtkAccelGroup  *
     accel_group->lock_count -= 1;
 }
 
-static GtkAccelEntry*
+static GSList *
 gtk_accel_group_lookup (GtkAccelGroup	*accel_group,
 			guint		 accel_key,
 			GdkModifierType	 accel_mods)
 {
   GtkAccelEntry key_entry = { 0 };
+  GSList list_elem = { &key_entry, NULL};
   
   key_entry.accel_group = accel_group;
   key_entry.accelerator_key = gdk_keyval_to_lower (accel_key);
   key_entry.accelerator_mods = accel_mods & accel_group->modifier_mask;
   
-  return g_hash_table_lookup (accel_entry_hash_table, &key_entry);
+  return g_hash_table_lookup (accel_entry_hash_table, &list_elem);
 }
 
+static GtkAccelEntry *
+gtk_accel_group_lookup_1st (GtkAccelGroup	*accel_group,
+			    guint		 accel_key,
+			    GdkModifierType	 accel_mods)
+{
+  GSList *list;
+
+  list = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
+
+  if (list)
+    return list->data;
+
+  return NULL;
+}
+
+static GtkAccelEntry *
+gtk_accel_group_lookup_obj (GtkAccelGroup	*accel_group,
+			    guint		 accel_key,
+			    GdkModifierType	 accel_mods,
+			    GtkObject           *object)
+{
+  GSList *list;
+  GtkAccelEntry *entry;
+
+  list = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
+  
+  while (list)
+    {
+      entry = list->data;
+
+      if (entry->object == object)
+	return entry;
+      
+      list = g_slist_next (list);
+    }
+  return NULL;
+}
+
+static void
+gtk_accel_group_hash_insert (GtkAccelEntry *entry)
+{
+  GSList *entry_list;
+  GSList list_elem;
+  
+  list_elem.data = entry;
+
+  entry_list = g_hash_table_lookup (accel_entry_hash_table, &list_elem);
+
+  if (entry_list)
+    g_hash_table_remove (accel_entry_hash_table, entry_list);
+  
+  entry_list = g_slist_prepend (entry_list, entry);
+  
+  g_hash_table_insert (accel_entry_hash_table, entry_list, entry_list);
+}
+
+static void
+gtk_accel_group_hash_remove (GtkAccelEntry *entry)
+{
+  GSList *entry_list;
+  GSList list_elem;
+  
+  list_elem.data = entry;
+
+  entry_list = g_hash_table_lookup (accel_entry_hash_table, &list_elem);
+
+  if (entry_list)
+    {
+      g_hash_table_remove (accel_entry_hash_table, entry_list);
+      entry_list = g_slist_remove (entry_list, entry);
+
+      if (entry_list)
+	{
+	  g_hash_table_insert (accel_entry_hash_table, entry_list, entry_list);
+	}
+    }
+  else
+    g_warning ("Calling gtk_accel_group_hash_remove() with entry not in hashtable\n");
+}
+
 gboolean
 gtk_accel_group_activate (GtkAccelGroup	 *accel_group,
 			  guint		  accel_key,
 			  GdkModifierType accel_mods)
 {
-  GtkAccelEntry *entry;
+  GtkAccelEntry *entry, *choosen_entry;
+  GSList *list, *entry_list;
+  gboolean overloaded;
   
   g_return_val_if_fail (accel_group != NULL, FALSE);
-  
-  entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
-  if (entry && entry->signal_id &&
-      (!GTK_IS_WIDGET (entry->object) || GTK_WIDGET_IS_SENSITIVE (entry->object)))
+
+  choosen_entry = NULL;
+  overloaded = FALSE;
+  entry_list = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
+  list = entry_list;
+  while (list)
+    {
+      entry = list->data;
+
+      if (entry->signal_id &&
+	  (!GTK_IS_WIDGET (entry->object) ||
+	   (GTK_WIDGET_IS_SENSITIVE (entry->object) &&
+	    (!accel_group->allow_conflicts || GTK_WIDGET_MAPPED (entry->object)))))
+	{
+	  if (choosen_entry)
+	    {
+	      overloaded = TRUE;
+	      break;
+	    }
+	  else
+	    choosen_entry = entry;
+	}
+      list = g_slist_next (list);
+    }
+
+
+  if (choosen_entry)
     {
-      gtk_signal_emit (entry->object, entry->signal_id);
+      if (choosen_entry->extended_signal)
+	gtk_signal_emit (choosen_entry->object, choosen_entry->signal_id,
+			 overloaded, choosen_entry->accel_data);
+      else
+	gtk_signal_emit (choosen_entry->object, choosen_entry->signal_id);
+      /* For round robin we should put the activated entry on
+       * the end of the list after activation */
+      g_hash_table_remove (accel_entry_hash_table, entry_list);
+      entry_list = g_slist_remove (entry_list, choosen_entry);
+      entry_list = g_slist_append (entry_list, choosen_entry);
+      g_hash_table_insert (accel_entry_hash_table, entry_list, entry_list);
       return TRUE;
     }
+  
   return FALSE;
 }
 
@@ -276,16 +394,29 @@ gtk_accel_groups_activate (GtkObject	   
 			   guint	     accel_key,
 			   GdkModifierType   accel_mods)
 {
+  GtkAccelGroup *accel_group;
   g_return_val_if_fail (object != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_OBJECT (object), FALSE);
   
   if (gtk_accelerator_valid (accel_key, accel_mods))
     {
       GSList *slist;
-      
+
+      /* First try all non-conflict groups */
+      for (slist = gtk_accel_groups_from_object (object); slist; slist = slist->next)
+	{
+	  accel_group = slist->data;
+	  if (!accel_group->allow_conflicts && gtk_accel_group_activate (accel_group, accel_key, accel_mods))
+	    return TRUE;
+	}
+      /* Then try the groups allowing conflicts */
       for (slist = gtk_accel_groups_from_object (object); slist; slist = slist->next)
-	if (gtk_accel_group_activate (slist->data, accel_key, accel_mods))
-	  return TRUE;
+	{
+	  accel_group = slist->data;
+	  if (accel_group->allow_conflicts && gtk_accel_group_activate (accel_group, accel_key, accel_mods))
+	    return TRUE;
+	}
+      /* Then the default group */
       return gtk_accel_group_activate (gtk_accel_group_get_default (), accel_key, accel_mods);
     }
   
@@ -300,8 +431,10 @@ gtk_accel_group_lock_entry (GtkAccelGrou
   GtkAccelEntry *entry;
   
   g_return_if_fail (accel_group != NULL);
+
+  g_assert_not_reached (); /* TODO: This is broken, entry is a list */
   
-  entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
+  entry = gtk_accel_group_lookup_1st (accel_group, accel_key, accel_mods);
   if (entry)
     entry->accel_flags |= GTK_ACCEL_LOCKED;
 }
@@ -314,8 +447,10 @@ gtk_accel_group_unlock_entry (GtkAccelGr
   GtkAccelEntry *entry;
   
   g_return_if_fail (accel_group != NULL);
-  
-  entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
+
+  g_assert_not_reached (); /* TODO: This is broken, entry is a list */
+
+  entry = gtk_accel_group_lookup_1st (accel_group, accel_key, accel_mods);
   if (entry)
     entry->accel_flags &= ~GTK_ACCEL_LOCKED;
 }
@@ -323,11 +458,12 @@ gtk_accel_group_unlock_entry (GtkAccelGr
 GtkAccelEntry*
 gtk_accel_group_get_entry (GtkAccelGroup    *accel_group,
 			   guint             accel_key,
-			   GdkModifierType   accel_mods)
+			   GdkModifierType   accel_mods,
+			   GtkObject         *object)
 {
   g_return_val_if_fail (accel_group != NULL, 0);
   
-  return gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
+  return gtk_accel_group_lookup_obj (accel_group, accel_key, accel_mods, object);
 }
 
 void
@@ -378,13 +514,16 @@ gtk_accel_group_add (GtkAccelGroup	*acce
       return;
     }
   g_signal_query (accel_signal_id, &query);
-  if (!query.signal_id || query.n_params > 0)
+  if (!query.signal_id ||
+      !(query.n_params == 0 ||
+	(query.n_params == 2 &&
+	 query.param_types[0] == G_TYPE_BOOLEAN &&
+	 query.param_types[1] == G_TYPE_POINTER)))
     {
       g_warning ("gtk_accel_group_add(): signal \"%s\" in the `%s' class ancestry"
 		 "cannot be used as accelerator signal",
 		 accel_signal,
 		 gtk_type_name (GTK_OBJECT_TYPE (object)));
-
       return;
     }
 
@@ -392,8 +531,10 @@ gtk_accel_group_add (GtkAccelGroup	*acce
    */
   if (accel_group->lock_count > 0)
     return;
-  entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
-  if (entry && entry->accel_flags & GTK_ACCEL_LOCKED)
+  
+  entry = gtk_accel_group_lookup_1st (accel_group, accel_key, accel_mods);
+  if (!accel_group->allow_conflicts && entry && 
+      entry->accel_flags & GTK_ACCEL_LOCKED)
     return;
   
   /* make sure our structures stay alive
@@ -401,9 +542,9 @@ gtk_accel_group_add (GtkAccelGroup	*acce
   gtk_accel_group_ref (accel_group);
   gtk_object_ref (object);
   
-  /* remove an existing entry
+  /* remove an existing entry if conflicts not allowed
    */
-  if (entry)
+  if (!accel_group->allow_conflicts && entry)
     gtk_signal_emit (entry->object, remove_accelerator_signal_id,
 		     accel_group,
 		     gdk_keyval_to_lower (accel_key),
@@ -411,8 +552,8 @@ gtk_accel_group_add (GtkAccelGroup	*acce
   
   /* abort if the entry still exists
    */
-  entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
-  if (entry)
+  entry = gtk_accel_group_lookup_1st (accel_group, accel_key, accel_mods);
+  if (!accel_group->allow_conflicts && entry)
     {
       gtk_accel_group_unref (accel_group);
       gtk_object_unref (object);
@@ -420,47 +561,53 @@ gtk_accel_group_add (GtkAccelGroup	*acce
       return;
     }
   
-  /* collect accel groups and remove existing entries
-   */
-  attach_objects = accel_group->attach_objects;
-  groups = NULL;
-  for (attach_objects = accel_group->attach_objects; attach_objects; attach_objects = attach_objects->next)
+  if (!accel_group->allow_conflicts)
     {
-      GSList *tmp_groups;
-      
-      tmp_groups = gtk_object_get_data_by_id (attach_objects->data, accel_groups_key_id);
-      while (tmp_groups)
+      /* collect accel groups and remove existing entries
+       */
+      groups = NULL;
+      for (attach_objects = accel_group->attach_objects; attach_objects; attach_objects = attach_objects->next)
 	{
-	  groups = g_slist_prepend (groups, tmp_groups->data);
-	  gtk_accel_group_ref (tmp_groups->data);
-	  tmp_groups = tmp_groups->next;
+	  GSList *tmp_groups;
+	  
+	  tmp_groups = gtk_object_get_data_by_id (attach_objects->data, accel_groups_key_id);
+	  while (tmp_groups)
+	    {
+	      GtkAccelGroup *tmp_group = tmp_groups->data;
+	      if (!tmp_group->allow_conflicts)
+		{
+		  groups = g_slist_prepend (groups, tmp_group);
+		  gtk_accel_group_ref (tmp_group);
+		}
+	      tmp_groups = tmp_groups->next;
+	    }
 	}
-    }
-  for (slist = groups; slist; slist = slist->next)
-    {
-      GtkAccelGroup *tmp_group;
-      
-      tmp_group = slist->data;
-      
-      /* we only remove the accelerator if neccessary
-       */
-      if (tmp_group->lock_count == 0)
+      for (slist = groups; slist; slist = slist->next)
 	{
-	  entry = gtk_accel_group_lookup (tmp_group, accel_key, accel_mods);
-	  if (entry && !(entry->accel_flags & GTK_ACCEL_LOCKED))
-	    gtk_signal_emit (entry->object, remove_accelerator_signal_id,
-			     tmp_group,
-			     gdk_keyval_to_lower (accel_key),
-			     accel_mods & tmp_group->modifier_mask);
+	  GtkAccelGroup *tmp_group;
+	  
+	  tmp_group = slist->data;
+	  
+	  /* we only remove the accelerator if neccessary
+	   */
+	  if (tmp_group->lock_count == 0)
+	    {
+	      entry = gtk_accel_group_lookup_1st (tmp_group, accel_key, accel_mods);
+	      if (entry && !(entry->accel_flags & GTK_ACCEL_LOCKED))
+		gtk_signal_emit (entry->object, remove_accelerator_signal_id,
+				 tmp_group,
+				 gdk_keyval_to_lower (accel_key),
+				 accel_mods & tmp_group->modifier_mask);
+	    }
+	  gtk_accel_group_unref (tmp_group);
 	}
-      gtk_accel_group_unref (tmp_group);
+      g_slist_free (groups);
     }
-  g_slist_free (groups);
   
   /* now install the new accelerator
    */
-  entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
-  if (!entry)
+  entry = gtk_accel_group_lookup_1st (accel_group, accel_key, accel_mods);
+  if (!entry || accel_group->allow_conflicts)
     gtk_signal_emit (object, add_accelerator_signal_id,
 		     accel_signal_id,
 		     accel_group,
@@ -493,9 +640,10 @@ gtk_accel_group_delete_entries (GtkObjec
       GtkAccelEntry *entry;
       
       entry = slist->data;
-      
-      g_hash_table_remove (accel_entry_hash_table, entry);
+
+      gtk_accel_group_hash_remove (entry);
       gtk_accel_group_unref (entry->accel_group);
+      
       g_chunk_free (entry, accel_entries_mem_chunk);
     }
   g_slist_free (free_slist);
@@ -509,8 +657,11 @@ gtk_accel_group_handle_add (GtkObject	  
 			    GdkModifierType    accel_mods,
 			    GtkAccelFlags      accel_flags)
 {
+  GSList *entry_list;
+  GSList *slist;
   GtkAccelEntry *entry;
-  
+  GSignalQuery query;
+
   g_return_if_fail (object != NULL);
   g_return_if_fail (GTK_IS_OBJECT (object));
   g_return_if_fail (accel_group != NULL);
@@ -519,11 +670,9 @@ gtk_accel_group_handle_add (GtkObject	  
   if (!gtk_accelerator_valid (accel_key, accel_mods))
     return;
   
-  entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
-  if (!entry)
+  entry_list = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
+  if (!entry_list || accel_group->allow_conflicts)
     {
-      GSList *slist;
-      
       gtk_accel_group_ref (accel_group);
       
       entry = g_chunk_new (GtkAccelEntry, accel_entries_mem_chunk);
@@ -534,7 +683,11 @@ gtk_accel_group_handle_add (GtkObject	  
       entry->object = object;
       entry->signal_id = accel_signal_id;
       
-      g_hash_table_insert (accel_entry_hash_table, entry, entry);
+      g_signal_query (accel_signal_id, &query);
+      entry->extended_signal = (query.n_params == 2);
+      entry->accel_data = NULL;
+
+      gtk_accel_group_hash_insert (entry);
       
       slist = gtk_object_get_data_by_id (object, accel_entries_key_id);
       if (!slist)
@@ -576,11 +729,11 @@ gtk_accel_group_remove (GtkAccelGroup	  
    */
   if (accel_group->lock_count > 0)
     return;
-  entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
-  if (!entry ||
-      entry->accel_flags & GTK_ACCEL_LOCKED)
+  entry = gtk_accel_group_lookup_obj (accel_group, accel_key, accel_mods, object);
+  if (entry && entry->accel_flags & GTK_ACCEL_LOCKED)
     return;
-  if (entry->object != object)
+
+  if (!entry || entry->object != object)
     {
       g_warning ("gtk_accel_group_remove(): invalid object reference for accel-group entry");
       return;
@@ -616,35 +769,29 @@ gtk_accel_group_handle_remove (GtkObject
   g_return_if_fail (GTK_IS_OBJECT (object));
   g_return_if_fail (accel_group != NULL);
   
-  entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
+  entry = gtk_accel_group_lookup_obj (accel_group, accel_key, accel_mods, object);
   if (entry)
     {
-      if (entry->object == object)
+      GSList *slist;
+      
+      slist = gtk_object_get_data_by_id (object, accel_entries_key_id);
+      if (slist)
 	{
-	  GSList *slist;
+	  slist = g_slist_remove (slist, entry);
+	  if (!slist)
+	    gtk_signal_disconnect_by_func (object,
+					   GTK_SIGNAL_FUNC (gtk_accel_group_delete_entries),
+					   NULL);
+	  gtk_object_set_data_by_id (object, accel_entries_key_id, slist);
 	  
-	  g_hash_table_remove (accel_entry_hash_table, entry);
 	  
-	  slist = gtk_object_get_data_by_id (object, accel_entries_key_id);
-	  if (slist)
-	    {
-	      slist = g_slist_remove (slist, entry);
-	      if (!slist)
-		gtk_signal_disconnect_by_func (object,
-					       GTK_SIGNAL_FUNC (gtk_accel_group_delete_entries),
-					       NULL);
-	      gtk_object_set_data_by_id (object, accel_entries_key_id, slist);
-	      
-	      gtk_accel_group_unref (accel_group);
-	      
-	      g_chunk_free (entry, accel_entries_mem_chunk);
-	    }
+	  gtk_accel_group_hash_remove (entry);
+	  gtk_accel_group_unref (accel_group);
+	  g_chunk_free (entry, accel_entries_mem_chunk);
 	}
-      else
-	g_warning ("gtk_accel_group_handle_remove(): invalid object reference for accel-group entry");
     }
   else
-    g_warning ("gtk_accel_group_handle_remove(): attempt to remove unexisting accel-group entry");
+    g_warning ("gtk_accel_group_handle_remove(): invalid object reference for accel-group entry");
 }
 
 guint
Index: gtk/gtkwindow.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.h,v
retrieving revision 1.29
diff -u -p -r1.29 gtkwindow.h
--- gtk/gtkwindow.h	2001/03/09 16:43:19	1.29
+++ gtk/gtkwindow.h	2001/03/16 14:15:41
@@ -174,6 +174,7 @@ GList*	   gtk_window_list_toplevels	    
 
 /* Get the "built-in" accel group (convenience thing) */
 GtkAccelGroup* gtk_window_get_default_accel_group (GtkWindow *window);
+GtkAccelGroup* gtk_window_get_default_uline_accel_group (GtkWindow *window);
 
 void     gtk_window_present       (GtkWindow *window);
 void     gtk_window_iconify       (GtkWindow *window);
Index: gtk/gtkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.c,v
retrieving revision 1.104
diff -u -p -r1.104 gtkwindow.c
--- gtk/gtkwindow.c	2001/03/12 21:01:53	1.104
+++ gtk/gtkwindow.c	2001/03/16 14:15:41
@@ -789,10 +789,33 @@ gtk_window_get_default_accel_group (GtkW
 
   if (group == NULL)
     {
-      group = gtk_accel_group_new ();
+      group = gtk_accel_group_new (FALSE);
       gtk_window_add_accel_group (window, group);
       gtk_object_set_data (GTK_OBJECT (window),
                            "gtk-accel-group",
+                           group);
+      gtk_accel_group_unref (group);
+    }
+
+  return group;
+}
+
+GtkAccelGroup*
+gtk_window_get_default_uline_accel_group (GtkWindow *window)
+{
+  GtkAccelGroup *group;
+  
+  g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
+
+  group = gtk_object_get_data (GTK_OBJECT (window),
+                               "gtk-uline-accel-group");
+
+  if (group == NULL)
+    {
+      group = gtk_accel_group_new (TRUE);
+      gtk_window_add_accel_group (window, group);
+      gtk_object_set_data (GTK_OBJECT (window),
+                           "gtk-uline-accel-group",
                            group);
       gtk_accel_group_unref (group);
     }
Index: gtk/gtklabel.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtklabel.h,v
retrieving revision 1.26
diff -u -p -r1.26 gtklabel.h
--- gtk/gtklabel.h	2001/03/07 21:10:44	1.26
+++ gtk/gtklabel.h	2001/03/16 14:15:26
@@ -67,16 +67,23 @@ struct _GtkLabel
   
   PangoLayout *layout;
 
+  GtkWidget *accel_widget;
+  GtkAccelGroup *accel_group;
+  gboolean accel_activate;
+  
   GtkLabelSelectionInfo *select_info;
 };
 
 struct _GtkLabelClass
 {
   GtkMiscClass parent_class;
+
+  void (* run_accelerator) (GtkLabel *label);
 };
 
 GtkType    gtk_label_get_type       (void) G_GNUC_CONST;
 GtkWidget *gtk_label_new            (const char       *str);
+GtkWidget *gtk_label_new_with_accel (const char       *str);
 
 void                  gtk_label_set_text (GtkLabel   *label,
 					  const char *str);
@@ -101,8 +108,13 @@ void       gtk_label_set_line_wrap (GtkL
  * a string with embedded underscores, and return the appropriate
  * key symbol for the accelerator.
  */
-guint       gtk_label_parse_uline   (GtkLabel         *label,
-				     const gchar      *string);
+guint       gtk_label_parse_uline         (GtkLabel         *label,
+					   const gchar      *string);
+guint       gtk_label_set_text_with_accel (GtkLabel         *label,
+					   const gchar      *string);
+void        gtk_label_set_accel_widget    (GtkLabel         *label,
+					   GtkWidget        *widget,
+					   gboolean          activate);
 
 void     gtk_label_set_selectable (GtkLabel *label,
                                    gboolean  setting);
Index: gtk/gtklabel.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtklabel.c,v
retrieving revision 1.79
diff -u -p -r1.79 gtklabel.c
--- gtk/gtklabel.c	2001/03/09 16:43:15	1.79
+++ gtk/gtklabel.c	2001/03/16 14:15:25
@@ -26,6 +26,8 @@
 #include <math.h>
 #include <string.h>
 #include "gtklabel.h"
+#include "gtksignal.h"
+#include "gtkwindow.h"
 #include "gdk/gdkkeysyms.h"
 #include "gtkclipboard.h"
 #include "gdk/gdki18n.h"
@@ -40,6 +42,12 @@ struct _GtkLabelSelectionInfo
 };
 
 enum {
+  RUN_ACCELERATOR,
+  LAST_SIGNAL
+};
+
+
+enum {
   PROP_0,
   PROP_LABEL,
   PROP_ATTRIBUTES,
@@ -52,6 +60,9 @@ enum {
   PROP_ACCEL_KEYVAL
 };
 
+static guint signals[LAST_SIGNAL] = { 0 };
+
+
 static void gtk_label_class_init        (GtkLabelClass    *klass);
 static void gtk_label_init              (GtkLabel         *label);
 static void gtk_label_set_property      (GObject          *object,
@@ -106,6 +117,10 @@ static void set_markup                  
 						  const gchar   *str,
 						  gboolean       with_uline);
 static void gtk_label_recalculate                (GtkLabel      *label);
+static void gtk_label_run_accelerator            (GtkLabel      *label,
+						  gboolean       overloaded,
+						  gpointer       accel_data);
+static void gtk_label_hierarchy_changed          (GtkWidget     *widget);
 
 static void gtk_label_create_window       (GtkLabel *label);
 static void gtk_label_destroy_window      (GtkLabel *label);
@@ -175,7 +190,10 @@ gtk_label_class_init (GtkLabelClass *cla
   widget_class->button_press_event = gtk_label_button_press;
   widget_class->button_release_event = gtk_label_button_release;
   widget_class->motion_notify_event = gtk_label_motion;
+  widget_class->hierarchy_changed = gtk_label_hierarchy_changed;
 
+  class->run_accelerator = gtk_label_run_accelerator;
+  
   g_object_class_install_property (G_OBJECT_CLASS(object_class),
                                    PROP_LABEL,
                                    g_param_spec_string ("label",
@@ -245,6 +263,16 @@ gtk_label_class_init (GtkLabelClass *cla
 						      G_MAXUINT,
 						      GDK_VoidSymbol,
 						      G_PARAM_READABLE));
+
+  signals[RUN_ACCELERATOR] =
+    gtk_signal_new ("run_accelerator",
+		    GTK_RUN_LAST | GTK_RUN_ACTION,
+		    GTK_CLASS_TYPE (object_class),
+		    GTK_SIGNAL_OFFSET (GtkLabelClass, run_accelerator),
+		    gtk_marshal_VOID__BOOLEAN_POINTER,
+		    GTK_TYPE_NONE, 2,
+		    GTK_TYPE_BOOL,
+		    GTK_TYPE_POINTER );
 }
 
 static void 
@@ -355,6 +383,9 @@ gtk_label_init (GtkLabel *label)
   label->layout = NULL;
   label->text = NULL;
   label->attrs = NULL;
+
+  label->accel_widget = NULL;
+  label->accel_group = NULL;
   
   gtk_label_set_text (label, "");
 }
@@ -372,6 +403,115 @@ gtk_label_new (const gchar *str)
   return GTK_WIDGET (label);
 }
 
+GtkWidget*
+gtk_label_new_with_accel (const gchar *str)
+{
+  GtkLabel *label;
+  
+  label = gtk_type_new (GTK_TYPE_LABEL);
+
+  if (str && *str)
+    gtk_label_set_text_with_accel (label, str);
+  
+  return GTK_WIDGET (label);
+}
+
+
+static void
+gtk_label_run_accelerator (GtkLabel *label,
+			   gboolean overloaded,
+			   gpointer accel_data)
+{
+  if (label->accel_widget)
+    {
+      guchar *signal;
+
+      signal = "grab_focus";
+
+      if (!overloaded && label->accel_activate)
+	signal = "activate";
+      
+      gtk_signal_emit_by_name (GTK_OBJECT (label->accel_widget),
+			       signal);
+    }
+}
+
+static void
+gtk_label_setup_accel (GtkLabel *label, guint last_key)
+{
+  GtkAccelGroup *accel_group;
+  GtkWidget *toplevel;
+
+  if ((last_key != GDK_VoidSymbol) && label->accel_group)
+    gtk_widget_remove_accelerator  (GTK_WIDGET (label),
+				    label->accel_group,
+				    last_key,
+				    GDK_MOD1_MASK);
+
+  if (label->accel_group)
+    {
+      gtk_accel_group_unref (label->accel_group);
+      label->accel_group = NULL;
+    }
+  
+  if (label->accel_keyval == GDK_VoidSymbol)
+    return;
+  
+  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (label));
+  
+  if (GTK_IS_WINDOW (toplevel))
+    {
+      accel_group = gtk_window_get_default_uline_accel_group (GTK_WINDOW (toplevel));
+  
+      gtk_widget_add_accelerator (GTK_WIDGET (label),
+				  "run_accelerator",
+				  accel_group,
+				  label->accel_keyval,
+				  GDK_MOD1_MASK,
+				  GTK_ACCEL_LOCKED);
+      
+      label->accel_group = gtk_accel_group_ref (accel_group);
+    }
+}
+
+static void
+gtk_label_hierarchy_changed (GtkWidget *widget)
+{
+  GtkLabel *label = GTK_LABEL (widget);
+  
+  gtk_label_setup_accel (label, label->accel_keyval);
+}
+
+
+/**
+ * gtk_label_set_accel_widget:
+ * @label: a #GtkLabel
+ * @widget: the target #GtkWidget 
+ * @activate: TRUE if the widget should be activated, instead of focused
+ *
+ * If the label has been set so that it has an accelerator key (using i.e.
+ * gtk_label_set_markup_with_accel, gtk_label_set_text_with_accel or
+ * gtk_label_new_with_accel) the label can be associated with a widget that
+ * is the target of the accelerator.
+ *
+ * If @activate is FALSE pressing the accelerator will emit "grab_focus" on
+ * the target widget. If it is TRUE, "activate" will be emitted, unless there
+ * are several accelerators with the same accelerator key, then "grab_focus"
+ * will be emitted.
+ **/
+void
+gtk_label_set_accel_widget (GtkLabel         *label,
+			    GtkWidget        *widget,
+			    gboolean          activate)
+{
+  g_return_if_fail (GTK_IS_LABEL (label));
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  label->accel_widget = widget;
+  label->accel_activate = activate;
+}
+
+
 /**
  * gtk_label_get_accel_keyval:
  * @label: a #GtkLabel
@@ -465,7 +605,11 @@ gtk_label_recalculate (GtkLabel *label)
     }
 
   if (!label->use_underline)
-    label->accel_keyval = GDK_VoidSymbol;
+    {
+      guint keyval = label->accel_keyval;
+      label->accel_keyval = GDK_VoidSymbol;
+      gtk_label_setup_accel (label, keyval);
+    }
 
   gtk_label_clear_layout (label);  
   gtk_widget_queue_resize (GTK_WIDGET (label));
@@ -576,19 +720,25 @@ gtk_label_set_markup (GtkLabel    *label
  * keyval for the first underlined accelerator is returned. If there are
  * no underlines in the text, GDK_VoidSymbol will be returned.
  *
+ * To use the accelerator to activate another widget use gtk_label_set_accel_widget.
+ *
  * Return value: GDK keyval for accelerator
  **/
 guint
 gtk_label_set_markup_with_accel (GtkLabel    *label,
                                  const gchar *str)
 {
+  guint last_keyval;
   g_return_val_if_fail (GTK_IS_LABEL (label), GDK_VoidSymbol);
 
+  last_keyval = label->accel_keyval;
   gtk_label_set_label_internal (label, g_strdup (str ? str : ""));
   gtk_label_set_use_markup_internal (label, TRUE);
   gtk_label_set_use_underline_internal (label, TRUE);
   
   gtk_label_recalculate (label);
+  gtk_label_setup_accel (label, last_keyval);
+  
   return label->accel_keyval;
 }
 
@@ -741,6 +891,9 @@ gtk_label_finalize (GObject *object)
     pango_attr_list_unref (label->attrs);
 
   g_free (label->select_info);
+
+  if (label->accel_group)
+    gtk_accel_group_unref (label->accel_group);
   
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -1214,14 +1367,61 @@ guint      
 gtk_label_parse_uline (GtkLabel    *label,
 		       const gchar *str)
 {
+  guint keyval;
+  guint orig_keyval;
+  
+  g_return_val_if_fail (GTK_IS_LABEL (label), GDK_VoidSymbol);
+  g_return_val_if_fail (str != NULL, GDK_VoidSymbol);
+
+  orig_keyval = label->accel_keyval;
+  
+  gtk_label_set_label_internal (label, g_strdup (str ? str : ""));
+  gtk_label_set_use_markup_internal (label, FALSE);
+  gtk_label_set_use_underline_internal (label, TRUE);
+  
+  gtk_label_recalculate (label);
+
+  keyval = label->accel_keyval;
+  label->accel_keyval = GDK_VoidSymbol;
+  
+  gtk_label_setup_accel (label, orig_keyval);
+  
+  return keyval;
+}
+
+/**
+ * gtk_label_set_text_with_accel:
+ * @label: a #GtkLabel
+ * @str: a string
+ * 
+ * Sets the label's text from the string @str.
+ * If characters in @str are preceded by an underscore, they are underlined
+ * indicating that they represent a keyboard accelerator, and the GDK
+ * keyval for the first underlined accelerator is returned. If there are
+ * no underlines in the text, GDK_VoidSymbol will be returned. To use
+ * the accelerator to activate another widget use gtk_label_set_accel_widget.
+ *
+ * Return value: GDK keyval for accelerator
+ **/
+guint      
+gtk_label_set_text_with_accel (GtkLabel    *label,
+			       const gchar *str)
+{
+  guint last_keyval;
+  
   g_return_val_if_fail (GTK_IS_LABEL (label), GDK_VoidSymbol);
   g_return_val_if_fail (str != NULL, GDK_VoidSymbol);
 
+  last_keyval = label->accel_keyval;
+  
   gtk_label_set_label_internal (label, g_strdup (str ? str : ""));
   gtk_label_set_use_markup_internal (label, FALSE);
   gtk_label_set_use_underline_internal (label, TRUE);
   
   gtk_label_recalculate (label);
+
+  gtk_label_setup_accel (label, last_keyval);
+
   return label->accel_keyval;
 }
 
Index: gtk/gtkbutton.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkbutton.h,v
retrieving revision 1.15
diff -u -p -r1.15 gtkbutton.h
--- gtk/gtkbutton.h	2001/03/06 15:51:09	1.15
+++ gtk/gtkbutton.h	2001/03/16 14:15:20
@@ -79,10 +79,8 @@ struct _GtkButtonClass
 GtkType        gtk_button_get_type       (void) G_GNUC_CONST;
 GtkWidget*     gtk_button_new            (void);
 GtkWidget*     gtk_button_new_with_label (const gchar   *label);
-GtkWidget*     gtk_button_new_stock      (const gchar   *stock_id,
-                                          GtkAccelGroup *accel_group);
-GtkWidget*     gtk_button_new_accel      (const gchar   *uline_label,
-                                          GtkAccelGroup *accel_group);
+GtkWidget*     gtk_button_new_from_stock (const gchar   *stock_id);
+GtkWidget*     gtk_button_new_with_accel (const gchar   *uline_label);
 void           gtk_button_pressed        (GtkButton *button);
 void           gtk_button_released       (GtkButton *button);
 void           gtk_button_clicked        (GtkButton *button);
Index: gtk/gtkbutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkbutton.c,v
retrieving revision 1.54
diff -u -p -r1.54 gtkbutton.c
--- gtk/gtkbutton.c	2001/03/09 13:28:22	1.54
+++ gtk/gtkbutton.c	2001/03/16 14:15:20
@@ -320,8 +320,7 @@ gtk_button_new_with_label (const gchar *
 }
 
 GtkWidget*
-gtk_button_new_stock (const gchar   *stock_id,
-                      GtkAccelGroup *accel_group)
+gtk_button_new_from_stock (const gchar   *stock_id)
 {
   GtkWidget *button;
   GtkStockItem item;
@@ -331,35 +330,26 @@ gtk_button_new_stock (const gchar   *sto
       GtkWidget *label;
       GtkWidget *image;
       GtkWidget *hbox;
-      guint keyval;
       
       button = gtk_button_new ();
 
-      label = gtk_label_new (NULL);
-      keyval = gtk_label_parse_uline (GTK_LABEL (label),
-                                      item.label);
+      label = gtk_label_new_with_accel (item.label);
 
-      if (keyval && accel_group)
-        {
-          gtk_widget_add_accelerator (button,
-                                      "clicked",
-                                      accel_group,
-                                      keyval,
-                                      GDK_MOD1_MASK,
-                                      GTK_ACCEL_LOCKED);
-        }
+      gtk_label_set_accel_widget (GTK_LABEL (label), button, TRUE);
 
+#ifdef TODO
       /* Also add the stock accelerator if one was specified. */
       if (item.keyval && accel_group)
         {
           gtk_widget_add_accelerator (button,
-                                      "clicked",
+                                      "activate",
                                       accel_group,
                                       item.keyval,
                                       item.modifier,
                                       GTK_ACCEL_LOCKED);
         }
-
+#endif
+      
       image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON);
       hbox = gtk_hbox_new (FALSE, 0);
 
@@ -371,34 +361,23 @@ gtk_button_new_stock (const gchar   *sto
     }
   else
     {
-      button = gtk_button_new_accel (stock_id, accel_group);
+      button = gtk_button_new_with_accel (stock_id);
     }
   
   return button;
 }
 
 GtkWidget*
-gtk_button_new_accel (const gchar   *uline_label,
-                      GtkAccelGroup *accel_group)
+gtk_button_new_with_accel (const gchar   *uline_label)
 {
   GtkWidget *button;
   GtkWidget *label;
-  guint keyval;
 
   button = gtk_button_new ();
   
-  label = gtk_label_new (NULL);
-  keyval = gtk_label_parse_uline (GTK_LABEL (label), uline_label);
+  label = gtk_label_new_with_accel (uline_label);
 
-  if (keyval && accel_group)
-    {
-      gtk_widget_add_accelerator (button,
-                                  "clicked",
-                                  accel_group,
-                                  keyval,
-                                  GDK_MOD1_MASK,
-                                  GTK_ACCEL_LOCKED);
-    }
+  gtk_label_set_accel_widget (GTK_LABEL (label), button, TRUE);
   
   gtk_container_add (GTK_CONTAINER (button), label);
   gtk_widget_show (label);
Index: gtk/gtkcheckbutton.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcheckbutton.h,v
retrieving revision 1.7
diff -u -p -r1.7 gtkcheckbutton.h
--- gtk/gtkcheckbutton.h	2000/08/30 00:33:37	1.7
+++ gtk/gtkcheckbutton.h	2001/03/16 14:15:21
@@ -68,6 +68,7 @@ struct _GtkCheckButtonClass
 GtkType    gtk_check_button_get_type       (void) G_GNUC_CONST;
 GtkWidget* gtk_check_button_new            (void);
 GtkWidget* gtk_check_button_new_with_label (const gchar *label);
+GtkWidget* gtk_check_button_new_with_accel (const gchar *label);
 
 
 #ifdef __cplusplus
Index: gtk/gtkcheckbutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcheckbutton.c,v
retrieving revision 1.26
diff -u -p -r1.26 gtkcheckbutton.c
--- gtk/gtkcheckbutton.c	2001/03/09 13:28:23	1.26
+++ gtk/gtkcheckbutton.c	2001/03/16 14:15:21
@@ -123,6 +123,24 @@ gtk_check_button_new_with_label (const g
   return check_button;
 }
 
+GtkWidget*
+gtk_check_button_new_with_accel (const gchar *label)
+{
+  GtkWidget *check_button;
+  GtkWidget *label_widget;
+  
+  check_button = gtk_check_button_new ();
+  label_widget = gtk_label_new_with_accel (label);
+  gtk_label_set_accel_widget (GTK_LABEL (label_widget), check_button, TRUE);
+  gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
+  
+  gtk_container_add (GTK_CONTAINER (check_button), label_widget);
+  gtk_widget_show (label_widget);
+  
+  return check_button;
+}
+
+
 /* This should only be called when toggle_button->draw_indicator
  * is true.
  */
Index: gtk/gtkdialog.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkdialog.c,v
retrieving revision 1.21
diff -u -p -r1.21 gtkdialog.c
--- gtk/gtkdialog.c	2001/03/07 21:32:50	1.21
+++ gtk/gtkdialog.c	2001/03/16 14:15:22
@@ -471,8 +471,7 @@ gtk_dialog_add_button (GtkDialog   *dial
   g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL);
   g_return_val_if_fail (button_text != NULL, NULL);
 
-  button = gtk_button_new_stock (button_text,
-                                 gtk_window_get_default_accel_group (GTK_WINDOW (dialog)));
+  button = gtk_button_new_from_stock (button_text);
 
   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
   
Index: gtk/gtkmarshal.list
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmarshal.list,v
retrieving revision 1.24
diff -u -p -r1.24 gtkmarshal.list
--- gtk/gtkmarshal.list	2001/03/09 14:49:00	1.24
+++ gtk/gtkmarshal.list	2001/03/16 14:15:26
@@ -35,6 +35,7 @@ NONE:NONE
 NONE:POINTER
 NONE:STRING,INT,POINTER
 VOID:BOOLEAN
+VOID:BOOLEAN,POINTER
 VOID:BOXED
 VOID:BOXED,BOXED
 VOID:BOXED,OBJECT
Index: gtk/gtkmenu.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenu.c,v
retrieving revision 1.59
diff -u -p -r1.59 gtkmenu.c
--- gtk/gtkmenu.c	2001/03/09 13:28:25	1.59
+++ gtk/gtkmenu.c	2001/03/16 14:15:30
@@ -752,7 +752,7 @@ gtk_menu_ensure_uline_accel_group (GtkMe
   accel_group = gtk_object_get_data_by_id (GTK_OBJECT (menu), quark_uline_accel_group);
   if (!accel_group)
     {
-      accel_group = gtk_accel_group_new ();
+      accel_group = gtk_accel_group_new (TRUE);
       gtk_accel_group_attach (accel_group, GTK_OBJECT (menu));
       gtk_object_set_data_by_id_full (GTK_OBJECT (menu),
 				      quark_uline_accel_group,
Index: gtk/gtkmenufactory.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenufactory.c,v
retrieving revision 1.12
diff -u -p -r1.12 gtkmenufactory.c
--- gtk/gtkmenufactory.c	2001/02/21 09:29:00	1.12
+++ gtk/gtkmenufactory.c	2001/03/16 14:15:30
@@ -266,7 +266,7 @@ gtk_menu_factory_create (GtkMenuFactory 
 				     &accelerator_key,
 				     &accelerator_mods);
 	      if (!factory->accel_group)
-		factory->accel_group = gtk_accel_group_new ();
+		factory->accel_group = gtk_accel_group_new (FALSE);
 	      
 	      gtk_widget_add_accelerator (menu_path->widget,
 					  "activate",
@@ -323,7 +323,7 @@ gtk_menu_factory_create (GtkMenuFactory 
 	  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_path->widget), menu);
 	  
 	  if (!factory->accel_group)
-	    factory->accel_group = gtk_accel_group_new ();
+	    factory->accel_group = gtk_accel_group_new (FALSE);
 	  gtk_menu_set_accel_group (GTK_MENU (menu), factory->accel_group);
 	}
       
@@ -405,7 +405,7 @@ gtk_menu_factory_make_widget (GtkMenuFac
       widget = gtk_menu_new ();
       
       if (!factory->accel_group)
-	factory->accel_group = gtk_accel_group_new ();
+	factory->accel_group = gtk_accel_group_new (FALSE);
       gtk_menu_set_accel_group (GTK_MENU (widget), factory->accel_group);
       return widget;
     case GTK_MENU_FACTORY_MENU_BAR:
Index: gtk/gtknotebook.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtknotebook.c,v
retrieving revision 1.82
diff -u -p -r1.82 gtknotebook.c
--- gtk/gtknotebook.c	2001/03/09 13:28:25	1.82
+++ gtk/gtknotebook.c	2001/03/16 14:15:33
@@ -94,6 +94,8 @@ struct _GtkNotebookPage
 
   GtkRequisition requisition;
   GtkAllocation allocation;
+
+  guint grab_focus_signal;
 };
 
 #ifdef G_DISABLE_CHECKS
@@ -1977,6 +1979,10 @@ gtk_notebook_real_remove (GtkNotebook *n
   if (page->tab_label)
     gtk_widget_unparent (page->tab_label);
 
+  if (page->grab_focus_signal)
+    gtk_signal_disconnect (page->child,
+			   page->grab_focus_signal);
+  
   if (notebook->menu)
     {
       gtk_container_remove (GTK_CONTAINER (notebook->menu), 
@@ -3618,6 +3624,24 @@ gtk_notebook_insert_page (GtkNotebook *n
   gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, position);
 }
 
+
+static gboolean
+gtk_notebook_grab_focus_switch_page (GtkWidget *child, gpointer data)
+{
+  GtkNotebook *notebook = GTK_NOTEBOOK (data);
+  GtkNotebookPage *page;
+  GList *list;
+
+  list = CHECK_FIND_CHILD (notebook, child);
+  if (!list)  
+    return TRUE;
+
+  page = list->data;
+
+  gtk_notebook_switch_page (notebook, page,  -1);
+  return TRUE;
+}
+
 /**
  * gtk_notebook_insert_page_menu:
  * @notebook: a #GtkNotebook
@@ -3661,6 +3685,7 @@ gtk_notebook_insert_page_menu (GtkNotebo
   page->allocation.height = 0;
   page->default_menu = FALSE;
   page->default_tab = FALSE;
+  page->grab_focus_signal = 0;
    
   nchildren = g_list_length (notebook->children);
   if ((position < 0) || (position > nchildren))
@@ -3741,6 +3766,12 @@ gtk_notebook_insert_page_menu (GtkNotebo
 	    gtk_widget_hide (tab_label);
 	}
     }
+
+  page->grab_focus_signal =
+    gtk_signal_connect (GTK_OBJECT (child),
+			"grab_focus",
+			(GtkSignalFunc) gtk_notebook_grab_focus_switch_page,
+			notebook);
 }
 
 /**
Index: gtk/gtkwidget.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwidget.c,v
retrieving revision 1.193
diff -u -p -r1.193 gtkwidget.c
--- gtk/gtkwidget.c	2001/03/12 18:46:53	1.193
+++ gtk/gtkwidget.c	2001/03/16 14:15:37
@@ -2163,9 +2163,9 @@ gtk_widget_accelerator_signal (GtkWidget
   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
   g_return_val_if_fail (accel_group != NULL, 0);
 
-  ac_entry = gtk_accel_group_get_entry (accel_group, accel_key, accel_mods);
+  ac_entry = gtk_accel_group_get_entry (accel_group, accel_key, accel_mods, GTK_OBJECT (widget));
 
-  if (ac_entry && ac_entry->object == (GtkObject*) widget)
+  if (ac_entry)
     return ac_entry->signal_id;
   return 0;
 }
Index: gtk/testtext.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/testtext.c,v
retrieving revision 1.39
diff -u -p -r1.39 testtext.c
--- gtk/testtext.c	2001/02/19 23:27:27	1.39
+++ gtk/testtext.c	2001/03/16 14:15:50
@@ -2123,7 +2123,7 @@ create_view (Buffer *buffer)
   gtk_signal_connect (GTK_OBJECT (view->window), "delete_event",
 		      GTK_SIGNAL_FUNC (delete_event_cb), NULL);
 
-  view->accel_group = gtk_accel_group_new ();
+  view->accel_group = gtk_accel_group_new (FALSE);
   view->item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", view->accel_group);
   g_object_set_data (G_OBJECT (view->item_factory), "view", view);
   
Index: gtk/gtkimagemenuitem.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkimagemenuitem.h,v
retrieving revision 1.1
diff -u -p -r1.1 gtkimagemenuitem.h
--- gtk/gtkimagemenuitem.h	2001/02/13 05:44:47	1.1
+++ gtk/gtkimagemenuitem.h	2001/03/16 14:15:22
@@ -62,12 +62,14 @@ struct _GtkImageMenuItemClass
 };
 
 
-GtkType	   gtk_image_menu_item_get_type  (void) G_GNUC_CONST;
-GtkWidget* gtk_image_menu_item_new       (GtkWidget        *widget,
-                                          const gchar      *label);
-void       gtk_image_menu_item_add_image (GtkImageMenuItem *image_menu_item,
-                                          GtkWidget        *child);
-GtkWidget* gtk_image_menu_item_get_image (GtkImageMenuItem *image_menu_item);
+GtkType	   gtk_image_menu_item_get_type       (void) G_GNUC_CONST;
+GtkWidget* gtk_image_menu_item_new            (GtkWidget        *widget,
+					       const gchar      *label);
+GtkWidget* gtk_image_menu_item_new_from_stock (const gchar      *stock_id,
+					       GtkAccelGroup    *accel_group);
+void       gtk_image_menu_item_add_image      (GtkImageMenuItem *image_menu_item,
+					       GtkWidget        *child);
+GtkWidget* gtk_image_menu_item_get_image      (GtkImageMenuItem *image_menu_item);
 
 #ifdef __cplusplus
 }
Index: gtk/gtkimagemenuitem.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkimagemenuitem.c,v
retrieving revision 1.4
diff -u -p -r1.4 gtkimagemenuitem.c
--- gtk/gtkimagemenuitem.c	2001/03/09 13:28:25	1.4
+++ gtk/gtkimagemenuitem.c	2001/03/16 14:15:22
@@ -28,6 +28,9 @@
 #include "gtkaccellabel.h"
 #include "gtksignal.h"
 #include "gtkintl.h"
+#include "gtkstock.h"
+#include "gtkiconfactory.h"
+#include "gtkimage.h"
 
 static void gtk_image_menu_item_class_init           (GtkImageMenuItemClass *klass);
 static void gtk_image_menu_item_init                 (GtkImageMenuItem      *image_menu_item);
@@ -357,6 +360,37 @@ gtk_image_menu_item_new (GtkWidget   *wi
     gtk_image_menu_item_add_image (image_menu_item, widget);
   
   return GTK_WIDGET(image_menu_item);
+}
+
+GtkWidget*
+gtk_image_menu_item_new_from_stock (const gchar      *stock_id,
+				    GtkAccelGroup    *accel_group)
+{
+  GtkWidget *image;
+  GtkStockItem stock_item;
+  GtkWidget *item;
+
+  g_return_val_if_fail (stock_id != NULL, NULL);
+
+  image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
+
+  if (gtk_stock_lookup (stock_id, &stock_item))
+    {
+      item = gtk_image_menu_item_new (image, stock_item.label);
+      
+      if (stock_item.keyval && accel_group)
+	gtk_widget_add_accelerator (item,
+				    "activate",
+				    accel_group,
+				    stock_item.keyval,
+				    stock_item.modifier,
+				    GTK_ACCEL_VISIBLE);
+    }
+  else
+    item = gtk_image_menu_item_new (image, stock_id);
+  
+  gtk_widget_show (image);
+  return item;
 }
 
 void
Index: gtk/gtkitemfactory.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkitemfactory.h,v
retrieving revision 1.18
diff -u -p -r1.18 gtkitemfactory.h
--- gtk/gtkitemfactory.h	2000/08/30 00:33:37	1.18
+++ gtk/gtkitemfactory.h	2001/03/16 14:15:24
@@ -110,6 +110,13 @@ struct _GtkItemFactoryEntry
    * "<LastBranch>"	-> create a right justified item to hold sub items
    */
   gchar		 *item_type;
+
+  /* Extra data for some item types:
+   *  ImageItem  -> pointer to inline pixbuf + inline pixbuf length
+   *  StockItem  -> name of stock item
+   */
+  gpointer extra_data;
+  guint    extra_data2;
 };
 
 struct _GtkItemFactoryItem
Index: gtk/gtkitemfactory.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkitemfactory.c,v
retrieving revision 1.33
diff -u -p -r1.33 gtkitemfactory.c
--- gtk/gtkitemfactory.c	2001/03/07 14:49:19	1.33
+++ gtk/gtkitemfactory.c	2001/03/16 14:15:23
@@ -37,9 +37,13 @@
 #include	"gtk/gtkmenuitem.h"
 #include	"gtk/gtkradiomenuitem.h"
 #include	"gtk/gtkcheckmenuitem.h"
+#include	"gtk/gtkimagemenuitem.h"
 #include	"gtk/gtktearoffmenuitem.h"
 #include	"gtk/gtkaccellabel.h"
 #include        "gdk/gdkkeysyms.h"
+#include	"gtk/gtkimage.h"
+#include	"gtk/gtkstock.h"
+#include	"gtk/gtkiconfactory.h"
 #include	<string.h>
 #include	<sys/stat.h>
 #include	<fcntl.h>
@@ -105,6 +109,8 @@ static GQuark		 quark_type_title = 0;
 static GQuark		 quark_type_radio_item = 0;
 static GQuark		 quark_type_check_item = 0;
 static GQuark		 quark_type_toggle_item = 0;
+static GQuark		 quark_type_image_item = 0;
+static GQuark		 quark_type_stock_item = 0;
 static GQuark		 quark_type_tearoff_item = 0;
 static GQuark		 quark_type_separator_item = 0;
 static GQuark		 quark_type_branch = 0;
@@ -220,6 +226,8 @@ gtk_item_factory_class_init (GtkItemFact
   quark_type_radio_item		= g_quark_from_static_string ("<RadioItem>");
   quark_type_check_item		= g_quark_from_static_string ("<CheckItem>");
   quark_type_toggle_item	= g_quark_from_static_string ("<ToggleItem>");
+  quark_type_image_item         = g_quark_from_static_string ("<ImageItem>");
+  quark_type_stock_item         = g_quark_from_static_string ("<StockItem>");
   quark_type_tearoff_item	= g_quark_from_static_string ("<Tearoff>");
   quark_type_separator_item	= g_quark_from_static_string ("<Separator>");
   quark_type_branch		= g_quark_from_static_string ("<Branch>");
@@ -593,7 +601,7 @@ gtk_item_factory_construct (GtkItemFacto
       gtk_accel_group_ref (ifactory->accel_group);
     }
   else
-    ifactory->accel_group = gtk_accel_group_new ();
+    ifactory->accel_group = gtk_accel_group_new (FALSE);
 
   ifactory->path = g_strdup (path);
   ifactory->widget = g_object_connect (gtk_widget_new (container_type, NULL),
@@ -1000,15 +1008,18 @@ gtk_item_factory_create_item (GtkItemFac
   GtkOptionMenu *option_menu = NULL;
   GtkWidget *parent;
   GtkWidget *widget;
+  GtkWidget *image;
   GSList *radio_group;
   gchar *name;
   gchar *parent_path;
   gchar *path;
+  gchar *accelerator;
   guint accel_key;
   guint type_id;
   GtkType type;
   gchar *item_type_path;
-
+  GtkStockItem stock_item;
+      
   g_return_if_fail (ifactory != NULL);
   g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory));
   g_return_if_fail (entry != NULL);
@@ -1037,6 +1048,10 @@ gtk_item_factory_create_item (GtkItemFac
     type = GTK_TYPE_RADIO_MENU_ITEM;
   else if (type_id == quark_type_check_item)
     type = GTK_TYPE_CHECK_MENU_ITEM;
+  else if (type_id == quark_type_image_item)
+    type = GTK_TYPE_IMAGE_MENU_ITEM;
+  else if (type_id == quark_type_stock_item)
+    type = GTK_TYPE_IMAGE_MENU_ITEM;
   else if (type_id == quark_type_tearoff_item)
     type = GTK_TYPE_TEAROFF_MENU_ITEM;
   else if (type_id == quark_type_toggle_item)
@@ -1104,6 +1119,8 @@ gtk_item_factory_create_item (GtkItemFac
 			      
   g_return_if_fail (GTK_IS_CONTAINER (parent));
 
+  accelerator = entry->accelerator;
+  
   widget = gtk_widget_new (type,
 			   "GtkWidget::visible", TRUE,
 			   "GtkWidget::sensitive", (type_id != quark_type_separator_item &&
@@ -1117,7 +1134,40 @@ gtk_item_factory_create_item (GtkItemFac
     gtk_radio_menu_item_set_group (GTK_RADIO_MENU_ITEM (widget), radio_group);
   if (GTK_IS_CHECK_MENU_ITEM (widget))
     gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (widget), TRUE);
+  if (GTK_IS_IMAGE_MENU_ITEM (widget))
+    {
+      GdkPixbuf *pixbuf = NULL;
+      image = NULL;
+
+      pixbuf = gdk_pixbuf_new_from_inline (entry->extra_data,
+					   FALSE,
+					   entry->extra_data2,
+					   NULL);
 
+      if (pixbuf)
+	image = gtk_image_new_from_pixbuf (pixbuf);
+
+      if (image)
+	gtk_image_menu_item_add_image (GTK_IMAGE_MENU_ITEM (widget), image);
+
+      if (pixbuf)
+	g_object_unref (G_OBJECT (pixbuf));
+    }
+  if (type_id == quark_type_stock_item)
+    {
+      image = gtk_image_new_from_stock (entry->extra_data, GTK_ICON_SIZE_MENU);
+      if (image)
+	gtk_image_menu_item_add_image (GTK_IMAGE_MENU_ITEM (widget), image);
+      
+      if (gtk_stock_lookup (entry->extra_data, &stock_item))
+	{
+	  if (!accelerator)
+	    accelerator = gtk_accelerator_name (stock_item.keyval, stock_item.modifier);
+	}
+    }
+  
+  
+
   /* install underline accelerators for this item
    */
   if (type_id != quark_type_separator_item && 
@@ -1173,7 +1223,7 @@ gtk_item_factory_create_item (GtkItemFac
     }	   
   
   gtk_item_factory_add_item (ifactory,
-			     path, entry->accelerator,
+			     path, accelerator,
 			     (type_id == quark_type_branch ||
 			      type_id == quark_type_last_branch) ?
 			      (GtkItemFactoryCallback) NULL : entry->callback,
@@ -1182,6 +1232,9 @@ gtk_item_factory_create_item (GtkItemFac
 			     item_type_path,
 			     widget);
 
+  if (accelerator != entry->accelerator)
+    g_free (accelerator);
+  
   g_free (path);
 }
 
Index: gtk/testgtk.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/testgtk.c,v
retrieving revision 1.228
diff -u -p -r1.228 testgtk.c
--- gtk/testgtk.c	2001/03/08 17:13:11	1.228
+++ gtk/testgtk.c	2001/03/16 14:15:48
@@ -189,13 +189,13 @@ create_buttons (void)
       gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
 
       button[0] = gtk_button_new_with_label ("button1");
-      button[1] = gtk_button_new_accel ("_button2", accel_group);
-      button[2] = gtk_button_new_with_label ("button3");
-      button[3] = gtk_button_new_stock (GTK_STOCK_BUTTON_OK, NULL);
+      button[1] = gtk_button_new_with_accel ("_button2");
+      button[2] = gtk_button_new_with_accel ("_button3");
+      button[3] = gtk_button_new_from_stock (GTK_STOCK_BUTTON_OK);
       button[4] = gtk_button_new_with_label ("button5");
       button[5] = gtk_button_new_with_label ("button6");
       button[6] = gtk_button_new_with_label ("button7");
-      button[7] = gtk_button_new_stock (GTK_STOCK_BUTTON_CLOSE, accel_group);
+      button[7] = gtk_button_new_from_stock (GTK_STOCK_BUTTON_CLOSE);
       button[8] = gtk_button_new_with_label ("button9");
       
       gtk_signal_connect (GTK_OBJECT (button[0]), "clicked",
@@ -630,7 +630,22 @@ new_pixmap (char      *filename,
   return wpixmap;
 }
 
+
+static void
+set_toolbar_small_stock (GtkWidget *widget,
+			 gpointer   data)
+{
+  gtk_toolbar_set_icon_size (GTK_TOOLBAR (data), GTK_ICON_SIZE_SMALL_TOOLBAR);
+}
+
 static void
+set_toolbar_large_stock (GtkWidget *widget,
+			 gpointer   data)
+{
+  gtk_toolbar_set_icon_size (GTK_TOOLBAR (data), GTK_ICON_SIZE_LARGE_TOOLBAR);
+}
+
+static void
 set_toolbar_horizontal (GtkWidget *widget,
 			gpointer   data)
 {
@@ -751,6 +766,16 @@ create_toolbar (void)
       toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH);
       gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_NONE);
 
+      gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
+				GTK_STOCK_NEW,
+				"Stock icon: New", "Toolbar/New",
+				(GtkSignalFunc) set_toolbar_small_stock, toolbar, -1);
+      
+      gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
+				GTK_STOCK_OPEN,
+				"Stock icon: Open", "Toolbar/Open",
+				(GtkSignalFunc) set_toolbar_large_stock, toolbar, -1);
+      
       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
 			       "Horizontal", "Horizontal toolbar layout", "Toolbar/Horizontal",
 			       new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
@@ -1022,9 +1047,18 @@ create_statusbar (void)
 			       "visible", TRUE,
 			       "parent", box2,
 			       NULL);
-      g_object_connect (G_OBJECT (button),
-			"signal::clicked", statusbar_push, statusbar,
-			NULL);
+      g_object_set (G_OBJECT (button),
+		    "signal::clicked", statusbar_push, statusbar,
+		    NULL);
+
+      button = gtk_widget_new (gtk_button_get_type (),
+			       "label", "pop",
+			       "visible", TRUE,
+			       "parent", box2,
+			       NULL);
+      g_object_set (G_OBJECT (button),
+		    "signal::clicked", statusbar_pop, statusbar,
+		    NULL);
 
       button = g_object_connect (gtk_widget_new (gtk_button_get_type (),
 						 "label", "pop",
@@ -2108,16 +2142,16 @@ void create_labels (void)
       gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
       gtk_container_set_border_width (GTK_CONTAINER (window), 5);
 
-      frame = gtk_frame_new ("Normal Label");
+      frame = gtk_frame_new (NULL);//"Normal Label");
       label = gtk_label_new ("This is a Normal label");
       gtk_container_add (GTK_CONTAINER (frame), label);
       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
 
-      frame = gtk_frame_new ("Multi-line Label");
+      frame = gtk_frame_new (NULL);//"Multi-line Label");
       label = gtk_label_new ("This is a Multi-line label.\nSecond line\nThird line");
       gtk_container_add (GTK_CONTAINER (frame), label);
       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
-
+      
       frame = gtk_frame_new ("Left Justified Label");
       label = gtk_label_new ("This is a Left-Justified\nMulti-line label.\nThird      line");
       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
@@ -2797,7 +2831,7 @@ create_menu (gint depth, gint length, gb
   menuitem = gtk_image_menu_item_new (image, "Image item");
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
   gtk_widget_show (menuitem);
-  
+
   for (i = 0, j = 1; i < length; i++, j++)
     {
       sprintf (buf, "item %2d - %d", depth, j);
@@ -2851,9 +2885,9 @@ create_menus (void)
 			  GTK_SIGNAL_FUNC (gtk_true),
 			  NULL);
       
-      accel_group = gtk_accel_group_new ();
+      accel_group = gtk_accel_group_new (FALSE);
       gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
-
+      
       gtk_window_set_title (GTK_WINDOW (window), "menus");
       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
       
@@ -2872,7 +2906,8 @@ create_menus (void)
       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
       gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
       gtk_widget_show (menuitem);
-      
+
+
       menuitem = gtk_menu_item_new_with_label ("foo");
       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (3, 5, TRUE));
       gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
@@ -2886,6 +2921,7 @@ create_menus (void)
       gtk_menu_item_right_justify (GTK_MENU_ITEM (menuitem));
       gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
       gtk_widget_show (menuitem);
+
       
       box2 = gtk_vbox_new (FALSE, 10);
       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
@@ -2895,6 +2931,10 @@ create_menus (void)
       menu = create_menu (1, 5, FALSE);
       gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
 
+      menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_NEW, accel_group);
+      gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+      gtk_widget_show (menuitem);
+      
       menuitem = gtk_check_menu_item_new_with_label ("Accelerate Me");
       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
       gtk_widget_show (menuitem);
@@ -2945,7 +2985,7 @@ create_menus (void)
       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
       gtk_widget_show (box2);
 
-      button = gtk_button_new_with_label ("close");
+      button = gtk_button_new_with_accel ("_close");
       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
 				 GTK_SIGNAL_FUNC(gtk_widget_destroy),
 				 GTK_OBJECT (window));
@@ -2969,16 +3009,129 @@ gtk_ifactory_cb (gpointer             ca
   g_message ("ItemFactory: activated \"%s\"", gtk_item_factory_path_from_widget (widget));
 }
 
+/* This file was automatically generated by the make-inline-pixbuf program.
+ * It contains inline RGB image data.
+ */
+static const guchar apple[] =
+{
+  /* File magic (1197763408) */
+  0x47, 0x64, 0x6b, 0x50,
+  /* Format of following stuff (0) */
+  0x00, 0x00, 0x00, 0x00,
+  /* Rowstride (64) */
+  0x00, 0x00, 0x00, 0x40,
+  /* Width (16) */
+  0x00, 0x00, 0x00, 0x10,
+  /* Height (16) */
+  0x00, 0x00, 0x00, 0x10,
+  /* Has an alpha channel (TRUE) */
+  0x01,
+  /* Colorspace (0 == RGB, no other options implemented) (0) */
+  0x00, 0x00, 0x00, 0x00,
+  /* Number of channels (4) */
+  0x00, 0x00, 0x00, 0x04,
+  /* Bits per sample (8) */
+  0x00, 0x00, 0x00, 0x08,
+  /* Image data */
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x16, 0x14, 0x0f, 0x04,
+  0x00, 0x00, 0x00, 0x01,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x61, 0x6d, 0x5b, 0x2b,  0x6e, 0x7c, 0x61, 0xd9,
+  0x71, 0x80, 0x63, 0xd7,  0x5f, 0x6b, 0x5b, 0x35,  0x00, 0x00, 0x00, 0x00,
+  0x3a, 0x35, 0x28, 0x8f,  0x00, 0x00, 0x00, 0x32,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x60, 0x6c, 0x5c, 0x07,  0x6d, 0x7b, 0x61, 0xd8,
+  0x75, 0x84, 0x65, 0xf6,  0x76, 0x86, 0x66, 0xf7,  0x6a, 0x77, 0x60, 0xec,
+  0x5e, 0x6a, 0x58, 0x47,  0x1c, 0x1a, 0x13, 0xa2,  0x4b, 0x47, 0x30, 0x07,
+  0x55, 0x4e, 0x33, 0x21,  0x48, 0x3e, 0x2a, 0x08,  0xd0, 0xb8, 0x84, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x69, 0x76, 0x5f, 0x74,
+  0x75, 0x84, 0x65, 0xf3,  0x67, 0x75, 0x5e, 0xc4,  0x69, 0x62, 0x55, 0x75,
+  0x94, 0x50, 0x50, 0x69,  0x75, 0x5c, 0x52, 0xb2,  0x69, 0x38, 0x34, 0xa2,
+  0xa7, 0x5b, 0x53, 0xea,  0xa3, 0x52, 0x4f, 0xff,  0x90, 0x47, 0x42, 0xfa,
+  0x76, 0x44, 0x36, 0xb9,  0x59, 0x38, 0x29, 0x3c,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x5f, 0x6b, 0x5a, 0x09,
+  0x69, 0x76, 0x5e, 0xb0,  0x5f, 0x6b, 0x59, 0x57,  0x9a, 0x4b, 0x4d, 0x5b,
+  0xb8, 0x5f, 0x63, 0xfa,  0xcc, 0x7d, 0x7e, 0xff,  0xc5, 0x69, 0x68, 0xff,
+  0xc7, 0x6b, 0x67, 0xff,  0xc5, 0x6f, 0x67, 0xff,  0xba, 0x5e, 0x5a, 0xff,
+  0xb1, 0x4d, 0x4d, 0xff,  0x92, 0x4b, 0x42, 0xff,  0x6a, 0x3e, 0x30, 0xfc,
+  0x5c, 0x3b, 0x27, 0x6d,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x5d, 0x69, 0x57, 0x09,  0x5d, 0x69, 0x57, 0x09,  0x92, 0x47, 0x46, 0x1e,
+  0xba, 0x65, 0x64, 0xf4,  0xe7, 0xbf, 0xc0, 0xff,  0xdf, 0xa5, 0xa3, 0xff,
+  0xd4, 0x84, 0x81, 0xff,  0xd1, 0x7c, 0x76, 0xff,  0xc9, 0x78, 0x6d, 0xff,
+  0xbb, 0x6a, 0x5d, 0xff,  0xb3, 0x5a, 0x52, 0xff,  0x9f, 0x4b, 0x47, 0xff,
+  0x78, 0x45, 0x35, 0xff,  0x5f, 0x3c, 0x28, 0xfa,  0x53, 0x5a, 0x38, 0x24,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0xa1, 0x54, 0x4d, 0x8c,  0xcf, 0x8e, 0x89, 0xff,  0xe3, 0xb1, 0xae, 0xff,
+  0xd8, 0x94, 0x8e, 0xff,  0xd3, 0x8a, 0x82, 0xff,  0xcf, 0x80, 0x76, 0xff,
+  0xc4, 0x75, 0x67, 0xff,  0xb7, 0x6c, 0x5c, 0xff,  0xab, 0x5e, 0x51, 0xff,
+  0x9c, 0x4c, 0x46, 0xff,  0x7e, 0x4a, 0x3a, 0xff,  0x5c, 0x3c, 0x26, 0xff,
+  0x58, 0x3d, 0x28, 0x55,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0xa2, 0x59, 0x4f, 0xc3,  0xcd, 0x8e, 0x88, 0xff,
+  0xd3, 0x93, 0x8c, 0xff,  0xd0, 0x8c, 0x83, 0xff,  0xcc, 0x84, 0x79, 0xff,
+  0xc7, 0x7c, 0x6e, 0xff,  0xbc, 0x73, 0x61, 0xff,  0xb1, 0x6b, 0x59, 0xff,
+  0xa3, 0x5f, 0x4f, 0xff,  0x93, 0x50, 0x44, 0xff,  0x78, 0x48, 0x35, 0xff,
+  0x59, 0x3b, 0x25, 0xff,  0x4f, 0x3d, 0x28, 0x4f,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x9b, 0x5b, 0x4d, 0xbc,
+  0xbd, 0x7e, 0x72, 0xff,  0xc6, 0x86, 0x7a, 0xff,  0xc5, 0x7f, 0x72, 0xff,
+  0xc2, 0x7b, 0x6c, 0xff,  0xbf, 0x77, 0x63, 0xff,  0xb7, 0x72, 0x5b, 0xff,
+  0xa9, 0x6b, 0x53, 0xff,  0x9a, 0x60, 0x4b, 0xff,  0x8b, 0x56, 0x41, 0xff,
+  0x6a, 0x44, 0x2e, 0xff,  0x53, 0x38, 0x21, 0xfd,  0x42, 0x4b, 0x2e, 0x1a,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x8e, 0x57, 0x48, 0x6e,  0xa6, 0x6b, 0x5a, 0xff,  0xb3, 0x74, 0x62, 0xff,
+  0xb8, 0x75, 0x61, 0xff,  0xba, 0x76, 0x61, 0xff,  0xb7, 0x74, 0x5c, 0xff,
+  0xae, 0x6e, 0x54, 0xff,  0x9f, 0x67, 0x4c, 0xff,  0x90, 0x5d, 0x43, 0xff,
+  0x79, 0x4d, 0x38, 0xff,  0x5c, 0x3d, 0x25, 0xff,  0x50, 0x39, 0x23, 0xb8,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x78, 0x52, 0x43, 0x07,  0x92, 0x5c, 0x47, 0xdc,
+  0x9e, 0x64, 0x4e, 0xff,  0xa8, 0x6b, 0x52, 0xff,  0xaa, 0x6d, 0x53, 0xff,
+  0xa7, 0x6d, 0x50, 0xff,  0x9c, 0x67, 0x4a, 0xff,  0x8e, 0x5d, 0x41, 0xff,
+  0x7d, 0x54, 0x3a, 0xff,  0x6a, 0x4b, 0x32, 0xff,  0x51, 0x39, 0x23, 0xff,
+  0x28, 0x20, 0x12, 0x77,  0x00, 0x00, 0x00, 0x12,  0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x03,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x6f, 0x4a, 0x37, 0x2a,  0x81, 0x54, 0x3d, 0xec,  0x8b, 0x5a, 0x41, 0xff,
+  0x8b, 0x5a, 0x3f, 0xff,  0x85, 0x56, 0x3c, 0xff,  0x7d, 0x52, 0x38, 0xff,
+  0x77, 0x51, 0x33, 0xff,  0x6f, 0x4e, 0x34, 0xff,  0x5f, 0x45, 0x2c, 0xff,
+  0x2e, 0x21, 0x14, 0xff,  0x00, 0x00, 0x00, 0xf8,  0x00, 0x00, 0x00, 0x92,
+  0x00, 0x00, 0x00, 0x0e,  0x00, 0x00, 0x00, 0x04,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x14,  0x11, 0x0b, 0x08, 0xb4,
+  0x50, 0x37, 0x25, 0xfe,  0x6d, 0x49, 0x2f, 0xff,  0x52, 0x37, 0x22, 0xff,
+  0x50, 0x37, 0x21, 0xff,  0x66, 0x45, 0x2b, 0xff,  0x60, 0x46, 0x2c, 0xff,
+  0x2d, 0x22, 0x16, 0xff,  0x00, 0x00, 0x00, 0xfe,  0x00, 0x00, 0x00, 0xd2,
+  0x00, 0x00, 0x00, 0x63,  0x00, 0x00, 0x00, 0x07,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x22,  0x00, 0x00, 0x00, 0x64,  0x09, 0x0a, 0x07, 0xa4,
+  0x00, 0x00, 0x00, 0xbd,  0x00, 0x00, 0x00, 0xbe,  0x00, 0x00, 0x00, 0xc4,
+  0x00, 0x00, 0x00, 0xb8,  0x00, 0x00, 0x00, 0x9d,  0x00, 0x00, 0x00, 0x6c,
+  0x00, 0x00, 0x00, 0x2c,  0x00, 0x00, 0x00, 0x07,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x05,  0x00, 0x00, 0x00, 0x0b,  0x00, 0x00, 0x00, 0x0d,
+  0x00, 0x00, 0x00, 0x0b,  0x00, 0x00, 0x00, 0x08,  0x00, 0x00, 0x00, 0x06,
+  0x00, 0x00, 0x00, 0x02,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+
 static GtkItemFactoryEntry menu_items[] =
 {
   { "/_File",            NULL,         0,                     0, "<Branch>" },
   { "/File/tearoff1",    NULL,         gtk_ifactory_cb,       0, "<Tearoff>" },
-  { "/File/_New",        "<control>N", gtk_ifactory_cb,       0 },
-  { "/File/_Open",       "<control>O", gtk_ifactory_cb,       0 },
-  { "/File/_Save",       "<control>S", gtk_ifactory_cb,       0 },
-  { "/File/Save _As...", NULL,         gtk_ifactory_cb,       0 },
+  { "/File/_New",        NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_NEW },
+  { "/File/_Open",       NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_OPEN },
+  { "/File/_Save",       NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_SAVE },
+  { "/File/Save _As...", "<control>A", gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_SAVE },
   { "/File/sep1",        NULL,         gtk_ifactory_cb,       0, "<Separator>" },
-  { "/File/_Quit",       "<control>Q", gtk_ifactory_cb,       0 },
+  { "/File/_Quit",       NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_QUIT },
 
   { "/_Preferences",     		NULL, 0,               0, "<Branch>" },
   { "/_Preferences/_Color", 		NULL, 0,               0, "<Branch>" },
@@ -2991,6 +3144,7 @@ static GtkItemFactoryEntry menu_items[] 
   { "/_Preferences/Shape/_Oval",        NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Rectangle" },
   { "/_Preferences/Shape/_Rectangle",   NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Square" },
   { "/_Preferences/Shape/_Oval",        NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Rectangle" },
+  { "/_Preferences/Shape/_Image",       NULL, gtk_ifactory_cb, 0, "<ImageItem>", apple, sizeof(apple) },
 
   /* For testing deletion of menus */
   { "/_Preferences/Should_NotAppear",          NULL, 0,               0, "<Branch>" },
@@ -2998,6 +3152,7 @@ static GtkItemFactoryEntry menu_items[] 
   { "/Preferences/ShouldNotAppear/SubItem2",   NULL, gtk_ifactory_cb, 0 },
 
   { "/_Help",            NULL,         0,                     0, "<LastBranch>" },
+  { "/Help/_Help",       NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_HELP},
   { "/Help/_About",      NULL,         gtk_ifactory_cb,       0 },
 };
 
@@ -3028,7 +3183,7 @@ create_item_factory (void)
 			  GTK_SIGNAL_FUNC (gtk_true),
 			  NULL);
       
-      accel_group = gtk_accel_group_new ();
+      accel_group = gtk_accel_group_new (FALSE);
       item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);
       gtk_object_set_data_full (GTK_OBJECT (window),
 				"<main>",
@@ -3066,7 +3221,7 @@ create_item_factory (void)
       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
 
-      button = gtk_button_new_with_label ("close");
+      button = gtk_button_new_with_accel ("_close");
       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
 				 GTK_SIGNAL_FUNC(gtk_widget_destroy),
 				 GTK_OBJECT (window));
@@ -5564,35 +5719,38 @@ void create_ctree (void)
       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
       
-      label = gtk_label_new ("Depth :");
+      label = gtk_label_new_with_accel ("De_pth :");
       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
       
       adj = (GtkAdjustment *) gtk_adjustment_new (4, 1, 10, 1, 5, 0);
       spin1 = gtk_spin_button_new (adj, 0, 0);
+      gtk_label_set_accel_widget (label, spin1, FALSE);
       gtk_box_pack_start (GTK_BOX (hbox), spin1, FALSE, TRUE, 5);
   
-      label = gtk_label_new ("Books :");
+      label = gtk_label_new_with_accel ("_Books :");
       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
       
       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
       spin2 = gtk_spin_button_new (adj, 0, 0);
+      gtk_label_set_accel_widget (label, spin2, FALSE);
       gtk_box_pack_start (GTK_BOX (hbox), spin2, FALSE, TRUE, 5);
 
-      label = gtk_label_new ("Pages :");
+      label = gtk_label_new_with_accel ("_Pages :");
       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
       
       adj = (GtkAdjustment *) gtk_adjustment_new (5, 1, 20, 1, 5, 0);
       spin3 = gtk_spin_button_new (adj, 0, 0);
+      gtk_label_set_accel_widget (label, spin3, FALSE);
       gtk_box_pack_start (GTK_BOX (hbox), spin3, FALSE, TRUE, 5);
 
-      button = gtk_button_new_with_label ("Close");
+      button = gtk_button_new_with_accel ("C_lose");
       gtk_box_pack_end (GTK_BOX (hbox), button, TRUE, TRUE, 0);
 
       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
 				 (GtkSignalFunc) gtk_widget_destroy,
 				 GTK_OBJECT(window));
 
-      button = gtk_button_new_with_label ("Rebuild Tree");
+      button = gtk_button_new_with_accel ("Rebui_ld Tree");
       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
 
       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
@@ -5640,7 +5798,7 @@ void create_ctree (void)
       mbox = gtk_vbox_new (TRUE, 5);
       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
 
-      label = gtk_label_new ("Row Height :");
+      label = gtk_label_new_with_accel ("Row Height :");
       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
 
       label = gtk_label_new ("Indent :");
@@ -5681,12 +5839,12 @@ void create_ctree (void)
       hbox = gtk_hbox_new (FALSE, 5);
       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
 
-      button = gtk_button_new_with_label ("Expand All");
+      button = gtk_button_new_with_accel ("_Expand All");
       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
       gtk_signal_connect (GTK_OBJECT (button), "clicked",
 			  GTK_SIGNAL_FUNC (expand_all), ctree);
 
-      button = gtk_button_new_with_label ("Collapse All");
+      button = gtk_button_new_with_accel ("_Collapse All");
       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
       gtk_signal_connect (GTK_OBJECT (button), "clicked",
 			  GTK_SIGNAL_FUNC (collapse_all), ctree);
@@ -6718,7 +6876,7 @@ page_switch (GtkWidget *widget, GtkNoteb
  
   if (page_num == old_page_num)
     return;
-
+  
   set_page_pixmaps (notebook, page_num, book_open, book_open_mask);
 
   if (old_page_num != -1)
@@ -6763,7 +6921,7 @@ tab_pack (GtkToggleButton *button, GtkWi
 }
 
 static void
-create_pages (GtkNotebook *notebook, gint start, gint end)
+create_pages (GtkNotebook *notebook, gint start, gint end, GtkAccelGroup *accel_group)
 {
   GtkWidget *child = NULL;
   GtkWidget *button;
@@ -6775,10 +6933,12 @@ create_pages (GtkNotebook *notebook, gin
   GtkWidget *pixwid;
   gint i;
   char buffer[32];
+  char accel_buffer[32];
 
   for (i = start; i <= end; i++)
     {
       sprintf (buffer, "Page %d", i);
+      sprintf (accel_buffer, "Page _%d", i);
 
       child = gtk_frame_new (buffer);
       gtk_container_set_border_width (GTK_CONTAINER (child), 10);
@@ -6796,7 +6956,7 @@ create_pages (GtkNotebook *notebook, gin
       gtk_signal_connect (GTK_OBJECT (button), "toggled",
 			  GTK_SIGNAL_FUNC (tab_fill), child);
 
-      button = gtk_check_button_new_with_label ("Expand Tab");
+      button = gtk_check_button_new_with_accel ("_Expand Tab");
       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
       gtk_signal_connect (GTK_OBJECT (button), "toggled",
       GTK_SIGNAL_FUNC (tab_expand), child);
@@ -6820,7 +6980,8 @@ create_pages (GtkNotebook *notebook, gin
 			   
       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
-      label = gtk_label_new (buffer);
+      label = gtk_label_new_with_accel (accel_buffer);
+      gtk_label_set_accel_widget (GTK_LABEL (label), child, FALSE);
       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
       gtk_widget_show_all (label_box);
 
@@ -6902,7 +7063,7 @@ scrollable_notebook (GtkButton   *button
   gtk_notebook_set_show_border (notebook, TRUE);
   gtk_notebook_set_scrollable (notebook, TRUE);
   if (g_list_length (notebook->children) == 5)
-    create_pages (notebook, 6, 15);
+    create_pages (notebook, 6, 15, NULL);
 }
 
 static void
@@ -6975,7 +7136,8 @@ create_notebook (void)
 						    transparent, 
 						    book_closed_xpm);
 
-      create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5);
+      create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5,
+		    gtk_window_get_default_accel_group (GTK_WINDOW (window)));
 
       separator = gtk_hseparator_new ();
       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
@@ -6984,7 +7146,7 @@ create_notebook (void)
       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
 
-      button = gtk_check_button_new_with_label ("popup menu");
+      button = gtk_check_button_new_with_accel ("popup m_enu");
       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
       gtk_signal_connect (GTK_OBJECT(button), "clicked",
 			  GTK_SIGNAL_FUNC (notebook_popup),
@@ -8764,70 +8926,16 @@ scroll_test_adjustment_changed (GtkAdjus
   gint dest_max = widget->allocation.height;
   GdkRectangle rect;
   GdkEvent *event;
+  gint dy;
 
+  dy = scroll_test_pos - (int)adj->value;
   scroll_test_pos = adj->value;
 
   if (!GTK_WIDGET_DRAWABLE (widget))
     return;
-
-  if (source_min < 0)
-    {
-      rect.x = 0; 
-      rect.y = 0;
-      rect.width = widget->allocation.width;
-      rect.height = -source_min;
-      if (rect.height > widget->allocation.height)
-	rect.height = widget->allocation.height;
 
-      source_min = 0;
-      dest_min = rect.height;
-    }
-  else
-    {
-      rect.x = 0;
-      rect.y = 2*widget->allocation.height - source_max;
-      if (rect.y < 0)
-	rect.y = 0;
-      rect.width = widget->allocation.width;
-      rect.height = widget->allocation.height - rect.y;
-
-      source_max = widget->allocation.height;
-      dest_max = rect.y;
-    }
-
-  if (source_min != source_max)
-    {
-      if (scroll_test_gc == NULL)
-	{
-	  scroll_test_gc = gdk_gc_new (widget->window);
-	  gdk_gc_set_exposures (scroll_test_gc, TRUE);
-	}
-
-      gdk_draw_pixmap (widget->window,
-		       scroll_test_gc,
-		       widget->window,
-		       0, source_min,
-		       0, dest_min,
-		       widget->allocation.width,
-		       source_max - source_min);
-
-      /* Make sure graphics expose events are processed before scrolling
-       * again */
-      
-      while ((event = gdk_event_get_graphics_expose (widget->window)) != NULL)
-	{
-	  gtk_widget_event (widget, event);
-	  if (event->expose.count == 0)
-	    {
-	      gdk_event_free (event);
-	      break;
-	    }
-	  gdk_event_free (event);
-	}
-    }
-
-  if (rect.height != 0)
-    gtk_widget_draw (widget, &rect);
+  gdk_window_scroll (widget->window, 0, dy);
+  gdk_window_process_updates (widget->window, FALSE);
 }
 
 
@@ -9744,6 +9852,17 @@ create_main_window (void)
   gtk_widget_grab_default (button);
 
   gtk_widget_show_all (window);
+
+  {
+    GdkPixbuf *pixbuf;
+
+    pixbuf = gdk_pixbuf_new_from_inline (apple,
+					 FALSE,
+					 sizeof (apple),
+					 NULL);
+					 
+    gdk_window_set_icon_list (window->window, g_list_prepend (NULL, pixbuf));
+  }
 }
 
 static void












[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]