Index: gtkenums.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkenums.h,v
retrieving revision 1.45
diff -u -p -r1.45 gtkenums.h
--- gtkenums.h	2001/08/27 19:19:24	1.45
+++ gtkenums.h	2001/10/08 16:21:35
@@ -366,6 +366,15 @@ typedef enum
   GTK_TOOLBAR_BOTH_HORIZ
 } GtkToolbarStyle;
 
+/* Direction for toolbars */
+typedef enum
+{
+  GTK_TOOLBAR_DIR_PREV,
+  GTK_TOOLBAR_DIR_NEXT,
+  GTK_TOOLBAR_DIR_FIRST,
+  GTK_TOOLBAR_DIR_LAST
+} GtkToolbarDirection;
+
 /* Data update types (for ranges) */
 typedef enum
 {
Index: gtksettings.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtksettings.c,v
retrieving revision 1.19
diff -u -p -r1.19 gtksettings.c
--- gtksettings.c	2001/10/04 06:48:09	1.19
+++ gtksettings.c	2001/10/08 16:21:36
@@ -29,7 +29,8 @@ enum {
   PROP_SPLIT_CURSOR,
   PROP_THEME_NAME,
   PROP_KEY_THEME_NAME,
-  PROP_MENU_BAR_ACCEL
+  PROP_MENU_BAR_ACCEL,
+  PROP_TOOLBAR_ACCEL
 };
 
 
@@ -199,6 +200,16 @@ gtk_settings_class_init (GtkSettingsClas
                                              NULL);
 
   g_assert (result == PROP_MENU_BAR_ACCEL);
+
+  result = settings_install_property_parser (class,
+                                             g_param_spec_string ("gtk-toolbar-accel",
+                                                                  _("Toolbar accelerator"),
+                                                                  _("Keybinding to activate the toolbar"),
+                                                                  "<Ctrl>F10",
+                                                                  G_PARAM_READWRITE),
+                                             NULL);
+
+  g_assert (result == PROP_TOOLBAR_ACCEL);
 }
 
 static void
Index: gtktoolbar.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktoolbar.c,v
retrieving revision 1.62
diff -u -p -r1.62 gtktoolbar.c
--- gtktoolbar.c	2001/08/23 23:38:32	1.62
+++ gtktoolbar.c	2001/10/08 16:21:37
@@ -25,6 +25,7 @@
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+#include "gdk/gdkkeysyms.h"
 #include "gtkbutton.h"
 #include "gtktogglebutton.h"
 #include "gtkradiobutton.h"
@@ -37,6 +38,8 @@
 #include "gtkimage.h"
 #include "gtksettings.h"
 #include "gtkintl.h"
+#include "gtkmain.h"
+#include "gtkbindings.h"
 
 
 #define DEFAULT_IPADDING 0
@@ -58,6 +61,9 @@ enum {
 enum {
   ORIENTATION_CHANGED,
   STYLE_CHANGED,
+  MOVE_CURRENT,
+  ACTIVATE_CURRENT,
+  CANCEL,
   LAST_SIGNAL
 };
 
@@ -91,6 +97,13 @@ static void gtk_toolbar_style_set       
                                                   GtkStyle        *prev_style);
 static gboolean gtk_toolbar_focus                (GtkWidget       *widget,
                                                   GtkDirectionType dir);
+static void gtk_toolbar_hierarchy_changed        (GtkWidget       *widget,
+                                                  GtkWidget       *old_toplevel);
+static gint gtk_toolbar_enter_notify             (GtkWidget         *widget,
+                                                  GdkEventCrossing  *event);
+static gint gtk_toolbar_leave_notify             (GtkWidget         *widget,
+                                                  GdkEventCrossing  *event);
+
 static void gtk_toolbar_show_all                 (GtkWidget       *widget);
 static void gtk_toolbar_add                      (GtkContainer    *container,
 				                  GtkWidget       *widget);
@@ -134,6 +147,15 @@ static GtkReliefStyle       get_button_r
 static gint                 get_space_size    (GtkToolbar *toolbar);
 static GtkToolbarSpaceStyle get_space_style   (GtkToolbar *toolbar);
 
+static void        gtk_real_toolbar_move_current    (GtkToolbar         *toolbar,
+                                                     GtkToolbarDirection direction);
+static void        gtk_real_toolbar_activate_current (GtkToolbar        *toolbar);
+static void        gtk_real_toolbar_cancel           (GtkToolbar        *toolbar);
+
+static void        gtk_toolbar_move_selected         (GtkToolbar        *toolbar,
+                                                      gint               distance);
+static void        gtk_toolbar_select_item           (GtkToolbar        *toolbar,
+                                                      GtkToolbarChild   *child);
 
 static GtkContainerClass *parent_class;
 
@@ -173,6 +195,8 @@ gtk_toolbar_class_init (GtkToolbarClass 
   GtkWidgetClass *widget_class;
   GtkContainerClass *container_class;
 
+  GtkBindingSet *binding_set;
+
   gobject_class = G_OBJECT_CLASS (class);
   object_class = (GtkObjectClass *) class;
   widget_class = (GtkWidgetClass *) class;
@@ -192,6 +216,9 @@ gtk_toolbar_class_init (GtkToolbarClass 
   widget_class->style_set = gtk_toolbar_style_set;
   widget_class->show_all = gtk_toolbar_show_all;
   widget_class->focus = gtk_toolbar_focus;
+  widget_class->hierarchy_changed = gtk_toolbar_hierarchy_changed;
+  widget_class->enter_notify_event = gtk_toolbar_enter_notify;
+  widget_class->leave_notify_event = gtk_toolbar_leave_notify;
   
   container_class->add = gtk_toolbar_add;
   container_class->remove = gtk_toolbar_remove;
@@ -199,6 +226,9 @@ gtk_toolbar_class_init (GtkToolbarClass 
   
   class->orientation_changed = gtk_real_toolbar_orientation_changed;
   class->style_changed = gtk_real_toolbar_style_changed;
+  class->move_current = gtk_real_toolbar_move_current;
+  class->activate_current = gtk_real_toolbar_activate_current;
+  class->cancel = gtk_real_toolbar_cancel;
 
   toolbar_signals[ORIENTATION_CHANGED] =
     gtk_signal_new ("orientation_changed",
@@ -216,6 +246,28 @@ gtk_toolbar_class_init (GtkToolbarClass 
 		    gtk_marshal_VOID__INT,
 		    GTK_TYPE_NONE, 1,
 		    GTK_TYPE_INT);
+  toolbar_signals[MOVE_CURRENT] =
+    gtk_signal_new ("move_current",
+                    GTK_RUN_LAST | GTK_RUN_ACTION,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GtkToolbarClass, move_current),
+                    gtk_marshal_VOID__ENUM,
+                    GTK_TYPE_NONE, 1,
+                    GTK_TYPE_DIRECTION_TYPE);
+  toolbar_signals[ACTIVATE_CURRENT] =
+    gtk_signal_new ("activate_current",
+                    GTK_RUN_LAST | GTK_RUN_ACTION,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GtkToolbarClass, activate_current),
+                    gtk_marshal_VOID__VOID,
+                    GTK_TYPE_NONE, 0);
+  toolbar_signals[CANCEL] =
+    gtk_signal_new ("cancel",
+                    GTK_RUN_LAST | GTK_RUN_ACTION,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GtkToolbarClass, cancel),
+                    gtk_marshal_VOID__VOID,
+                    GTK_TYPE_NONE, 0);
   
   g_object_class_install_property (gobject_class,
 				   PROP_ORIENTATION,
@@ -292,6 +344,77 @@ gtk_toolbar_class_init (GtkToolbarClass 
                                                     GTK_TYPE_ICON_SIZE,
                                                     GTK_ICON_SIZE_LARGE_TOOLBAR,
                                                     G_PARAM_READWRITE));  
+
+  binding_set = gtk_binding_set_by_class (class);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_Escape, 0,
+                                "cancel", 0);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_Return, 0,
+                                "activate_current", 0);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_KP_Enter, 0,
+                                "activate_current", 0);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_Left, 0,
+                                "move_current", 1,
+                                GTK_TYPE_TOOLBAR_DIRECTION,
+                                GTK_TOOLBAR_DIR_PREV);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_KP_Left, 0,
+                                "move_current", 1,
+                                GTK_TYPE_TOOLBAR_DIRECTION,
+                                GTK_TOOLBAR_DIR_PREV);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_Right, 0,
+                                "move_current", 1,
+                                GTK_TYPE_TOOLBAR_DIRECTION,
+                                GTK_TOOLBAR_DIR_NEXT);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_KP_Right, 0,
+                                "move_current", 1,
+                                GTK_TYPE_TOOLBAR_DIRECTION,
+                                GTK_TOOLBAR_DIR_NEXT);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_Up, 0,
+                                "move_current", 1,
+                                GTK_TYPE_TOOLBAR_DIRECTION,
+                                GTK_TOOLBAR_DIR_PREV);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_KP_Up, 0,
+                                "move_current", 1,
+                                GTK_TYPE_TOOLBAR_DIRECTION,
+                                GTK_TOOLBAR_DIR_PREV);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_Down, 0,
+                                "move_current", 1,
+                                GTK_TYPE_TOOLBAR_DIRECTION,
+                                GTK_TOOLBAR_DIR_NEXT);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_KP_Down, 0,
+                                "move_current", 1,
+                                GTK_TYPE_TOOLBAR_DIRECTION,
+                                GTK_TOOLBAR_DIR_NEXT);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_Home, 0,
+                                "move_current", 1,
+                                GTK_TYPE_TOOLBAR_DIRECTION,
+                                GTK_TOOLBAR_DIR_FIRST);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_KP_Home, 0,
+                                "move_current", 1,
+                                GTK_TYPE_TOOLBAR_DIRECTION,
+                                GTK_TOOLBAR_DIR_FIRST);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_End, 0,
+                                "move_current", 1,
+                                GTK_TYPE_TOOLBAR_DIRECTION,
+                                GTK_TOOLBAR_DIR_LAST);
+  gtk_binding_entry_add_signal (binding_set,
+                                GDK_KP_End, 0,
+                                "move_current", 1,
+                                GTK_TYPE_TOOLBAR_DIRECTION,
+                                GTK_TOOLBAR_DIR_LAST);
 }
 
 static void
@@ -344,6 +467,7 @@ gtk_toolbar_init (GtkToolbar *toolbar)
 
   toolbar->style_set = FALSE;
   toolbar->icon_size_set = FALSE;
+  toolbar->active = FALSE;
   g_object_get (gtk_settings_get_default (),
                 "gtk-toolbar-icon-size",
                 &toolbar->icon_size,
@@ -785,7 +909,6 @@ gtk_toolbar_focus (GtkWidget       *widg
                    GtkDirectionType dir)
 {
   /* Focus can't go in toolbars */
-  
   return FALSE;
 }
 
@@ -1716,4 +1839,326 @@ get_space_style (GtkToolbar *toolbar)
 
 
   return space_style;  
+}
+
+static gboolean
+window_key_press_handler (GtkWidget   *widget,
+                          GdkEventKey *event,
+                          gpointer     data)
+{
+  gchar *accel = NULL;
+  gboolean retval = FALSE;
+
+
+  g_object_get (G_OBJECT (gtk_widget_get_settings (widget)),
+                "gtk-toolbar-accel",
+                &accel,
+                NULL);
+
+  if (accel)
+    {
+      guint keyval = 0;
+      GdkModifierType mods = 0;
+
+      gtk_accelerator_parse (accel, &keyval, &mods);
+
+      if (keyval == 0)
+        g_warning ("Failed to parse toolbar accelerator '%s'\n", accel);
+
+      /* FIXME this is wrong, needs to be in the global accel resolution
+       * thing, to properly consider i18n etc., but that probably requires
+       * AccelGroup changes etc.
+       */
+      if (event->keyval == keyval &&
+          (mods & event->state) == mods)
+        {
+          GtkToolbar *toolbar;
+
+          toolbar = GTK_TOOLBAR (data);
+
+          if (toolbar->children)
+            {
+              if (toolbar->active)
+                {
+                  gtk_signal_emit_by_name (GTK_OBJECT (toolbar), "cancel");
+                }
+              else
+                {
+                  GList *children;
+                  GtkToolbarChild *child;
+                  gboolean child_prelit = FALSE;
+
+                  toolbar->active = TRUE;
+                  toolbar->active_child = NULL;
+                  gtk_grab_add (GTK_WIDGET (toolbar));
+                  /*
+                   * Check whether any of the buttons are prelit, 
+                   * presumably, because of mouse position.
+                   */
+                  children = toolbar->children;
+                  while (children && !child_prelit)
+                    {
+                      child = children->data;
+
+                      switch (child->type)
+                        {
+                        case GTK_TOOLBAR_CHILD_BUTTON:
+                        case GTK_TOOLBAR_CHILD_RADIOBUTTON:
+                        case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
+                          if (GTK_WIDGET_STATE (child->widget) == GTK_STATE_PRELIGHT)
+                            {
+                              toolbar->active_child = child;
+                              child_prelit = TRUE;
+                            }
+                          break;
+                        case GTK_TOOLBAR_CHILD_WIDGET:
+                          /*
+                           * Attempt to take down tooltip, in case it is up
+                           */
+                          _gtk_tooltips_popdown_tip (child->widget);
+                          break;
+                        default:
+                          break;
+                        }  
+                      children = children->next;
+                    }  
+                  /*
+                   * Select the first item
+                   */
+                  gtk_toolbar_select_item (toolbar, toolbar->children->data);
+                }
+              retval = TRUE;
+            }
+        }
+
+      g_free (accel);
+    }
+
+  return retval;
+}
+
+static void
+add_to_window (GtkWindow  *window,
+               GtkToolbar *toolbar)
+{
+  g_signal_connect (G_OBJECT (window),
+                    "key_press_event",
+                    G_CALLBACK (window_key_press_handler),
+                    toolbar);
+}
+
+static void
+remove_from_window (GtkWindow  *window,
+                    GtkToolbar *toolbar)
+{
+  g_signal_handlers_disconnect_by_func (G_OBJECT (window),
+                                        G_CALLBACK (window_key_press_handler),
+                                        toolbar);
+}
+
+static void
+gtk_toolbar_hierarchy_changed (GtkWidget *widget,
+                               GtkWidget *old_toplevel)
+{
+  GtkWidget *toplevel;
+  GtkToolbar *toolbar;
+
+  toolbar = GTK_TOOLBAR (widget);
+
+  toplevel = gtk_widget_get_toplevel (widget);
+
+  if (old_toplevel)
+    remove_from_window (GTK_WINDOW (old_toplevel), toolbar);
+
+  if (GTK_WIDGET_TOPLEVEL (toplevel))
+    add_to_window (GTK_WINDOW (toplevel), toolbar);
+}
+
+static gint
+gtk_toolbar_enter_notify (GtkWidget       *widget,
+                          GdkEventCrossing *event)
+{
+  GtkWidget *event_widget;
+  GtkWidget *event_toplevel;
+  GtkWidget *widget_toplevel;
+
+  event_widget = gtk_get_event_widget ((GdkEvent *)event);
+  event_toplevel = gtk_widget_get_toplevel (event_widget);
+  widget_toplevel = gtk_widget_get_toplevel (widget);
+  if (event_toplevel == widget_toplevel)
+    {
+      GtkToolbar *toolbar;
+
+      g_return_val_if_fail (GTK_IS_TOOLBAR (widget), FALSE);
+      toolbar = GTK_TOOLBAR (widget);
+      if (toolbar->active)
+        {
+          gtk_signal_emit_by_name (GTK_OBJECT (toolbar), "cancel");
+          return TRUE;
+        }
+    }
+  return FALSE;
+}
+
+static gint
+gtk_toolbar_leave_notify (GtkWidget       *widget,
+                          GdkEventCrossing *event)
+{
+  GtkWidget *event_widget;
+
+  event_widget = gtk_get_event_widget ((GdkEvent *)event);
+  g_print ("gtk_toolbar_leave_notify %s\n", g_type_name (G_OBJECT_TYPE (event_widget)));
+  return TRUE;
+}
+
+static void
+gtk_real_toolbar_move_current (GtkToolbar      *toolbar,
+                               GtkToolbarDirection direction)
+{
+  switch (direction)
+    {
+    case GTK_TOOLBAR_DIR_FIRST:
+      if (toolbar->children)
+        {
+          GList *node;
+          GtkToolbarChild *child;
+
+          node = toolbar->children;
+          child = toolbar->children->data;
+          while (node && child->type == GTK_TOOLBAR_CHILD_SPACE)
+            {
+              node = node->next;
+              if (node)
+                child = (GtkToolbarChild *)node->data;
+            }
+          if (node)
+            gtk_toolbar_select_item (toolbar, child);
+        }
+      break;
+
+    case GTK_TOOLBAR_DIR_LAST:
+      if (toolbar->children)
+        {
+          GList *node;
+          GtkToolbarChild *child;
+
+          node = g_list_last (toolbar->children);
+          child = toolbar->children->data;
+          while (node && child->type == GTK_TOOLBAR_CHILD_SPACE)
+            {
+              node = node->prev;
+              if (node)
+                child = (GtkToolbarChild *)node->data;
+            }
+          if (node)
+            gtk_toolbar_select_item (toolbar, child);
+        }
+      break;
+
+    case GTK_TOOLBAR_DIR_NEXT:
+      gtk_toolbar_move_selected (toolbar, 1);
+      break;
+    case GTK_TOOLBAR_DIR_PREV:
+      gtk_toolbar_move_selected (toolbar, -1);
+      break;
+    }
+}
+
+static void
+gtk_real_toolbar_activate_current (GtkToolbar   *toolbar)
+{
+  if (toolbar->active_child)
+    {
+      if (toolbar->active_child->type == GTK_TOOLBAR_CHILD_WIDGET &&
+          GTK_WIDGET_CAN_FOCUS (toolbar->active_child->widget))
+        gtk_widget_grab_focus (toolbar->active_child->widget);
+      else 
+        gtk_widget_activate (toolbar->active_child->widget);
+
+      gtk_toolbar_select_item (toolbar, toolbar->active_child);
+    }
+}
+
+static void
+gtk_real_toolbar_cancel (GtkToolbar   *toolbar)
+{
+  g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
+
+  if (toolbar->active_child)
+    {
+      gtk_widget_set_state (toolbar->active_child->widget, GTK_STATE_NORMAL);
+      _gtk_tooltips_popdown_tip (toolbar->active_child->widget);
+      toolbar->active_child = NULL;
+    }
+
+  if (toolbar->active)
+    {
+      gtk_grab_remove (GTK_WIDGET (toolbar));
+      toolbar->active = FALSE;
+    }
+}
+
+/* Distance should be +/- 1 */
+static void
+gtk_toolbar_move_selected (GtkToolbar   *toolbar,
+                           gint         distance)
+{
+  if (toolbar->active_child)
+    {
+      GList *node = g_list_find (toolbar->children,
+                                 toolbar->active_child);
+      GtkToolbarChild *child;
+
+      if (distance > 0)
+        {
+          node = node->next;
+          if (node)
+            child = node->data;
+          while (!node ||
+                 (child->type == GTK_TOOLBAR_CHILD_SPACE))
+            {
+              if (!node)
+                node = toolbar->children;
+              else
+                node = node->next;
+              if (node)
+                child = node->data;
+            }
+        }
+      else
+        {
+          node = node->prev;
+          if (node)
+            child = node->data;
+          while (!node ||
+                 (child->type == GTK_TOOLBAR_CHILD_SPACE))
+            {
+              if (!node)
+                node = g_list_last (toolbar->children);
+              else
+                node = node->prev;
+              if (node)
+                child = node->data;
+            }
+        }
+      gtk_toolbar_select_item (toolbar, child);
+    }
+}
+
+static void
+gtk_toolbar_select_item (GtkToolbar      *toolbar,
+                         GtkToolbarChild *child)
+{
+  if (toolbar->active_child != child)
+    {
+      if (toolbar->active_child)
+        {
+          gtk_widget_set_state (toolbar->active_child->widget, GTK_STATE_NORMAL);
+          _gtk_tooltips_popdown_tip (toolbar->active_child->widget);
+        }
+      toolbar->active_child = child;
+    }
+  gtk_widget_set_state (toolbar->active_child->widget, GTK_STATE_PRELIGHT); 
+  if (gtk_toolbar_get_tooltips (toolbar))
+    _gtk_tooltips_show_tip (toolbar->active_child->widget);
 }
