--- gtk/gtkmenubar.c.old	2006-07-03 08:25:06.000000000 +0800
+++ gtk/gtkmenubar.c	2006-10-14 02:10:26.000000000 +0800
@@ -38,6 +38,17 @@
 #include "gtkwindow.h"
 #include "gtkprivate.h"
 #include "gtkalias.h"
+// For mac menubar
+#include "gdk/x11/gdkx.h"
+#include "gdk/x11/gdkwindow-x11.h"
+#include "gtkbox.h"
+#include "gtkdrawingarea.h"
+#include "gtkhbox.h"
+#include "gtklabel.h"
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
 
 
 #define BORDER_SPACING  0
@@ -55,6 +66,8 @@
 {
   GtkPackDirection pack_direction;
   GtkPackDirection child_pack_direction;
+  GtkWindow*       orig_toplevel_win;    // original window, obtained in map()
+  GtkWindow*       mbar_toplevel_win;    // could be NULL, if disabled
 };
 
 #define GTK_MENU_BAR_GET_PRIVATE(o)  \
@@ -89,9 +102,129 @@
 
 G_DEFINE_TYPE (GtkMenuBar, gtk_menu_bar, GTK_TYPE_MENU_SHELL)
 
+
+/*
+ * Mac Menubar options
+ */
+
+static gboolean option_no_mac()
+{
+  static gboolean no_mac_set = FALSE;
+  static gboolean no_mac = FALSE;
+  char* env = NULL;
+  if (no_mac_set) return no_mac;
+  env = getenv("GTK_MENUBAR_NO_MAC");
+  if (env == NULL)
+    env = "acroread gnome-panel";
+  if (strcmp(env, "1") == 0)
+    no_mac = TRUE;
+  else
+  {
+    gchar** no_mac_prgs = g_strsplit(env, " ", 0);
+    gchar** p = no_mac_prgs;
+    gchar* prg = g_get_prgname();
+    while (*p != NULL)
+    {
+      if (strcmp(*p, prg) == 0)
+      {
+        no_mac = TRUE;
+        break;
+      }
+      p ++;
+    }
+    g_strfreev(no_mac_prgs);
+  }
+  no_mac_set = TRUE;
+  return no_mac;
+}
+
+/*
+ * Mac Menubar event handlers/callbacks
+ */
+
+static gboolean orig_toplevel_on_destroy (GtkWidget *widget, gpointer my_data)
+{
+  GtkMenuBar* menubar = (GtkMenuBar*) my_data;
+  GtkMenuBarPrivate* priv = GTK_MENU_BAR_GET_PRIVATE (menubar);
+  if (priv->mbar_toplevel_win)
+  {
+    gtk_widget_destroy (GTK_WIDGET (priv->mbar_toplevel_win));
+    priv->mbar_toplevel_win = NULL;
+    priv->orig_toplevel_win = NULL;
+  }
+  return FALSE;
+}
+
+static void orig_toplevel_on_event_after (GtkWidget*  widget,
+                                          GdkEvent*   event,
+                                          gpointer    my_data)
+{
+  GtkMenuBar* menubar = (GtkMenuBar*) my_data;
+  GtkMenuBarPrivate* priv = GTK_MENU_BAR_GET_PRIVATE (menubar);
+  if (! priv->mbar_toplevel_win) return;
+  if (event->type == GDK_FOCUS_CHANGE && event->focus_change.in)
+    gtk_widget_show (GTK_WIDGET (priv->mbar_toplevel_win));
+}
+
+static void gtk_menu_bar_map (GtkWidget *widget)
+{
+  GtkMenuBar* menubar = GTK_MENU_BAR (widget);
+  GtkMenuBarPrivate* priv = GTK_MENU_BAR_GET_PRIVATE (menubar);
+
+  if (!priv->mbar_toplevel_win && !option_no_mac())
+    {
+      Atom typehints[2];
+      GdkGeometry geometry;
+      // Setup menubar's original top-level window
+      priv->orig_toplevel_win
+        = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (menubar)));
+      g_signal_connect (GTK_WIDGET (priv->orig_toplevel_win), "destroy",
+                        G_CALLBACK (orig_toplevel_on_destroy), menubar);
+      g_signal_connect (GTK_WIDGET (priv->orig_toplevel_win), "event-after",
+                        G_CALLBACK (orig_toplevel_on_event_after), menubar);
+      // Create new top-level window for menubar
+      priv->mbar_toplevel_win
+        = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL));
+      gtk_window_set_transient_for (priv->mbar_toplevel_win, priv->orig_toplevel_win);
+      gtk_window_set_title (priv->mbar_toplevel_win, "GTK MENUBAR");
+      gtk_window_set_resizable (priv->mbar_toplevel_win, FALSE);
+      gtk_window_set_decorated (priv->mbar_toplevel_win, FALSE);
+      gtk_window_set_type_hint (priv->mbar_toplevel_win,
+                                GDK_WINDOW_TYPE_HINT_DOCK);
+      // Set geometry hints
+      geometry.max_width = geometry.min_width = -1;
+      geometry.max_height = geometry.min_height = -1;
+      gtk_window_set_geometry_hints (priv->mbar_toplevel_win,
+                                     GTK_WIDGET (priv->mbar_toplevel_win),
+                                     &geometry,
+                                     GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
+      gtk_window_stick (priv->mbar_toplevel_win);
+      g_signal_connect (GTK_WIDGET (priv->mbar_toplevel_win), "delete-event",
+                        G_CALLBACK (gtk_widget_hide_on_delete), menubar);
+      // Menubar
+      gtk_widget_reparent (GTK_WIDGET (menubar),
+                           GTK_WIDGET (priv->mbar_toplevel_win));
+      // Show everything!
+      gtk_widget_show_all (GTK_WIDGET (priv->mbar_toplevel_win));
+      typehints[0] = XInternAtom (gdk_display, "_KDE_NET_WM_WINDOW_TYPE_TOPMENU", FALSE);
+      typehints[1] = XInternAtom (gdk_display, "_NET_WM_WINDOW_TYPE_DOCK", FALSE);
+      XChangeProperty (gdk_display,
+                       GDK_WINDOW_XID(GTK_WIDGET (priv->mbar_toplevel_win)->window),
+                       XInternAtom (gdk_display, "_NET_WM_WINDOW_TYPE", FALSE),
+                       XA_ATOM, 32, PropModeReplace,
+                       (const guchar *) typehints, 2);
+      gtk_window_move (priv->mbar_toplevel_win, 0, 0);
+    }
+
+  (* GTK_WIDGET_CLASS (gtk_menu_bar_parent_class)->map) (GTK_WIDGET (menubar));
+}
+
 static void
 gtk_menu_bar_init (GtkMenuBar *object)
 {
+  GtkMenuBarPrivate* priv = GTK_MENU_BAR_GET_PRIVATE (object);
+  priv->mbar_toplevel_win = 0;
+  priv->orig_toplevel_win = 0;
 }
 
 static void
@@ -114,6 +247,7 @@
   widget_class->size_allocate = gtk_menu_bar_size_allocate;
   widget_class->expose_event = gtk_menu_bar_expose;
   widget_class->hierarchy_changed = gtk_menu_bar_hierarchy_changed;
+  widget_class->map = gtk_menu_bar_map;
   
   menu_shell_class->submenu_placement = GTK_TOP_BOTTOM;
   menu_shell_class->get_popup_delay = gtk_menu_bar_get_popup_delay;
