Index: gimpdisplayshell.c
===================================================================
RCS file: /cvs/gnome/gimp/app/display/gimpdisplayshell.c,v
retrieving revision 1.322
diff -u -p -u -p -r1.322 gimpdisplayshell.c
--- a/gimpdisplayshell.c	1 Jun 2004 23:14:28 -0000	1.322
+++ b/gimpdisplayshell.c	19 Jun 2004 12:59:16 -0000
@@ -957,7 +957,6 @@ gimp_display_shell_new (GimpDisplay     
 
   /*  the statusbar  */
   shell->statusbar = gimp_statusbar_new (shell);
-  gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (shell->statusbar), FALSE);
   gimp_help_set_help_data (shell->statusbar, NULL,
                            GIMP_HELP_IMAGE_WINDOW_STATUS_BAR);
 
Index: gimpstatusbar.c
===================================================================
RCS file: /cvs/gnome/gimp/app/display/gimpstatusbar.c,v
retrieving revision 1.12
diff -u -p -u -p -r1.12 gimpstatusbar.c
--- a/gimpstatusbar.c	1 Jun 2004 22:04:19 -0000	1.12
+++ b/gimpstatusbar.c	19 Jun 2004 12:59:16 -0000
@@ -26,6 +26,7 @@
 
 #include "core/gimpimage.h"
 #include "core/gimpunit.h"
+#include "core/gimpmarshal.h"
 
 #include "widgets/gimpunitstore.h"
 #include "widgets/gimpunitcombobox.h"
@@ -38,29 +39,42 @@
 
 #include "gimp-intl.h"
 
+typedef struct _GimpStatusbarMsg GimpStatusbarMsg;
+
+struct _GimpStatusbarMsg
+{
+  gchar *text;
+  guint context_id;
+  guint message_id;
+};
+
+enum
+{
+  SIGNAL_TEXT_PUSHED,
+  SIGNAL_TEXT_POPPED,
+  SIGNAL_LAST
+};
 
 /* maximal width of the string holding the cursor-coordinates for
  * the status line
  */
 #define CURSOR_LEN 256
 
-
-static void   gimp_statusbar_class_init    (GimpStatusbarClass *klass);
-static void   gimp_statusbar_init          (GimpStatusbar      *statusbar);
-
-static void   gimp_statusbar_update        (GtkStatusbar       *gtk_statusbar,
-                                            guint               context_id,
-                                            const gchar        *text);
-static void   gimp_statusbar_unit_changed  (GimpUnitComboBox   *combo,
-                                            GimpStatusbar      *statusbar);
-static void   gimp_statusbar_scale_changed (GimpScaleComboBox  *combo,
-                                            GimpStatusbar      *statusbar);
-static void   gimp_statusbar_shell_scaled  (GimpDisplayShell   *shell,
-                                            GimpStatusbar      *statusbar);
-
-
-static GtkStatusbarClass *parent_class = NULL;
-
+static void     gimp_statusbar_class_init        (GimpStatusbarClass *klass);
+static void     gimp_statusbar_init              (GimpStatusbar      *statusbar);
+static void     gimp_statusbar_update            (GimpStatusbar      *statusbar,
+                                                  const gchar        *context_id,
+                                                  const gchar        *text);
+static void     gimp_statusbar_unit_changed      (GimpUnitComboBox   *combo,
+                                                  GimpStatusbar      *statusbar);
+static void     gimp_statusbar_scale_changed     (GimpScaleComboBox  *combo,
+                                                  GimpStatusbar      *statusbar);
+static void     gimp_statusbar_shell_scaled      (GimpDisplayShell   *shell,
+                                                  GimpStatusbar      *statusbar);                                            
+static void     gimp_statusbar_destroy           (GtkObject          *object);
+                               
+static GtkContainerClass *parent_class;
+static guint              statusbar_signals[SIGNAL_LAST] = { 0 };
 
 GType
 gimp_statusbar_get_type (void)
@@ -82,7 +96,7 @@ gimp_statusbar_get_type (void)
 	(GInstanceInitFunc) gimp_statusbar_init,
       };
 
-      statusbar_type = g_type_register_static (GTK_TYPE_STATUSBAR,
+      statusbar_type = g_type_register_static (GTK_TYPE_HBOX,
                                                "GimpStatusbar",
                                                &statusbar_info, 0);
     }
@@ -93,30 +107,73 @@ gimp_statusbar_get_type (void)
 static void
 gimp_statusbar_class_init (GimpStatusbarClass *klass)
 {
-  GtkStatusbarClass *gtk_statusbar_class;
 
-  parent_class = g_type_class_peek_parent (klass);
+      
+  GObjectClass *g_object_class;
+  GtkObjectClass *gtk_object_class;
+  GtkWidgetClass *gtk_widget_class;
+  GtkContainerClass *gtk_container_class;
+
+  g_object_class = (GObjectClass *) klass;
+  gtk_object_class = (GtkObjectClass *) klass;
+  gtk_widget_class = (GtkWidgetClass *) klass;
+  gtk_container_class = (GtkContainerClass *) klass;
 
-  gtk_statusbar_class = GTK_STATUSBAR_CLASS (klass);
+  parent_class = g_type_class_peek_parent (klass);
+  
+  gtk_object_class->destroy = gimp_statusbar_destroy;
+ 
+  klass->messages_mem_chunk = g_mem_chunk_new ("GimpStatusbar messages mem chunk",
+                                               sizeof (GimpStatusbarMsg),
+                                               sizeof (GimpStatusbarMsg) * 64,
+                                               G_ALLOC_AND_FREE);
+
+  statusbar_signals[SIGNAL_TEXT_PUSHED] =
+    g_signal_new ("text_pushed",
+                  G_OBJECT_CLASS_TYPE (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GimpStatusbarClass, text_pushed),
+                  NULL, NULL,
+                  gimp_marshal_VOID__UINT_STRING,
+                  G_TYPE_NONE, 2,
+                  G_TYPE_UINT,
+                  G_TYPE_STRING);
+  statusbar_signals[SIGNAL_TEXT_POPPED] =
+    g_signal_new ("text_popped",
+                  G_OBJECT_CLASS_TYPE (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GimpStatusbarClass, text_popped),
+                  NULL, NULL,
+                  gimp_marshal_VOID__UINT_STRING,
+                  G_TYPE_NONE, 2,
+                  G_TYPE_UINT,
+                  G_TYPE_STRING);
+
+  gtk_widget_class_install_style_property (gtk_widget_class,
+                                           g_param_spec_enum ("shadow_type",
+                                           _("Shadow type"),
+                                           _("Style of bevel around the statusbar text"),
+                                           GTK_TYPE_SHADOW_TYPE,
+                                           GTK_SHADOW_IN,
+                                           G_PARAM_READABLE));                                                                 
 
-  gtk_statusbar_class->text_pushed = gimp_statusbar_update;
-  gtk_statusbar_class->text_popped = gimp_statusbar_update;
+  klass->text_pushed = gimp_statusbar_update;
+  klass->text_popped = gimp_statusbar_update;                                           
 }
 
 static void
 gimp_statusbar_init (GimpStatusbar *statusbar)
 {
-  GtkStatusbar  *gtk_statusbar;
   GtkBox        *box;
   GtkWidget     *hbox;
   GtkWidget     *frame;
   GimpUnitStore *store;
   GtkShadowType  shadow_type;
 
-  gtk_statusbar = GTK_STATUSBAR (statusbar);
-  box           = GTK_BOX (statusbar);
+  box = GTK_BOX (statusbar);
 
-  gtk_widget_hide (gtk_statusbar->frame);
+  box->spacing = 2;
+  box->homogeneous = FALSE;
 
   statusbar->shell                 = NULL;
   statusbar->cursor_format_str[0]  = '\0';
@@ -190,15 +247,18 @@ gimp_statusbar_init (GimpStatusbar *stat
 
   gtk_progress_bar_set_text (GTK_PROGRESS_BAR (statusbar->progressbar),
                              "GIMP");
+  
+  statusbar->seq_context_id = 1;
+  statusbar->seq_message_id = 1;
+  statusbar->messages = NULL;
+  statusbar->keys = NULL;
 }
 
 static void
-gimp_statusbar_update (GtkStatusbar *gtk_statusbar,
-                       guint         context_id,
-                       const gchar  *text)
+gimp_statusbar_update (GimpStatusbar *statusbar,
+                       const gchar   *context_id,
+                       const gchar   *text)
 {
-  GimpStatusbar *statusbar = GIMP_STATUSBAR (gtk_statusbar);
-
   if (! text)
     text = "";
 
@@ -223,39 +283,129 @@ gimp_statusbar_new (GimpDisplayShell *sh
   return GTK_WIDGET (statusbar);
 }
 
-void
+guint     
 gimp_statusbar_push (GimpStatusbar *statusbar,
-                     const gchar   *context_id,
+                     const gchar   *context,
                      const gchar   *message)
 {
-  GtkStatusbar *bar;
-
-  g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
-
-  bar = GTK_STATUSBAR (statusbar);
-
-  gtk_statusbar_push (bar,
-                      gtk_statusbar_get_context_id (bar, context_id),
-                      message);
+  GimpStatusbarMsg *msg;
+  GimpStatusbarClass *class;
+  guint context_id;
+  
+  g_return_val_if_fail (GIMP_IS_STATUSBAR (statusbar), 0);
+  g_return_val_if_fail (message != NULL, 0);
+  
+  class = GIMP_STATUSBAR_GET_CLASS (statusbar);
+  context_id = gimp_statusbar_get_context_id (statusbar, context);
+   
+  msg = g_chunk_new (GimpStatusbarMsg, class->messages_mem_chunk);
+  msg->text = g_strdup (message);
+  msg->context_id = context_id;
+  msg->message_id = statusbar->seq_message_id++;
+
+  statusbar->messages = g_slist_prepend (statusbar->messages, msg);
+
+  g_signal_emit (statusbar,
+                 statusbar_signals[SIGNAL_TEXT_PUSHED],
+                 0,
+                 msg->context_id,
+                 msg->text);
+  return msg->message_id;
 }
 
 void
 gimp_statusbar_pop (GimpStatusbar *statusbar,
-                    const gchar   *context_id)
+                    const gchar   *context)
 {
-  GtkStatusbar *bar;
-
+  GimpStatusbarMsg *msg;
+  guint context_id;
+     
   g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
+  context_id = gimp_statusbar_get_context_id (statusbar, context);
+  if (statusbar->messages)
+    {
+      GSList *list;
+
+      for (list = statusbar->messages; list; list = list->next)
+        {
+           msg = list->data;
+
+           if (msg->context_id == context_id)
+             {
+               GimpStatusbarClass *class;
+
+               class = GIMP_STATUSBAR_GET_CLASS (statusbar);
+
+               statusbar->messages = g_slist_remove_link (statusbar->messages,
+                                                          list);
+               g_free (msg->text);
+               g_mem_chunk_free (class->messages_mem_chunk, msg);
+               g_slist_free_1 (list);
+               break;
+             }
+        }
+    }
 
-  bar = GTK_STATUSBAR (statusbar);
+  msg = statusbar->messages ? statusbar->messages->data : NULL;
 
-  gtk_statusbar_pop (bar,
-                     gtk_statusbar_get_context_id (bar, context_id));
+  g_signal_emit (statusbar,
+                 statusbar_signals[SIGNAL_TEXT_POPPED],
+                 0,
+                 (guint) (msg ? msg->context_id : 0),
+                 msg ? msg->text : NULL);
 }
 
+
 void
+gimp_statusbar_remove (GimpStatusbar *statusbar,
+                       const gchar   *context,
+                       guint          message_id)
+{
+  GimpStatusbarMsg *msg;
+  guint context_id;
+     
+  g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
+  g_return_if_fail (message_id > 0);
+  context_id = gimp_statusbar_get_context_id (statusbar, context);
+  
+  
+  msg = statusbar->messages ? statusbar->messages->data : NULL;
+  if (msg)
+    {
+      GSList *list;
+
+      /* care about signal emission if the topmost item is removed */
+      if (msg->context_id == context_id &&
+          msg->message_id == message_id)
+        {
+           gimp_statusbar_pop (statusbar, context);
+           return;
+        }
+      
+      for (list = statusbar->messages; list; list = list->next)
+        {
+           msg = list->data;
+      
+           if (msg->context_id == context_id &&
+               msg->message_id == message_id)
+             {
+                GimpStatusbarClass *class;
+              
+                class = GIMP_STATUSBAR_GET_CLASS (statusbar);
+                statusbar->messages = g_slist_remove_link (statusbar->messages, list);
+                g_free (msg->text);
+                g_mem_chunk_free (class->messages_mem_chunk, msg);
+                g_slist_free_1 (list);         
+                break;
+             }
+        }
+    }
+}
+
+
+guint
 gimp_statusbar_push_coords (GimpStatusbar *statusbar,
-                            const gchar   *context_id,
+                            const gchar   *context,
                             const gchar   *title,
                             gdouble        x,
                             const gchar   *separator,
@@ -264,16 +414,16 @@ gimp_statusbar_push_coords (GimpStatusba
   GimpDisplayShell *shell;
   gchar             buf[CURSOR_LEN];
 
-  g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
-  g_return_if_fail (title != NULL);
-  g_return_if_fail (separator != NULL);
+  g_return_val_if_fail  (GIMP_IS_STATUSBAR (statusbar), 0);
+  g_return_val_if_fail (title != NULL, 0);
+  g_return_val_if_fail (separator != NULL, 0);
 
   shell = statusbar->shell;
 
   if (shell->unit == GIMP_UNIT_PIXEL)
     {
       g_snprintf (buf, sizeof (buf), statusbar->cursor_format_str,
-		  title,
+               title,
                   ROUND (x),
                   separator,
                   ROUND (y));
@@ -285,15 +435,16 @@ gimp_statusbar_push_coords (GimpStatusba
                                                       shell->unit);
 
       g_snprintf (buf, sizeof (buf), statusbar->cursor_format_str,
-		  title,
-		  x * unit_factor / image->xresolution,
-		  separator,
-		  y * unit_factor / image->yresolution);
+                  title,
+                 x * unit_factor / image->xresolution,
+                  separator,
+             y * unit_factor / image->yresolution);
     }
 
-  gimp_statusbar_push (statusbar, context_id, buf);
+  return gimp_statusbar_push (statusbar, context, buf);
 }
 
+
 void
 gimp_statusbar_set_cursor (GimpStatusbar *statusbar,
                            gdouble        x,
@@ -425,3 +576,61 @@ gimp_statusbar_scale_changed (GimpScaleC
                             GIMP_ZOOM_TO,
                             gimp_scale_combo_box_get_scale (combo));
 }
+
+guint
+gimp_statusbar_get_context_id (GimpStatusbar *statusbar,
+                               const gchar  *context_description)
+{
+  gchar *string;
+  guint *id;
+  
+  g_return_val_if_fail (GIMP_IS_STATUSBAR (statusbar), 0);
+  g_return_val_if_fail (context_description != NULL, 0);
+
+  /* we need to preserve namespaces on object datas */
+  string = g_strconcat ("gimp-status-bar-context:", context_description, NULL);
+
+  id = g_object_get_data (G_OBJECT (statusbar), string);
+  if (!id)
+    {
+      id = g_new (guint, 1);
+      *id = statusbar->seq_context_id++;
+      g_object_set_data_full (G_OBJECT (statusbar), string, id, g_free);
+      statusbar->keys = g_slist_prepend (statusbar->keys, string);
+    }
+  else
+    g_free (string);
+
+  return *id;
+}
+
+static void
+gimp_statusbar_destroy (GtkObject *object)
+{
+  GimpStatusbar *statusbar;
+  GimpStatusbarClass *class;
+  GSList *list;
+
+  g_return_if_fail (GIMP_IS_STATUSBAR (object));
+
+  statusbar = GIMP_STATUSBAR (object);
+  class = GIMP_STATUSBAR_GET_CLASS (statusbar);
+
+  for (list = statusbar->messages; list; list = list->next)
+    {
+      GimpStatusbarMsg *msg;
+
+      msg = list->data;
+      g_free (msg->text);
+      g_mem_chunk_free (class->messages_mem_chunk, msg);
+    }
+  g_slist_free (statusbar->messages);
+  statusbar->messages = NULL;
+
+  for (list = statusbar->keys; list; list = list->next)
+    g_free (list->data);
+  g_slist_free (statusbar->keys);
+  statusbar->keys = NULL;
+
+  GTK_OBJECT_CLASS (parent_class)->destroy (object);
+}
Index: gimpstatusbar.h
===================================================================
RCS file: /cvs/gnome/gimp/app/display/gimpstatusbar.h,v
retrieving revision 1.5
diff -u -p -u -p -r1.5 gimpstatusbar.h
--- a/gimpstatusbar.h	10 May 2004 10:33:21 -0000	1.5
+++ b/gimpstatusbar.h	19 Jun 2004 12:59:16 -0000
@@ -19,11 +19,11 @@
 #ifndef __GIMP_STATUSBAR_H__
 #define __GIMP_STATUSBAR_H__
 
-#include <gtk/gtkstatusbar.h>
+#include <gtk/gtk.h>
+#include <gtk/gtkhbox.h>
 
 G_BEGIN_DECLS
 
-
 /*  maximal length of the format string for the cursor-coordinates  */
 #define CURSOR_FORMAT_LENGTH 32
 
@@ -35,12 +35,16 @@ G_BEGIN_DECLS
 #define GIMP_IS_STATUSBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_STATUSBAR))
 #define GIMP_STATUSBAR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_STATUSBAR, GimpStatusbarClass))
 
-
 typedef struct _GimpStatusbarClass GimpStatusbarClass;
 
 struct _GimpStatusbar
 {
-  GtkStatusbar      parent_instance;
+  GtkHBox parent_widget;
+
+  GSList *messages;
+  GSList *keys;
+  guint seq_context_id;
+  guint seq_message_id;
 
   GimpDisplayShell *shell;
 
@@ -53,35 +57,54 @@ struct _GimpStatusbar
   GtkWidget        *progressbar;
   guint             progressid;
   GtkWidget        *cancelbutton;
+
+  GdkWindow *grip_window;
+  
 };
 
 struct _GimpStatusbarClass
 {
-  GtkStatusbarClass  parent_class;
-};
-
+  GtkHBoxClass parent_class;
 
-GType       gimp_statusbar_get_type     (void) G_GNUC_CONST;
+  GMemChunk *messages_mem_chunk;
 
-GtkWidget * gimp_statusbar_new          (GimpDisplayShell *shell);
+  void  (*text_pushed) (GimpStatusbar   *statusbar,
+                        const gchar     *context_id,
+                        const gchar     *text);
+  void  (*text_popped) (GimpStatusbar   *statusbar,
+                        const gchar     *context_id,
+                        const gchar     *text);
+
+  /* Padding for future expansion */
+  void (*_gimp_reserved1) (void);
+  void (*_gimp_reserved2) (void);
+  void (*_gimp_reserved3) (void);
+  void (*_gimp_reserved4) (void);
+};
 
-void        gimp_statusbar_push         (GimpStatusbar    *statusbar,
-                                         const gchar      *context_id,
-                                         const gchar      *message);
-void        gimp_statusbar_push_coords  (GimpStatusbar    *statusbar,
-                                         const gchar      *context_id,
-                                         const gchar      *title,
-                                         gdouble           x,
-                                         const gchar      *separator,
-                                         gdouble           y);
-void        gimp_statusbar_pop          (GimpStatusbar    *statusbar,
-                                         const gchar      *context_id);
-
-void	    gimp_statusbar_set_cursor   (GimpStatusbar    *statusbar,
-                                         gdouble           x,
-                                         gdouble           y);
-void	    gimp_statusbar_clear_cursor (GimpStatusbar    *statusbar);
 
+GType       gimp_statusbar_get_type            (void) G_GNUC_CONST;
+GtkWidget * gimp_statusbar_new                 (GimpDisplayShell *shell);
+void        gimp_statusbar_pop                 (GimpStatusbar    *statusbar,
+                                                const gchar      *context);
+void        gimp_statusbar_remove              (GimpStatusbar    *statusbar,
+                                                const gchar      *context,
+                                                guint             message_id);
+guint       gimp_statusbar_push_coords         (GimpStatusbar    *statusbar,
+                                                const gchar      *context,
+                                                const gchar      *title,
+                                                gdouble           x,
+                                                const gchar      *separator,
+                                                gdouble           y);
+guint       gimp_statusbar_push                (GimpStatusbar    *statusbar,
+                                                const gchar      *context,
+                                                const gchar      *message);
+void	    gimp_statusbar_set_cursor          (GimpStatusbar    *statusbar,
+                                                gdouble           x,
+                                                gdouble           y);
+void	    gimp_statusbar_clear_cursor        (GimpStatusbar    *statusbar);
+guint       gimp_statusbar_get_context_id      (GimpStatusbar    *statusbar,
+                                                const gchar      *context_description);
 
 G_END_DECLS
 
Index: ../core/gimpmarshal.list
===================================================================
RCS file: /cvs/gnome/gimp/app/core/gimpmarshal.list,v
retrieving revision 1.18
diff -u -p -u -p -r1.18 gimpmarshal.list
--- a/../core/gimpmarshal.list	16 Apr 2004 12:09:46 -0000	1.18
+++ b/../core/gimpmarshal.list	19 Jun 2004 12:59:16 -0000
@@ -44,3 +44,4 @@ VOID: POINTER
 VOID: STRING
 VOID: STRING, FLAGS
 VOID: VOID
+VOID: UINT, STRING
