--- gtk/gtkmenubar.orig	2008-01-02 03:01:19.000000000 -0500
+++ gtk/gtkmenubar.c	2008-01-02 03:01:06.000000000 -0500
@@ -39,10 +39,21 @@
 #include "gtkprivate.h"
 #include "gtkalias.h"
 
+#ifdef GDK_WINDOWING_X11
+#define GNOME_GLOBAL_MENU
+#endif
+
+#ifdef GNOME_GLOBAL_MENU
+#include "x11/gdkx.h"
+#define INCLUDE_SOURCE
+#include "gtkmenuembed-x11.h"
+#undef INCLUDE_SOURCE
+#endif
 
 #define BORDER_SPACING  0
 #define DEFAULT_IPADDING 1
 
+#define LOG_FUNC_NAME g_message("%s invoked", __func__)
 /* Properties */
 enum {
   PROP_0,
@@ -55,6 +66,18 @@
 {
   GtkPackDirection pack_direction;
   GtkPackDirection child_pack_direction;
+#ifdef GNOME_GLOBAL_MENU
+  GlobalMenuSocket * socket;
+  gboolean connected; /*socket is connect-less, so this flag =whether menuserver exists*/
+  gboolean globalized;
+  GtkRequisition container_requisition;
+  GtkAllocation container_allocation;
+  GdkWindow * float_window;
+  GdkWindow * container_window;
+  GdkWindow * master_window;
+  gint ythickness_backup;
+  gint xthickness_backup;
+#endif
 };
 
 #define GTK_MENU_BAR_GET_PRIVATE(o)  \
@@ -82,6 +105,23 @@
 static gint gtk_menu_bar_get_popup_delay   (GtkMenuShell    *menu_shell);
 static void gtk_menu_bar_move_current      (GtkMenuShell     *menu_shell,
                                             GtkMenuDirectionType direction);
+#ifdef GNOME_GLOBAL_MENU
+static void gtk_menu_bar_finalize            (GObject         *object);
+static void gtk_menu_bar_realize            (GtkWidget         *widget);
+static void gtk_menu_bar_unrealize            (GtkWidget         *widget);
+static void gtk_menu_bar_map				(GtkWidget * widget);
+static void gtk_menu_bar_unmap				(GtkWidget * widget);
+static gboolean gtk_menu_bar_motion				(GtkWidget * widget, GdkEventMotion * event);
+static gboolean gtk_menu_bar_delete_event				(GtkWidget * widget, GdkEventAny * event);
+static void gtk_menu_bar_real_insert (GtkMenuShell * menu_shell, GtkWidget * child, gint position);
+static void gtk_menu_bar_notify_size_allocate_cb (GlobalMenuSocket * socket, GlobalMenuNotify * notify, GtkMenuBar * menubar);
+static void gtk_menu_bar_notify_server_destroy_cb (GlobalMenuSocket * socket, GlobalMenuNotify * notify, GtkMenuBar * menubar);
+static void gtk_menu_bar_notify_server_new_cb (GlobalMenuSocket * socket, GlobalMenuNotify * notify, GtkMenuBar * menubar);
+static void gtk_menu_bar_globalize(GtkMenuBar * menubar);
+static void gtk_menu_bar_unglobalize(GtkMenuBar * menubar);
+static void gtk_menu_bar_connect_to_menu_server(GtkMenuBar * menubar);
+static void gtk_menu_bar_ensure_style (GtkWidget * widget);
+#endif
 
 static GtkShadowType get_shadow_type   (GtkMenuBar      *menubar);
 
@@ -112,6 +152,16 @@
   menu_shell_class->get_popup_delay = gtk_menu_bar_get_popup_delay;
   menu_shell_class->move_current = gtk_menu_bar_move_current;
 
+#ifdef GNOME_GLOBAL_MENU
+  gobject_class->finalize = gtk_menu_bar_finalize;
+  widget_class->realize = gtk_menu_bar_realize;  
+  widget_class->unrealize = gtk_menu_bar_unrealize;  
+  widget_class->delete_event = gtk_menu_bar_delete_event;  
+  widget_class->map = gtk_menu_bar_map;
+  widget_class->unmap = gtk_menu_bar_unmap;
+  widget_class->motion_notify_event = gtk_menu_bar_motion;
+  menu_shell_class->insert = gtk_menu_bar_real_insert;
+#endif
   binding_set = gtk_binding_set_by_class (class);
   gtk_binding_entry_add_signal (binding_set,
 				GDK_Left, 0,
@@ -220,6 +270,19 @@
 static void
 gtk_menu_bar_init (GtkMenuBar *object)
 {
+#ifdef GNOME_GLOBALMENU
+	GtkMenuBarPrivate * priv;
+	priv = GTK_MENU_BAR_GET_PRIVATE(object);
+
+    priv->connected = FALSE;
+	priv->socket = NULL;
+    priv->globalized = FALSE;
+	priv->container_window = NULL;
+	priv->float_window = NULL;
+	priv->master_window = NULL;
+	priv->ythickness_backup = -1;
+	priv->xthickness_backup = -1;
+#endif
 }
 
 GtkWidget*
@@ -291,6 +354,9 @@
   requisition->width = 0;
   requisition->height = 0;
   
+#ifdef GNOME_GLOBAL_MENU
+  gtk_menu_bar_ensure_style(widget); 
+#endif
   if (GTK_WIDGET_VISIBLE (widget))
     {
       menu_bar = GTK_MENU_BAR (widget);
@@ -350,6 +416,15 @@
 	  requisition->height += widget->style->ythickness * 2;
 	}
     }
+#ifdef GNOME_GLOBAL_MENU
+/****store the requisition as container window's requistion****/
+	priv->container_requisition = *requisition;
+	if(priv->globalized){
+/******tell the parent my requisition is 0 **********/
+		requisition->width = 0;
+		requisition->height = 0;
+	}
+#endif
 }
 
 static void
@@ -368,8 +443,14 @@
   gint ltr_x, ltr_y;
   gint ipadding;
 
+#ifdef GNOME_GLOBAL_MENU
+LOG_FUNC_NAME;
+  gboolean need_allocate_child = FALSE;
+#endif
   g_return_if_fail (GTK_IS_MENU_BAR (widget));
+#ifndef GNOME_GLOBAL_MENU
   g_return_if_fail (allocation != NULL);
+#endif
 
   menu_bar = GTK_MENU_BAR (widget);
   menu_shell = GTK_MENU_SHELL (widget);
@@ -377,12 +458,36 @@
 
   direction = gtk_widget_get_direction (widget);
 
+#ifdef GNOME_GLOBAL_MENU
+  gtk_menu_bar_ensure_style(widget); 
+#endif
+
+#ifdef GNOME_GLOBAL_MENU
+  if(!allocation){ /*if allocation == NULL, it is from _cb, allocate chilrens*/
+	/*window resizing is handled in _cb*/
+	allocation = &priv->container_allocation;
+    need_allocate_child = TRUE;
+  }else{ /*if it is globalized, don't allocate childrens*/
+#endif
   widget->allocation = *allocation;
   if (GTK_WIDGET_REALIZED (widget))
     gdk_window_move_resize (widget->window,
 			    allocation->x, allocation->y,
 			    allocation->width, allocation->height);
 
+#ifdef GNOME_GLOBAL_MENU
+  if (GTK_WIDGET_REALIZED (widget))
+	  if (!priv->globalized)
+		gdk_window_move_resize (priv->container_window,
+					0, 0,
+					allocation->width, allocation->height);
+#endif
+
+#ifdef GNOME_GLOBAL_MENU
+      if (!priv->globalized) need_allocate_child = TRUE;
+  }
+  if(!need_allocate_child) return;
+#endif
   gtk_widget_style_get (widget, "internal-padding", &ipadding, NULL);
   
   if (menu_shell->children)
@@ -507,7 +612,17 @@
 gtk_menu_bar_paint (GtkWidget    *widget,
                     GdkRectangle *area)
 {
+#ifdef GNOME_GLOBAL_MENU
+  GtkMenuBar * menubar;
+  GtkMenuBarPrivate * priv;
+
+  menubar = GTK_MENU_BAR(widget);
+  priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+#endif
   g_return_if_fail (GTK_IS_MENU_BAR (widget));
+#ifdef GNOME_GLOBAL_MENU
+  if(priv->globalized) return;
+#endif
 
   if (GTK_WIDGET_DRAWABLE (widget))
     {
@@ -648,6 +763,9 @@
 
   if (!menubars)
     {
+#ifdef GNOME_GLOBAL_MENU
+	  gtk_menu_bar_connect_to_menu_server(menubar);
+#endif
       g_signal_connect (window,
 			"key_press_event",
 			G_CALLBACK (window_key_press_handler),
@@ -938,5 +1056,401 @@
     }
 }
 
+#ifdef GNOME_GLOBAL_MENU
+/************* Global menu patched methods ***************/
+static void gtk_menu_bar_finalize            (GObject         *object){
+
+	GtkMenuBar * menubar;
+	GtkMenuBarPrivate * priv;
+LOG_FUNC_NAME;
+	
+	menubar = GTK_MENU_BAR(object);
+	priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+    if(priv->globalized){
+		gtk_menu_bar_unglobalize(menubar);
+	}
+	if(priv->connected){
+		global_menu_socket_free(priv->socket);
+	}
+	G_OBJECT_CLASS(gtk_menu_bar_parent_class)->finalize(object);
+}
+
+static void 
+gtk_menu_bar_globalize(GtkMenuBar * menubar){
+  GtkMenuBarPrivate * priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+  GtkWidget * toplevel = NULL;
+LOG_FUNC_NAME;
+  if(priv->globalized == FALSE){
+	  toplevel = gtk_widget_get_toplevel(GTK_WIDGET(menubar));
+	  if(GTK_WIDGET_TOPLEVEL(toplevel) 
+		&& !GTK_WIDGET_NO_WINDOW(toplevel)
+		&& gdk_window_get_type_hint(toplevel->window) 
+		== GDK_WINDOW_TYPE_HINT_NORMAL){
+	      priv->master_window = toplevel->window;
+		  GlobalMenuNotify notify;
+		  priv->globalized = TRUE;
+		  g_message("Master window found:%x", priv->master_window);
+		  if(GTK_WIDGET_REALIZED(menubar)){
+			  gdk_window_reparent(priv->container_window, priv->float_window, 0, 0); 
+			  notify.type = GM_NOTIFY_NEW;
+			  notify.ClientNew.client_xid = GDK_WINDOW_XWINDOW(priv->socket->window);
+			  notify.ClientNew.float_xid = GDK_WINDOW_XWINDOW(priv->float_window);
+			  notify.ClientNew.master_xid = GDK_WINDOW_XWINDOW(priv->master_window);
+			  global_menu_socket_send(priv->socket, &notify);
+
+			  gtk_menu_bar_size_allocate(GTK_WIDGET(menubar), NULL); /*allocate according to container_allocation*/
+			  if(GTK_WIDGET_MAPPED(menubar)){
+				gtk_widget_queue_resize(GTK_WIDGET(menubar));
+				gdk_window_hide(priv->float_window); /*perhaps we need to hide it*/
+			  }else{
+				gtk_widget_queue_resize_no_redraw(GTK_WIDGET(menubar));
+			   }
+		  }
+	  } else {
+		priv->master_window = NULL;
+	  }
+  }
+}
+
+static void 
+gtk_menu_bar_unglobalize(GtkMenuBar * menubar){
+  GtkMenuBarPrivate * priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+LOG_FUNC_NAME;
+  if(priv->globalized){
+	  GlobalMenuNotify notify;
+	  priv->globalized = FALSE;
+	  priv->pack_direction = GTK_PACK_DIRECTION_LTR; /*perhaps need to restore users pref here(for RTL languages)*/
+	  if(GTK_WIDGET_REALIZED(menubar)){
+		  gdk_window_reparent(priv->container_window, 
+				GTK_WIDGET(menubar)->window, 0, 0); 
+		  if(GTK_WIDGET_MAPPED(menubar)){
+			  gdk_window_hide(priv->float_window);
+			  gtk_widget_queue_resize(GTK_WIDGET(menubar));
+		  }else
+			  gtk_widget_queue_resize_no_redraw(GTK_WIDGET(menubar));
+	  }
+	  notify.type = GM_NOTIFY_DESTROY;
+      notify.ClientDestroy.client_xid = GDK_WINDOW_XWINDOW(priv->socket->window);
+	  notify.ClientDestroy.float_xid = GDK_WINDOW_XWINDOW(priv->float_window);
+	  notify.ClientDestroy.master_xid = GDK_WINDOW_XWINDOW(priv->master_window);
+	  global_menu_socket_send(priv->socket, &notify);
+  }
+}
+static void
+gtk_menu_bar_realize(GtkWidget * widget)
+{
+  GtkMenuBar * menubar = NULL;
+  GtkMenuBarPrivate * priv = NULL;
+  GdkWindowAttr attributes;
+  gint attributes_mask = 0;
+
+  menubar = GTK_MENU_BAR(widget);
+  priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+LOG_FUNC_NAME;
+
+  g_return_if_fail (GTK_IS_MENU_SHELL (widget));
+
+//  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); set by parent class realize
+  GTK_WIDGET_CLASS(gtk_menu_bar_parent_class)->realize(widget);
+  //gdk_window_set_user_data (widget->window, widget); I think it is also set
+// parent realize will also create widget->window
+
+
+/*Then we create the float window*/
+
+  priv->container_allocation.x = 0;
+  priv->container_allocation.y = 0;
+  priv->container_allocation.width = priv->container_requisition.width;
+  priv->container_allocation.height = priv->container_requisition.height;
+
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = priv->container_allocation.width;
+  attributes.height = priv->container_allocation.height;
+  attributes.window_type = GDK_WINDOW_TEMP;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= (GDK_EXPOSURE_MASK |
+				GDK_STRUCTURE_MASK |
+			    GDK_KEY_PRESS_MASK |
+			    GDK_ENTER_NOTIFY_MASK |
+			    GDK_LEAVE_NOTIFY_MASK);
+
+  attributes.type_hint = GDK_WINDOW_TYPE_HINT_DOCK;
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;// | GDK_WA_TYPE_HINT;
+  priv->float_window = gdk_window_new (gtk_widget_get_root_window (widget), &attributes, attributes_mask);
+
+  gdk_window_stick(priv->float_window);
+  gdk_window_set_user_data (priv->float_window, widget);
+
+/*********Then the container window *********/
+  attributes.x = 0;
+  attributes.y = 0;
+  attributes.width = priv->container_allocation.width;
+  attributes.height = priv->container_allocation.height;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.event_mask = (gtk_widget_get_events (widget) |
+               GDK_EXPOSURE_MASK |
+               GDK_BUTTON1_MOTION_MASK |
+               GDK_POINTER_MOTION_HINT_MASK |
+               GDK_BUTTON_PRESS_MASK |
+                GDK_BUTTON_RELEASE_MASK);
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  priv->container_window = gdk_window_new (widget->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (priv->container_window, widget);
+/*Then move all the exsited menuitems's gdk parent window to the container */
+  gtk_container_forall(GTK_CONTAINER(widget), 
+			(GtkCallback)(gtk_widget_set_parent_window), 
+			(gpointer)(priv->container_window));
+
+/*Set some painting hints*/
+  gtk_menu_bar_ensure_style(widget);
+  gtk_style_set_background (widget->style, widget->window, GTK_WIDGET_STATE (menubar));
+  gtk_style_set_background (widget->style, priv->container_window, GTK_WIDGET_STATE (menubar));
+  gtk_style_set_background (widget->style, priv->float_window, GTK_WIDGET_STATE (menubar));
+  gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
+  if(priv->connected){
+		gtk_menu_bar_globalize(menubar);
+	}
+
+}
+
+static void
+gtk_menu_bar_unrealize(GtkWidget * widget)
+{
+  GtkMenuBar * menubar = NULL;
+  GtkMenuBarPrivate * priv = NULL;
+
+LOG_FUNC_NAME;
+
+  menubar = GTK_MENU_BAR(widget);
+  priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+
+  if(priv->globalized) gtk_menu_bar_unglobalize(menubar);
+
+  gdk_window_set_user_data (priv->container_window, NULL);
+  gdk_window_destroy (priv->container_window);
+  priv->container_window = NULL;
+
+  gdk_window_set_user_data (priv->float_window, NULL);
+  gdk_window_destroy (priv->float_window);
+  priv->float_window = NULL;
+  GTK_WIDGET_CLASS(gtk_menu_bar_parent_class)->unrealize(widget); 
+}
+
+static void
+gtk_menu_bar_map_child (GtkWidget *child,
+             gpointer   client_data)
+{
+  if (GTK_WIDGET_VISIBLE (child) &&
+      GTK_WIDGET_CHILD_VISIBLE (child) &&
+      !GTK_WIDGET_MAPPED (child))
+    gtk_widget_map (child);
+}
+
+static void
+gtk_menu_bar_map(GtkWidget * widget){
+  GtkMenuBar * menubar = NULL;
+  GtkMenuBarPrivate * priv = NULL;
+LOG_FUNC_NAME;
+
+  menubar = GTK_MENU_BAR(widget);
+  priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+
+  gtk_container_forall (GTK_CONTAINER (widget),
+            gtk_menu_bar_map_child,
+            NULL);
+
+  gdk_window_move_resize(priv->container_window,
+		0, 0, 
+        priv->container_allocation.width,
+        priv->container_allocation.height);
+
+  gdk_window_show(priv->container_window);
+  if(priv->globalized){
+	 gdk_window_show(priv->float_window);
+
+  }
+	  gdk_window_show(widget->window);
+}
+
+static void
+gtk_menu_bar_unmap(GtkWidget * widget){
+  GtkMenuBar * menubar = NULL;
+  GtkMenuBarPrivate * priv = NULL;
+LOG_FUNC_NAME;
+
+  menubar = GTK_MENU_BAR(widget);
+  priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); 
+
+  gdk_window_hide(priv->float_window);
+  gdk_window_hide(widget->window);
+}
+
+/*****************************
+ * overide gtk_menu_shell_insert, because we want to set proper parent gdkwindow
+ * *****************/
+static void
+gtk_menu_bar_real_insert(GtkMenuShell * menu_shell, GtkWidget * child, gint position){
+  GtkMenuBar * menubar = NULL;
+  GtkMenuBarPrivate * priv = NULL;
+LOG_FUNC_NAME;
+
+  menubar = GTK_MENU_BAR(menu_shell);
+  priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+
+  GTK_MENU_SHELL_CLASS(gtk_menu_bar_parent_class)->insert(menu_shell, child, position);
+  gtk_widget_set_parent_window(child, priv->container_window);
+}
+static gboolean 
+gtk_menu_bar_motion (GtkWidget * widget, 
+		GdkEventMotion * event){
+  GtkMenuBar * menubar = NULL;
+  GtkMenuBarPrivate * priv = NULL;
+
+  menubar = GTK_MENU_BAR(widget);
+  priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+
+	if(GTK_WIDGET_CLASS(gtk_menu_bar_parent_class)->motion_notify_event)
+		return GTK_WIDGET_CLASS(gtk_menu_bar_parent_class)->motion_notify_event(widget, event);
+	if(event->is_hint){
+		LOG_FUNC_NAME;
+	}
+	return TRUE;
+}
+static gboolean gtk_menu_bar_delete_event(GtkWidget * widget, GdkEventAny * event){
+	GtkMenuBar * menubar = GTK_MENU_BAR(widget);
+	GtkMenuBarPrivate * priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+LOG_FUNC_NAME;
+	if(priv->globalized && event->window == priv->float_window){
+		/*If we receive a delete_event from float_window, and we are globalized,
+          this is a signal to unglobalize. */
+		gtk_menu_bar_unglobalize(menubar);
+		return TRUE;
+	}
+	return FALSE;		
+}
+static void
+gtk_menu_bar_notify_size_allocate_cb(GlobalMenuSocket * socket, 
+		GlobalMenuNotify * notify,
+		GtkMenuBar * menubar){
+	GtkMenuBarPrivate * priv;
+	GtkAllocation allocation;
+	priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+
+    g_return_if_fail( priv->connected );
+	g_return_if_fail( notify->SizeAllocate.server_xid == socket->dest_xid); /*if not from out server*/
+
+	allocation.width = notify->SizeAllocate.width;
+	allocation.height = notify->SizeAllocate.height;
+	g_message("Size Allocate Notify Received: %d, %d",allocation.width, allocation.height);
+
+    if(priv->container_allocation.width == allocation.width &&
+		priv->container_allocation.height == allocation.height)
+		return; /*If the width and height didn't actually change*/
+	priv->container_allocation.width = allocation.width;
+	priv->container_allocation.height = allocation.height;
+
+	gdk_window_resize(priv->float_window, 
+		allocation.width, allocation.height);
+	gdk_window_resize(priv->container_window, 
+		allocation.width, allocation.height);
+
+	gtk_menu_bar_ensure_style(GTK_WIDGET(menubar));
+
+/****auto change direction if size is not enough******/
+    if(allocation.width > allocation.height){
+/****Perhaps we need new variable to store the user's prefs of direction****/
+		priv->pack_direction = GTK_PACK_DIRECTION_LTR;
+		priv->child_pack_direction = GTK_PACK_DIRECTION_LTR;
+	} else {
+		priv->pack_direction = GTK_PACK_DIRECTION_TTB;
+		priv->child_pack_direction = GTK_PACK_DIRECTION_LTR;
+	}
+
+	gtk_menu_bar_size_allocate(GTK_WIDGET(menubar), NULL);
+}
+static void
+gtk_menu_bar_notify_server_destroy_cb(GlobalMenuSocket * socket, 
+		GlobalMenuNotify * notify,
+		GtkMenuBar * menubar){
+	GtkMenuBarPrivate * priv;
+
+	priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+    g_return_if_fail( priv->connected );
+	g_return_if_fail( notify->ServerDestroy.server_xid == socket->dest_xid); /*if not from our server*/
+    g_message("Menu Server dies, move the menubar back!!");
+		priv->connected = FALSE;
+		gtk_menu_bar_unglobalize(menubar);
+}
+static void
+gtk_menu_bar_notify_server_new_cb(GlobalMenuSocket * socket, 
+		GlobalMenuNotify * notify,
+		GtkMenuBar * menubar){
+	GtkMenuBarPrivate * priv;
+	priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+    g_return_if_fail( !priv->connected ); 
+	/*if alread connected to another server, do nothing.*/
+	if(priv->connected == FALSE){
+	  priv->connected = global_menu_socket_connect_by_xid(priv->socket, 
+									notify->ServerNew.server_xid);
+		if(priv->connected){
+		  g_message("Menu Server Launched, float the menubar !!");
+		  gtk_menu_bar_globalize(menubar);
+		}
+	}
+}
+static void
+gtk_menu_bar_ensure_style (GtkWidget * widget){
+	GtkMenuBar * menubar = GTK_MENU_BAR(widget);
+	GtkMenuBarPrivate * priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+	GtkStyle * style;
+
+	gtk_widget_ensure_style(GTK_WIDGET(menubar));
+	style = GTK_WIDGET(menubar)->style;
+
+	if(priv->ythickness_backup == -1 || priv->xthickness_backup == -1){
+		priv->xthickness_backup = style->xthickness;
+		priv->ythickness_backup = style->ythickness;
+	}
+	if(priv->globalized){
+		if(priv->pack_direction == GTK_PACK_DIRECTION_LTR
+		|| priv->pack_direction == GTK_PACK_DIRECTION_RTL){
+			style->ythickness = 0;
+			style->xthickness = priv->xthickness_backup;
+		}
+        else {
+			style->xthickness = 0;
+			style->ythickness = priv->ythickness_backup;
+		}
+	}
+}
+static void gtk_menu_bar_connect_to_menu_server(GtkMenuBar * menubar){
+  GtkMenuBarPrivate * priv = GTK_MENU_BAR_GET_PRIVATE(menubar);
+
+  priv->socket = global_menu_socket_new(MENU_CLIENT_NAME, menubar);
+  global_menu_socket_set_callback(priv->socket, 
+	GM_NOTIFY_SIZE_ALLOCATE, 
+	(GlobalMenuCallback) gtk_menu_bar_notify_size_allocate_cb);
+  global_menu_socket_set_callback(priv->socket,
+	GM_NOTIFY_SERVER_NEW,
+	(GlobalMenuCallback) gtk_menu_bar_notify_server_new_cb);
+  global_menu_socket_set_callback(priv->socket,
+	GM_NOTIFY_SERVER_DESTROY,
+	(GlobalMenuCallback) gtk_menu_bar_notify_server_destroy_cb);
+/**we will receive notifications even if don't connect, so always check priv->connect (or priv->globalized)
+ * if we want to make sure we are connected!***/
+  priv->connected = global_menu_socket_connect_by_name(priv->socket, 
+									MENU_SERVER_NAME);
+}
+#endif
 #define __GTK_MENU_BAR_C__
 #include "gtkaliasdef.c"
--- /dev/null	2008-01-02 00:50:55.502092870 -0500
+++ gtk/gtkmenuembed-x11.h	2008-01-02 01:56:38.000000000 -0500
@@ -0,0 +1,277 @@
+typedef enum {
+	GM_NOTIFY_NOT_GM,
+	GM_NOTIFY_MIN,
+	GM_NOTIFY_NEW,
+	GM_NOTIFY_DESTROY,
+	GM_NOTIFY_SERVER_NEW,
+	GM_NOTIFY_SERVER_DESTROY,
+	GM_NOTIFY_SIZE_ALLOCATE,
+	GM_NOTIFY_MAX,
+} GlobalMenuNotifyType;
+#define ATOM_STRING "_GTKMENUBAR_EMBED"
+#define MENU_SERVER_NAME "GTK MENU BAR SERVER"
+#define MENU_CLIENT_NAME "GTK MENU BAR CLIENT"
+
+typedef struct _GlobalMenuNotify {
+	GlobalMenuNotifyType type;
+	union{
+	struct {
+		gulong param1;
+		gulong param2;
+		gulong param3;
+	}; /*general*/
+		struct {
+			Window client_xid;
+			Window float_xid;
+			Window master_xid;
+		} ClientNew;
+		struct {
+			Window client_xid;
+			Window float_xid;
+			Window master_xid;
+		} ClientDestroy;
+		struct {
+			Window server_xid;
+		} ServerNew;
+		struct {
+			Window server_xid;
+		} ServerDestroy;
+		struct {
+			Window server_xid;
+			glong width;
+			glong height;
+		} SizeAllocate;
+	};
+} GlobalMenuNotify;
+
+typedef struct _GlobalMenuSocket GlobalMenuSocket;
+
+typedef void (*GlobalMenuCallback)(GlobalMenuSocket* socket, 
+	GlobalMenuNotify * notify, gpointer data);
+
+struct _GlobalMenuSocket {
+	gchar * name;
+	GdkWindow * window;
+	GdkDisplay * display;
+	GlobalMenuCallback callbacks[GM_NOTIFY_MAX];
+	gpointer userdata;
+	Window dest_xid; // Where to connect to
+};
+
+
+#ifdef INCLUDE_SOURCE
+static const gchar * global_menu_notify_get_name(GlobalMenuNotifyType type){
+#define CASE(x) case x: return # x;
+	switch(type){
+	CASE(GM_NOTIFY_NOT_GM)
+	CASE(GM_NOTIFY_NEW)
+	CASE(GM_NOTIFY_DESTROY)
+	CASE(GM_NOTIFY_SERVER_NEW)
+	CASE(GM_NOTIFY_SERVER_DESTROY)
+	CASE(GM_NOTIFY_SIZE_ALLOCATE)
+	default:
+		return "Unknown notification";
+	}
+#undef CASE
+}
+
+static gboolean global_menu_xevent_to_notify(XEvent * xevent, GlobalMenuNotify * notify){
+	GdkDisplay * display = NULL;
+
+	if(notify == NULL){ 
+		g_warning("notify is NULL\n");
+		return FALSE;
+	}
+
+	notify->type = GM_NOTIFY_NOT_GM;
+	if(xevent->type == ClientMessage){
+		g_message("XClient notify translating");
+
+		display = gdk_x11_lookup_xdisplay(xevent->xclient.display);
+		if(display == NULL){
+			g_warning("Message not from a gdk managed display, ignore it\n");
+			return FALSE;		
+		}
+		if( xevent->xclient.message_type == 
+			gdk_x11_get_xatom_by_name_for_display(display, ATOM_STRING)){
+			notify->type = xevent->xclient.data.l[1];
+			notify->param1 = xevent->xclient.data.l[2];
+			notify->param2 = xevent->xclient.data.l[3];
+			notify->param3 = xevent->xclient.data.l[4];
+			g_message("Global Menu Notification: %s, %ld, %ld, %ld\n",
+				global_menu_notify_get_name(notify->type),
+					notify->param1, notify->param2, notify->param3);
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+static GdkFilterReturn global_menu_socket_dispatcher(XEvent * xevent, GdkEvent * event, GlobalMenuSocket * socket){
+	GlobalMenuNotify notify;
+	GlobalMenuNotifyType type;
+	g_message("XClientMessage received");
+	if(event->any.window == socket->window 
+		&& global_menu_xevent_to_notify(xevent, &notify)){
+		type = notify.type;
+		if(socket->callbacks[type] ){
+			(*(socket->callbacks[type]))(socket, &notify, socket->userdata);
+		}
+		return GDK_FILTER_REMOVE;
+	} else{
+	g_message("Pass to futher handlers, not a MenuBar message");
+
+	}
+	return GDK_FILTER_CONTINUE;
+	
+}
+
+static GlobalMenuSocket * global_menu_socket_new(gchar * name, gpointer userdata){
+	GdkWindowAttr attr;
+	GdkWindowAttributesType mask;
+
+	GlobalMenuSocket * socket = g_new0(GlobalMenuSocket, 1);
+	attr.title = name;
+	attr.wclass = GDK_INPUT_ONLY;
+	attr.window_type = GDK_WINDOW_TEMP;
+
+	mask = GDK_WA_TITLE;
+	socket->window = gdk_window_new(NULL, &attr, mask);
+	socket->name = g_strdup(name);
+	socket->userdata = userdata,
+	socket->display = gdk_drawable_get_display(socket->window);
+	
+	gdk_window_add_filter(socket->window, (GdkFilterFunc)global_menu_socket_dispatcher, socket);
+
+	return socket;
+}
+static void global_menu_socket_free(GlobalMenuSocket * socket){
+	gdk_window_destroy(socket->window);
+	g_free(socket->name);
+	g_free(socket);
+}
+static void global_menu_socket_set_callback(GlobalMenuSocket * socket, 
+		GlobalMenuNotifyType type, GlobalMenuCallback cb){
+	g_return_if_fail( type > GM_NOTIFY_MIN && type < GM_NOTIFY_MAX);
+	g_return_if_fail( socket );
+	g_return_if_fail( cb );
+	
+	socket->callbacks[type] = cb;
+}
+static GList * _global_menu_find_windows(GlobalMenuSocket * socket, char * dest_name){
+	GList * window_list = NULL;
+	GdkScreen * screen;
+	GdkWindow * root = NULL;
+
+	Window root_return;
+	Window parent_return;
+	Window * children_return;
+	unsigned int nchildren_return;
+	unsigned int i;
+	gboolean connected = FALSE;
+g_message("%s", __func__);
+	g_return_val_if_fail( socket ,FALSE);
+	g_return_val_if_fail( dest_name ,FALSE);
+	
+	screen = gdk_drawable_get_screen(socket->window);
+	root = gdk_screen_get_root_window(screen);
+	g_return_val_if_fail( screen , FALSE);	
+	g_return_val_if_fail( root , FALSE);	
+
+	gdk_error_trap_push();
+	XQueryTree(GDK_DISPLAY_XDISPLAY(socket->display),
+		GDK_WINDOW_XWINDOW(root),
+		&root_return,
+		&parent_return,
+		&children_return,
+		&nchildren_return);
+	if(gdk_error_trap_pop()){
+		g_warning("XQueryTree Failed");
+		return FALSE;
+	}
+
+	g_return_val_if_fail( children_return , FALSE );
+
+	for(i = 0; i < nchildren_return; i++){
+		Atom type_return;
+		Atom type_req = gdk_x11_get_xatom_by_name_for_display (socket->display, "UTF8_STRING");
+		gint format_return;
+		gulong nitems_return;
+		gulong bytes_after_return;
+		guchar * data;
+		gint rt;
+		gdk_error_trap_push();
+		rt = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (socket->display), children_return[i],
+						  gdk_x11_get_xatom_by_name_for_display (socket->display, "_NET_WM_NAME"),
+                          0, G_MAXLONG, False, type_req, &type_return,
+                          &format_return, &nitems_return, &bytes_after_return,
+                          &data);
+		if(!gdk_error_trap_pop()){
+			if(rt == Success && type_return == type_req){
+				if(g_str_equal(dest_name, data)){
+					g_message("Window found, Add to list");
+	//				socket->dest_xid = children_return[i];
+	//				connected = TRUE;
+					window_list = g_list_append(window_list, (gpointer) children_return[i]);
+				}
+			}
+		}else{
+			g_warning("XGetWindowProperty Failed");
+		}
+	}
+	XFree(children_return);
+	return window_list;
+}
+
+static Window global_menu_socket_get_xid(GlobalMenuSocket * socket){
+	return GDK_WINDOW_XWINDOW(socket->window);
+}
+static void global_menu_socket_send_to(GlobalMenuSocket * socket, Window xid, GlobalMenuNotify * message){
+	XClientMessageEvent xclient;
+
+	memset (&xclient, 0, sizeof (xclient));
+	xclient.window = xid;
+	xclient.type = ClientMessage;
+	xclient.message_type = gdk_x11_get_xatom_by_name_for_display (socket->display, ATOM_STRING);
+	xclient.format = 32;
+	xclient.data.l[0] = gtk_get_current_event_time();
+	xclient.data.l[1] = message->type;
+	xclient.data.l[2] = message->param1;
+	xclient.data.l[3] = message->param2;
+	xclient.data.l[4] = message->param3;
+	gdk_error_trap_push ();
+	XSendEvent (GDK_DISPLAY_XDISPLAY(socket->display),
+		  xid,
+		  False, NoEventMask, (XEvent *)&xclient);
+	gdk_display_sync (socket->display);
+	gdk_error_trap_pop ();
+}
+static void global_menu_socket_send(GlobalMenuSocket * socket, GlobalMenuNotify * message){
+	global_menu_socket_send_to(socket, socket->dest_xid, message);
+}
+static gboolean global_menu_socket_broadcast_by_name(GlobalMenuSocket * socket, char * dest_name, GlobalMenuNotify * notify){
+	GList * window_list = NULL;
+	GList * node = NULL;
+	window_list = _global_menu_find_windows(socket, dest_name);
+	for(node = g_list_first(window_list); node ; node = g_list_next(node)){
+		g_message("%s: sending to %p", __func__, (gpointer) node->data);
+		global_menu_socket_send_to(socket, node->data, notify);
+	}
+	g_list_free(window_list);
+}
+static gboolean global_menu_socket_connect_by_xid(GlobalMenuSocket * socket, Window xid){
+	socket->dest_xid = xid; /*perhaps need to check whether the window is valid*/
+	return TRUE;
+}
+static gboolean global_menu_socket_connect_by_name(GlobalMenuSocket * socket, gchar * dest_name){
+	GList * window_list = NULL;
+	gboolean rt = FALSE;
+	window_list = _global_menu_find_windows(socket, dest_name);
+	if(window_list){
+		rt = global_menu_socket_connect_by_xid(socket, window_list->data); 
+/*simply connect to the first server*/
+		g_list_free(window_list);
+	}
+	return rt;
+}
+#endif
