diff -urN aa/gnome-panel-2.6.0/gnome-panel/Makefile.am gnome-panel-2.6.0/gnome-panel/Makefile.am
--- aa/gnome-panel-2.6.0/gnome-panel/Makefile.am 2004-02-06 17:04:50.000000000 +0100
+++ gnome-panel-2.6.0/gnome-panel/Makefile.am 2004-03-27 00:29:00.520061944 +0100
@@ -80,6 +80,8 @@
panel-typebuiltins.h \
panel-marshal.c \
panel-marshal.h \
+ panel-menu.c \
+ panel-menu.h \
main.c \
panel-widget.c \
button-widget.c \
diff -urN aa/gnome-panel-2.6.0/gnome-panel/menu.c gnome-panel-2.6.0/gnome-panel/menu.c
--- aa/gnome-panel-2.6.0/gnome-panel/menu.c 2004-03-09 11:08:47.000000000 +0100
+++ gnome-panel-2.6.0/gnome-panel/menu.c 2004-03-27 00:29:00.522061640 +0100
@@ -44,6 +44,7 @@
#include "menu-fentry.h"
#include "menu-util.h"
#include "menu-ditem.h"
+#include "panel-menu.h"
#include "panel-util.h"
#include "panel-gconf.h"
#include "panel.h"
@@ -67,6 +68,7 @@
#include "panel-lockdown.h"
#undef MENU_DEBUG
+#define MENU_SNAP_LENGTH 10
static char *gnome_folder = NULL;
@@ -614,6 +616,9 @@
if (repo->orig_func != NULL) {
repo->orig_func (menu, x, y, push_in, repo->orig_data);
+ if (*x < MENU_SNAP_LENGTH)
+ *x = 0;
+
if (menu->parent_menu_item != NULL) {
/* This is a submenu so behave submenuish */
if (*x < monitor_basex ||
@@ -709,8 +714,8 @@
reload_image_menu_items ();
}
-GtkWidget *
-panel_create_menu (void)
+static GtkWidget *
+panel_create_menu_of_type (GType menu_type)
{
GtkWidget *retval;
static gboolean registered_icon_theme_changer = FALSE;
@@ -722,8 +727,7 @@
G_CALLBACK (icon_theme_changed), NULL);
}
- retval = gtk_menu_new ();
-
+ retval = g_object_new (menu_type, NULL);
panel_gconf_notify_add_while_alive ("/desktop/gnome/interface/menus_have_icons",
(GConfClientNotifyFunc) menus_have_icons_changed,
G_OBJECT (retval));
@@ -739,12 +743,18 @@
return retval;
}
+GtkWidget *
+panel_create_menu (void)
+{
+ return panel_create_menu_of_type (gtk_menu_get_type());
+}
+
static GtkWidget *
-menu_new (void)
+menu_new_of_type (GType menu_type)
{
GtkWidget *retval;
- retval = panel_create_menu ();
+ retval = panel_create_menu_of_type (menu_type);
g_signal_connect (
retval, "show", G_CALLBACK (setup_menu_panel), NULL);
@@ -752,6 +762,13 @@
return retval;
}
+static GtkWidget *
+menu_new (void)
+{
+ return menu_new_of_type (gtk_menu_get_type ());
+}
+
+
static void
icon_to_load_free (IconToLoad *icon)
{
@@ -3314,7 +3331,7 @@
}
if (!root_menu)
- root_menu = menu_new ();
+ root_menu = menu_new_of_type (panel_menu_get_type ());
g_object_set_data (G_OBJECT (root_menu), "menu_panel", panel);
diff -urN aa/gnome-panel-2.6.0/gnome-panel/panel-config-global.c gnome-panel-2.6.0/gnome-panel/panel-config-global.c
--- aa/gnome-panel-2.6.0/gnome-panel/panel-config-global.c 2004-01-18 15:35:47.000000000 +0100
+++ gnome-panel-2.6.0/gnome-panel/panel-config-global.c 2004-03-27 00:29:00.523061488 +0100
@@ -45,6 +45,7 @@
guint drawer_auto_close : 1;
guint confirm_panel_remove : 1;
guint highlight_when_over : 1;
+ guint menu_stripe : 1;
} GlobalConfig;
static GlobalConfig global_config = { 0, };
@@ -94,6 +95,13 @@
return global_config.confirm_panel_remove;
}
+gboolean
+panel_global_config_get_menu_stripe (void)
+{
+ g_assert (global_config_initialised == TRUE);
+
+ return global_config.menu_stripe;
+}
static void
panel_global_config_set_entry (GConfEntry *entry)
@@ -151,6 +159,11 @@
else if (strcmp (key, "highlight_launchers_on_mouseover") == 0)
global_config.highlight_when_over =
gconf_value_get_bool (value);
+
+ else if (strcmp (key, "show_menu_stripe") == 0)
+ global_config.menu_stripe =
+ gconf_value_get_bool (value);
+
}
static void
diff -urN aa/gnome-panel-2.6.0/gnome-panel/panel-config-global.h gnome-panel-2.6.0/gnome-panel/panel-config-global.h
--- aa/gnome-panel-2.6.0/gnome-panel/panel-config-global.h 2004-01-18 15:32:28.000000000 +0100
+++ gnome-panel-2.6.0/gnome-panel/panel-config-global.h 2004-03-27 00:29:00.523061488 +0100
@@ -37,6 +37,7 @@
gboolean panel_global_config_get_drawer_auto_close (void);
gboolean panel_global_config_get_tooltips_enabled (void);
gboolean panel_global_config_get_confirm_panel_remove (void);
+gboolean panel_global_config_get_menu_stripe (void);
G_END_DECLS
diff -urN aa/gnome-panel-2.6.0/gnome-panel/panel-global.schemas.in gnome-panel-2.6.0/gnome-panel/panel-global.schemas.in
--- aa/gnome-panel-2.6.0/gnome-panel/panel-global.schemas.in 2004-01-18 16:10:23.000000000 +0100
+++ gnome-panel-2.6.0/gnome-panel/panel-global.schemas.in 2004-03-27 00:29:00.588051608 +0100
@@ -93,6 +93,18 @@
+ /schemas/apps/panel/global/show_menu_stripe
+ /apps/panel/global/show_menu_stripe
+ panel
+ bool
+ true
+
+
+
+
+
+
+
/schemas/apps/panel/global/enable_key_bindings
/apps/panel/global/enable_key_bindings
panel
diff -urN aa/gnome-panel-2.6.0/gnome-panel/panel-menu.c gnome-panel-2.6.0/gnome-panel/panel-menu.c
--- aa/gnome-panel-2.6.0/gnome-panel/panel-menu.c 1970-01-01 01:00:00.000000000 +0100
+++ gnome-panel-2.6.0/gnome-panel/panel-menu.c 2004-03-27 00:49:47.929426896 +0100
@@ -0,0 +1,1082 @@
+/*
+ * To set this up insert something like this in your ~/.gtkrc-2.0
+ *
+ * Copyright (C) 2002 Ximian, Inc.
+ * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima
+ * Copyright (C) 2003 Marcin Krzyżanowski
+ *
+ * style "default"
+ * {
+ * PanelMenu::default_side_image = "/tmp/stripelogo.png"
+ * PanelMenu::gradient_bg = true
+ * }
+ * class "PanelMenu" style "default"
+ *
+ * Authors:
+ * Thomas, Michael Meeks
+ * GtkMenu code by the GTK+ team
+ * Gradient code from WindowMaker by Dan Pascu and Alfredo Kojima,
+ * by way of metacity by Havoc Pennington.
+ * Marcin Krzyżanowski
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "panel-config-global.h"
+
+#define dprintf(a) g_warning a
+/*#define dprintf(a) G_STMT_START { (void) 0; } G_STMT_END*/
+
+GNOME_CLASS_BOILERPLATE (PanelMenu, panel_menu,
+ GtkMenu, GTK_TYPE_MENU)
+
+
+
+static void
+panel_menu_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ PanelMenu *pm = PANEL_MENU (widget);
+
+ GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
+
+ if (panel_global_config_get_menu_stripe () && pm->side_image != NULL)
+ requisition->width += gdk_pixbuf_get_width (pm->side_image)
+ + gtk_widget_get_style (widget)->xthickness;
+}
+
+static GdkColor *
+get_light_stripe_color (PanelMenu *pm)
+{
+ GdkColor *color;
+
+ gtk_widget_style_get (GTK_WIDGET (pm),
+ "stripe-color-light", &color,
+ NULL);
+
+ if (!color) {
+ color = gdk_color_copy (>K_WIDGET (pm)->style->bg[GTK_STATE_NORMAL]);
+ }
+
+ return color;
+}
+
+static GdkColor *
+get_stripe_color (PanelMenu *pm)
+{
+ GdkColor *color;
+
+ gtk_widget_style_get (GTK_WIDGET (pm),
+ "stripe-color", &color,
+ NULL);
+
+ if (!color) {
+ color = gdk_color_copy (>K_WIDGET (pm)->style->bg[GTK_STATE_SELECTED]);
+ }
+
+ return color;
+}
+
+static GdkGC *
+get_stripe_gc (PanelMenu *pm)
+{
+ GdkGCValues gc_values;
+ GdkGCValuesMask gc_values_mask;
+ GdkColor *color;
+
+ color = get_stripe_color (pm);
+ gc_values.foreground = *color;
+ gdk_color_free (color);
+ gc_values_mask = GDK_GC_FOREGROUND;
+
+ gdk_rgb_find_color (GTK_WIDGET (pm)->style->colormap, &gc_values.foreground);
+
+ return gtk_gc_get (GTK_WIDGET (pm)->style->depth,
+ GTK_WIDGET (pm)->style->colormap,
+ &gc_values, gc_values_mask);
+}
+
+static gboolean
+panel_menu_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ GdkRectangle exposed;
+ GdkRectangle position;
+ GdkWindow *window;
+ int bin_height;
+ GdkGC *stripe_gc;
+ PanelMenu *pm = PANEL_MENU (widget);
+
+ GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
+
+ if (!panel_global_config_get_menu_stripe () || !pm->side_image) {
+ return TRUE;
+ }
+ window = GTK_MENU (widget)->bin_window;
+
+ stripe_gc = get_stripe_gc (pm);
+
+ gdk_gc_set_clip_rectangle (stripe_gc, &event->area);
+ gdk_draw_rectangle (window,
+ stripe_gc,
+ TRUE,
+ widget->allocation.x,
+ widget->allocation.y,
+ gdk_pixbuf_get_width (pm->side_image),
+ widget->allocation.height);
+ gdk_gc_set_clip_rectangle (stripe_gc, NULL);
+
+ bin_height = widget->allocation.height - 2 * (GTK_CONTAINER (widget)->border_width + widget->style->ythickness);
+
+ position = widget->allocation;
+ position.y += bin_height - gdk_pixbuf_get_height (pm->side_image);
+ position.width = gdk_pixbuf_get_width (pm->side_image);
+ position.height = gdk_pixbuf_get_height (pm->side_image);
+
+ if (widget->allocation.height >= gdk_pixbuf_get_height (pm->side_image)) {
+ if (gdk_rectangle_intersect (&event->area,
+ &position,
+ &exposed)) {
+ gdk_pixbuf_render_to_drawable (
+ pm->side_image, window,
+ widget->style->black_gc,
+ exposed.x - position.x,
+ exposed.y - position.y,
+ exposed.x, exposed.y,
+ exposed.width, exposed.height,
+ GDK_RGB_DITHER_NORMAL,
+ exposed.x, exposed.y);
+ }
+ }
+
+ position = widget->allocation;
+ if (position.height != gdk_pixbuf_get_height (pm->side_image)) {
+ position.width = gdk_pixbuf_get_width (pm->side_image);
+ if (position.height > gdk_pixbuf_get_height (pm->side_image)) {
+ position.height = bin_height - gdk_pixbuf_get_height (pm->side_image);
+ } else {
+ position.height = bin_height;
+ }
+
+ if (pm->scaled_image && gdk_rectangle_intersect (&event->area,
+ &position,
+ &exposed)) {
+
+ gdk_pixbuf_render_to_drawable (
+ pm->scaled_image, window,
+ widget->style->black_gc,
+ exposed.x - position.x,
+ exposed.y - position.y,
+ exposed.x, exposed.y,
+ exposed.width, exposed.height,
+ GDK_RGB_DITHER_NORMAL,
+ exposed.x, exposed.y);
+ }
+ }
+
+ return TRUE;
+}
+
+/* begin metacity cut and paste */
+static void
+free_buffer (guchar *pixels, gpointer data)
+{
+ g_free (pixels);
+}
+
+static GdkPixbuf*
+blank_pixbuf (int width, int height, gboolean no_padding)
+{
+ guchar *buf;
+ int rowstride;
+
+ g_return_val_if_fail (width > 0, NULL);
+ g_return_val_if_fail (height > 0, NULL);
+
+ if (no_padding)
+ rowstride = width * 3;
+ else
+ /* Always align rows to 32-bit boundaries */
+ rowstride = 4 * ((3 * width + 3) / 4);
+
+ buf = g_try_malloc (height * rowstride);
+ if (!buf)
+ return NULL;
+
+ return gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB,
+ FALSE, 8,
+ width, height, rowstride,
+ free_buffer, NULL);
+}
+
+static GdkPixbuf*
+meta_gradient_create_vertical (int width, int height,
+ const GdkColor *from,
+ const GdkColor *to)
+{
+ int i, j;
+ long r, g, b, dr, dg, db;
+ GdkPixbuf *pixbuf;
+ unsigned char *ptr;
+ unsigned char rr, gg, bb;
+ int r0, g0, b0;
+ int rf, gf, bf;
+ int rowstride;
+ unsigned char *pixels;
+
+ pixbuf = blank_pixbuf (width, height, FALSE);
+ if (pixbuf == NULL)
+ return NULL;
+
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ r0 = (guchar) (from->red / 256.0);
+ g0 = (guchar) (from->green / 256.0);
+ b0 = (guchar) (from->blue / 256.0);
+ rf = (guchar) (to->red / 256.0);
+ gf = (guchar) (to->green / 256.0);
+ bf = (guchar) (to->blue / 256.0);
+
+ r = r0<<16;
+ g = g0<<16;
+ b = b0<<16;
+
+ dr = ((rf-r0)<<16)/(int)height;
+ dg = ((gf-g0)<<16)/(int)height;
+ db = ((bf-b0)<<16)/(int)height;
+
+ for (i=0; i>16;
+ gg = g>>16;
+ bb = b>>16;
+ for (j=0; jheights);
+
+ g_free (priv);
+}
+
+static GtkMenuPrivate *
+gtk_menu_get_private (GtkMenu *menu)
+{
+ GtkMenuPrivate *private;
+ static GQuark private_quark = 0;
+
+ if (!private_quark)
+ private_quark = g_quark_from_static_string ("gtk-menu-private");
+
+ private = g_object_get_qdata (G_OBJECT (menu), private_quark);
+
+ if (!private)
+ {
+ private = g_new0 (GtkMenuPrivate, 1);
+ private->have_position = FALSE;
+
+ g_object_set_qdata_full (G_OBJECT (menu), private_quark,
+ private, gtk_menu_free_private);
+ }
+
+ return private;
+}
+
+static void
+gtk_menu_remove_scroll_timeout (GtkMenu *menu)
+{
+ if (menu->timeout_id)
+ {
+ g_source_remove (menu->timeout_id);
+ menu->timeout_id = 0;
+ }
+}
+
+static void
+gtk_menu_stop_scrolling (GtkMenu *menu)
+{
+ gtk_menu_remove_scroll_timeout (menu);
+
+ menu->upper_arrow_prelight = FALSE;
+ menu->lower_arrow_prelight = FALSE;
+}
+
+static void
+gtk_menu_scroll_to (GtkMenu *menu,
+ gint offset)
+{
+ GtkWidget *widget;
+ gint x, y;
+ gint view_width, view_height;
+ gint border_width;
+ gboolean last_visible;
+ gint menu_height;
+ guint vertical_padding;
+
+ widget = GTK_WIDGET (menu);
+
+ if (menu->tearoff_active &&
+ menu->tearoff_adjustment &&
+ (menu->tearoff_adjustment->value != offset))
+ {
+ menu->tearoff_adjustment->value =
+ CLAMP (offset,
+ 0, menu->tearoff_adjustment->upper - menu->tearoff_adjustment->page_size);
+ gtk_adjustment_value_changed (menu->tearoff_adjustment);
+ }
+
+ /* Move/resize the viewport according to arrows: */
+ view_width = widget->allocation.width;
+ view_height = widget->allocation.height;
+
+ gtk_widget_style_get (GTK_WIDGET (menu),
+ "vertical-padding", &vertical_padding,
+ NULL);
+
+ border_width = GTK_CONTAINER (menu)->border_width;
+ view_width -= (border_width + widget->style->xthickness) * 2;
+ view_height -= (border_width + widget->style->ythickness + vertical_padding) * 2;
+ menu_height = widget->requisition.height -
+ (border_width + widget->style->ythickness + vertical_padding) * 2;
+
+ x = border_width + widget->style->xthickness;
+ y = border_width + widget->style->ythickness + vertical_padding;
+
+ if (!menu->tearoff_active)
+ {
+ last_visible = menu->upper_arrow_visible;
+ menu->upper_arrow_visible = offset > 0;
+
+ if (menu->upper_arrow_visible)
+ view_height -= MENU_SCROLL_ARROW_HEIGHT;
+
+ if ( (last_visible != menu->upper_arrow_visible) &&
+ !menu->upper_arrow_visible)
+ {
+ menu->upper_arrow_prelight = FALSE;
+
+ /* If we hid the upper arrow, possibly remove timeout */
+ if (menu->scroll_step < 0)
+ {
+ gtk_menu_stop_scrolling (menu);
+ gtk_widget_queue_draw (GTK_WIDGET (menu));
+ }
+ }
+
+ last_visible = menu->lower_arrow_visible;
+ menu->lower_arrow_visible = offset < menu_height - view_height;
+
+ if (menu->lower_arrow_visible)
+ view_height -= MENU_SCROLL_ARROW_HEIGHT;
+
+ if ( (last_visible != menu->lower_arrow_visible) &&
+ !menu->lower_arrow_visible)
+ {
+ menu->lower_arrow_prelight = FALSE;
+
+ /* If we hid the lower arrow, possibly remove timeout */
+ if (menu->scroll_step > 0)
+ {
+ gtk_menu_stop_scrolling (menu);
+ gtk_widget_queue_draw (GTK_WIDGET (menu));
+ }
+ }
+
+ if (menu->upper_arrow_visible)
+ y += MENU_SCROLL_ARROW_HEIGHT;
+ }
+
+ /* Scroll the menu: */
+ if (GTK_WIDGET_REALIZED (menu))
+ gdk_window_move (menu->bin_window, 0, -offset);
+
+ if (GTK_WIDGET_REALIZED (menu))
+ gdk_window_move_resize (menu->view_window,
+ x,
+ y,
+ view_width,
+ view_height);
+
+ menu->scroll_offset = offset;
+}
+
+static AttachInfo *
+get_attach_info (GtkWidget *child)
+{
+ GObject *object = G_OBJECT (child);
+ AttachInfo *ai = g_object_get_data (object, ATTACH_INFO_KEY);
+
+ if (!ai)
+ {
+ ai = g_new0 (AttachInfo, 1);
+ g_object_set_data_full (object, ATTACH_INFO_KEY, ai, g_free);
+ }
+
+ return ai;
+}
+
+static gboolean
+is_grid_attached (AttachInfo *ai)
+{
+ return (ai->left_attach >= 0 &&
+ ai->right_attach >= 0 &&
+ ai->top_attach >= 0 &&
+ ai->bottom_attach >= 0);
+}
+
+static void
+menu_ensure_layout (GtkMenu *menu)
+{
+ GtkMenuPrivate *priv = gtk_menu_get_private (menu);
+
+ if (!priv->have_layout)
+ {
+ GtkMenuShell *menu_shell = GTK_MENU_SHELL (menu);
+ GList *l;
+ gchar *row_occupied;
+ gint current_row;
+ gint max_right_attach;
+ gint max_bottom_attach;
+
+ /* Find extents of gridded portion */
+ max_right_attach = 1;
+ max_bottom_attach = 0;
+
+ for (l = menu_shell->children; l; l = l->next)
+ {
+ GtkWidget *child = l->data;
+ AttachInfo *ai = get_attach_info (child);
+
+ if (is_grid_attached (ai))
+ {
+ max_bottom_attach = MAX (max_bottom_attach, ai->bottom_attach);
+ max_right_attach = MAX (max_right_attach, ai->right_attach);
+ }
+ }
+
+ /* Find empty rows */
+ row_occupied = g_malloc0 (max_bottom_attach);
+
+ for (l = menu_shell->children; l; l = l->next)
+ {
+ GtkWidget *child = l->data;
+ AttachInfo *ai = get_attach_info (child);
+
+ if (is_grid_attached (ai))
+ {
+ gint i;
+
+ for (i = ai->top_attach; i < ai->bottom_attach; i++)
+ row_occupied[i] = TRUE;
+ }
+ }
+
+ /* Lay non-grid-items out in those rows */
+ current_row = 0;
+ for (l = menu_shell->children; l; l = l->next)
+ {
+ GtkWidget *child = l->data;
+ AttachInfo *ai = get_attach_info (child);
+
+ if (!is_grid_attached (ai))
+ {
+ while (current_row < max_bottom_attach && row_occupied[current_row])
+ current_row++;
+
+ ai->effective_left_attach = 0;
+ ai->effective_right_attach = max_right_attach;
+ ai->effective_top_attach = current_row;
+ ai->effective_bottom_attach = current_row + 1;
+
+ current_row++;
+ }
+ else
+ {
+ ai->effective_left_attach = ai->left_attach;
+ ai->effective_right_attach = ai->right_attach;
+ ai->effective_top_attach = ai->top_attach;
+ ai->effective_bottom_attach = ai->bottom_attach;
+ }
+ }
+
+ g_free (row_occupied);
+
+ priv->n_rows = MAX (current_row, max_bottom_attach);
+ priv->n_columns = max_right_attach;
+ priv->have_layout = TRUE;
+ }
+}
+
+
+static gint
+gtk_menu_get_n_columns (GtkMenu *menu)
+{
+ GtkMenuPrivate *priv = gtk_menu_get_private (menu);
+
+ menu_ensure_layout (menu);
+
+ return priv->n_columns;
+}
+
+static gint
+gtk_menu_get_n_rows (GtkMenu *menu)
+{
+ GtkMenuPrivate *priv = gtk_menu_get_private (menu);
+
+ menu_ensure_layout (menu);
+
+ return priv->n_rows;
+}
+
+static void
+get_effective_child_attach (GtkWidget *child,
+ int *l,
+ int *r,
+ int *t,
+ int *b)
+{
+ GtkMenu *menu = GTK_MENU (child->parent);
+ AttachInfo *ai;
+
+ menu_ensure_layout (menu);
+
+ ai = get_attach_info (child);
+
+ if (l)
+ *l = ai->effective_left_attach;
+ if (r)
+ *r = ai->effective_right_attach;
+ if (t)
+ *t = ai->effective_top_attach;
+ if (b)
+ *b = ai->effective_bottom_attach;
+
+}
+
+static void
+gtk_menu_set_tearoff_hints (GtkMenu *menu,
+ gint width)
+{
+ GdkGeometry geometry_hints;
+
+ if (!menu->tearoff_window)
+ return;
+
+ if (GTK_WIDGET_VISIBLE (menu->tearoff_scrollbar))
+ {
+ gtk_widget_size_request (menu->tearoff_scrollbar, NULL);
+ width += menu->tearoff_scrollbar->requisition.width;
+ }
+
+ geometry_hints.min_width = width;
+ geometry_hints.max_width = width;
+
+ geometry_hints.min_height = 0;
+ geometry_hints.max_height = GTK_WIDGET (menu)->requisition.height;
+
+ gtk_window_set_geometry_hints (GTK_WINDOW (menu->tearoff_window),
+ NULL,
+ &geometry_hints,
+ GDK_HINT_MAX_SIZE|GDK_HINT_MIN_SIZE);
+}
+
+static void
+gtk_menu_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkMenu *menu;
+ GtkMenuShell *menu_shell;
+ GtkWidget *child;
+ GtkAllocation child_allocation;
+ GtkRequisition child_requisition;
+ GtkMenuPrivate *priv;
+ GList *children;
+ gint x, y;
+ gint width, height;
+ guint vertical_padding;
+ guint menu_stripe_width;
+
+ g_return_if_fail (GTK_IS_MENU (widget));
+ g_return_if_fail (allocation != NULL);
+
+ menu = GTK_MENU (widget);
+ menu_shell = GTK_MENU_SHELL (widget);
+ priv = gtk_menu_get_private (menu);
+
+ widget->allocation = *allocation;
+ gtk_widget_get_child_requisition (GTK_WIDGET (menu), &child_requisition);
+
+ gtk_widget_style_get (GTK_WIDGET (menu),
+ "vertical-padding", &vertical_padding,
+ NULL);
+
+ x = GTK_CONTAINER (menu)->border_width + widget->style->xthickness;
+ y = GTK_CONTAINER (menu)->border_width + widget->style->ythickness + vertical_padding;
+
+ width = MAX (1, allocation->width - x * 2);
+ height = MAX (1, allocation->height - y * 2);
+
+ child_requisition.width -= x * 2;
+ child_requisition.height -= y * 2;
+
+ if (menu_shell->active)
+ gtk_menu_scroll_to (menu, menu->scroll_offset);
+
+ if (menu->upper_arrow_visible && !menu->tearoff_active)
+ {
+ y += MENU_SCROLL_ARROW_HEIGHT;
+ height -= MENU_SCROLL_ARROW_HEIGHT;
+ }
+
+ if (menu->lower_arrow_visible && !menu->tearoff_active)
+ height -= MENU_SCROLL_ARROW_HEIGHT;
+
+ if (GTK_WIDGET_REALIZED (widget))
+ {
+ gdk_window_move_resize (widget->window,
+ allocation->x, allocation->y,
+ allocation->width, allocation->height);
+
+ gdk_window_move_resize (menu->view_window,
+ x,
+ y,
+ width,
+ height);
+ }
+
+/* inserted for panel-menu.c */
+ if (panel_global_config_get_menu_stripe () && PANEL_MENU (widget)->side_image) {
+ menu_stripe_width = gdk_pixbuf_get_width (PANEL_MENU (widget)->side_image) + gtk_widget_get_style (widget)->xthickness;
+ } else {
+ menu_stripe_width = 0;
+ }
+/* end panel-menu.c */
+
+ if (menu_shell->children)
+ {
+/* inserted for panel-menu.c */
+#if 0
+ gint base_width = width / gtk_menu_get_n_columns (menu);
+#else
+ gint base_width = (width - menu_stripe_width) / gtk_menu_get_n_columns (menu);
+#endif
+/* end panel-menu.c */
+
+ children = menu_shell->children;
+ while (children)
+ {
+ child = children->data;
+ children = children->next;
+
+ if (GTK_WIDGET_VISIBLE (child))
+ {
+ gint i;
+ guint l, r, t, b;
+
+ get_effective_child_attach (child, &l, &r, &t, &b);
+
+ if (gtk_widget_get_direction (GTK_WIDGET (menu)) == GTK_TEXT_DIR_RTL)
+ {
+ guint tmp;
+ tmp = gtk_menu_get_n_columns (menu) - l;
+ l = gtk_menu_get_n_columns (menu) - r;
+ r = tmp;
+ }
+
+ child_allocation.width = (r - l) * base_width;
+ child_allocation.height = 0;
+/* inserted for panel-menu.c */
+#if 0
+ child_allocation.x = l * base_width;
+#else
+ child_allocation.x = l * base_width + menu_stripe_width;
+#endif
+ child_allocation.y = 0;
+
+ for (i = 0; i < b; i++)
+ {
+ if (i < t)
+ child_allocation.y += priv->heights[i];
+ else
+ child_allocation.height += priv->heights[i];
+ }
+
+
+ gtk_menu_item_toggle_size_allocate (GTK_MENU_ITEM (child),
+ menu->toggle_size);
+
+ gtk_widget_size_allocate (child, &child_allocation);
+
+#if 0
+
+/* inserted for panel-menu.c */
+ if (use_menu_stripe && g_type_is_a (G_OBJECT_TYPE (child), GTK_TYPE_SEPARATOR_MENU_ITEM))
+ {
+ /* this is dumb, gtkmenuitem.c uses allocation.width as an absolute point */
+ child_allocation.width += gdk_pixbuf_get_width (PANEL_MENU (widget)->side_image);
+ }
+
+ gtk_widget_size_allocate (child, &child_allocation);
+
+ if (use_menu_stripe && g_type_is_a (G_OBJECT_TYPE (child), GTK_TYPE_SEPARATOR_MENU_ITEM))
+ {
+ child_allocation.width -= gdk_pixbuf_get_width (PANEL_MENU (widget)->side_image);
+ }
+#endif
+
+ /* Hack to handle events on the stripe area */
+ if (GTK_WIDGET_REALIZED (child) && l == 0)
+ {
+ gdk_window_move_resize (GTK_MENU_ITEM (child)->event_window,
+ 0, child_allocation.y,
+ child_allocation.width + child_allocation.x,
+ child_allocation.height);
+ }
+/* end panel-menu.c */
+
+ gtk_widget_queue_draw (child);
+ }
+ }
+
+ /* Resize the item window */
+ if (GTK_WIDGET_REALIZED (widget))
+ {
+ gint i;
+ gint width, height;
+
+ height = 0;
+ for (i = 0; i < gtk_menu_get_n_rows (menu); i++)
+ height += priv->heights[i];
+
+/* inserted for panel-menu.c */
+#if 0
+ width = gtk_menu_get_n_columns (menu) * base_width;
+#else
+ width = gtk_menu_get_n_columns (menu) * base_width + menu_stripe_width;
+#endif
+/* end panel-menu.c */
+
+ gdk_window_resize (menu->bin_window, width, height);
+ }
+
+ if (menu->tearoff_active)
+ {
+ if (allocation->height >= widget->requisition.height)
+ {
+ if (GTK_WIDGET_VISIBLE (menu->tearoff_scrollbar))
+ {
+ gtk_widget_hide (menu->tearoff_scrollbar);
+ gtk_menu_set_tearoff_hints (menu, allocation->width);
+
+ gtk_menu_scroll_to (menu, 0);
+ }
+ }
+ else
+ {
+ menu->tearoff_adjustment->upper = widget->requisition.height;
+ menu->tearoff_adjustment->page_size = allocation->height;
+
+ if (menu->tearoff_adjustment->value + menu->tearoff_adjustment->page_size >
+ menu->tearoff_adjustment->upper)
+ {
+ gint value;
+ value = menu->tearoff_adjustment->upper - menu->tearoff_adjustment->page_size;
+ if (value < 0)
+ value = 0;
+ gtk_menu_scroll_to (menu, value);
+ }
+
+ gtk_adjustment_changed (menu->tearoff_adjustment);
+
+ if (!GTK_WIDGET_VISIBLE (menu->tearoff_scrollbar))
+ {
+ gtk_widget_show (menu->tearoff_scrollbar);
+ gtk_menu_set_tearoff_hints (menu, allocation->width);
+ }
+ }
+ }
+ }
+/* inserted for panel-menu.c */
+
+ {
+ PanelMenu *pm = PANEL_MENU (widget);
+
+ gint scaled_height = height;
+
+ if (pm->side_image && widget->allocation.height > gdk_pixbuf_get_height (pm->side_image))
+ {
+ scaled_height -= gdk_pixbuf_get_height (pm->side_image);
+ }
+
+ if (pm->side_image && widget->allocation.height < gdk_pixbuf_get_height (pm->side_image))
+ {
+ gint scaled_width = ((scaled_height * gdk_pixbuf_get_width (pm->side_image)) / gdk_pixbuf_get_height (pm->side_image));
+
+ if (pm->scaled_image)
+ gdk_pixbuf_unref(pm->scaled_image);
+
+ pm->scaled_image = gdk_pixbuf_scale_simple (pm->side_image,
+ scaled_width,
+ scaled_height,
+ GDK_INTERP_BILINEAR); /* maybe HYPER ? */
+ gdk_pixbuf_unref(pm->side_image);
+ pm->side_image = pm->scaled_image;
+ }
+ else
+ {
+ gboolean draw_gradient;
+ gtk_widget_style_get (GTK_WIDGET (pm),
+ "gradient_bg", &draw_gradient,
+ NULL);
+
+ if (pm->side_image && draw_gradient)
+ {
+ GdkColor *stripe_color;
+ GdkColor *light_color;
+
+ stripe_color = get_stripe_color (pm);
+ light_color = get_light_stripe_color (pm);
+ pm->scaled_image = meta_gradient_create_vertical
+ (gdk_pixbuf_get_width (pm->side_image),
+ scaled_height,
+ light_color,
+ stripe_color);
+ gdk_color_free (light_color);
+ gdk_color_free (stripe_color);
+ }
+ }
+ }
+/* end panel-menu.c */
+}
+
+/* end gtkmenu cut and paste */
+
+static void
+unload_images (PanelMenu *pm)
+{
+ if (pm->side_image) {
+ g_object_unref (pm->side_image);
+ pm->side_image = NULL;
+ }
+
+ if (pm->scaled_image) {
+ g_object_unref (pm->scaled_image);
+ pm->scaled_image = NULL;
+ }
+}
+
+static GdkPixbuf *
+get_stripe_image (PanelMenu *pm,
+ const char *name,
+ const char *default_filename)
+{
+ GdkPixbuf *image = NULL;
+ char *file_src;
+
+ gtk_widget_style_get (GTK_WIDGET (pm), name, &file_src, NULL);
+
+ if (!file_src) {
+ file_src = gnome_program_locate_file (NULL,
+ GNOME_FILE_DOMAIN_PIXMAP,
+ default_filename,
+ TRUE,
+ NULL);
+ }
+
+ if (file_src)
+ image = gdk_pixbuf_new_from_file (file_src, NULL);
+
+ g_free (file_src);
+
+ return image;
+}
+
+static void
+load_images (PanelMenu *pm)
+{
+ GdkPixbuf *image;
+
+ unload_images (pm);
+
+ pm->side_image = get_stripe_image (pm, "default_side_image",
+ "pld-desktop-stripe.png");
+}
+
+static void
+panel_menu_style_set (GtkWidget *widget,
+ GtkStyle *old_style)
+{
+ load_images (PANEL_MENU (widget));
+ GNOME_CALL_PARENT (GTK_WIDGET_CLASS, style_set, (widget, old_style));
+}
+
+static void
+panel_menu_destroy (GtkObject *object)
+{
+ PanelMenu *pm = PANEL_MENU (object);
+
+ unload_images (pm);
+
+ GNOME_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+panel_menu_finalize (GObject *object)
+{
+ GNOME_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
+}
+
+static void
+panel_menu_class_init (PanelMenuClass *klass)
+{
+ GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
+ GtkObjectClass *gtk_object_class = (GtkObjectClass *)klass;
+ GObjectClass *object_class = (GObjectClass *) klass;
+
+ gtk_widget_class_install_style_property (
+ widget_class,
+ g_param_spec_string ("default_side_image",
+ _("Default Side Image"),
+ _("Filename of logo down the side of applications menu"),
+ NULL,
+ G_PARAM_READWRITE));
+
+ gtk_widget_class_install_style_property (
+ widget_class,
+ g_param_spec_boolean ("gradient_bg",
+ _("Gradient Background"),
+ _("Draw a gradient in the menu stripe"),
+ FALSE,
+ G_PARAM_READWRITE));
+ gtk_widget_class_install_style_property (
+ widget_class,
+ g_param_spec_boxed ("stripe_color",
+ _("Stripe Color"),
+ _("Color of the panel menu stripe"),
+ GDK_TYPE_COLOR,
+ G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property (
+ widget_class,
+ g_param_spec_boxed ("stripe_color_light",
+ _("Light Stripe Color"),
+ _("Light color of the panel menu stripe, for gradients"),
+ GDK_TYPE_COLOR,
+ G_PARAM_READABLE));
+
+ object_class->finalize = panel_menu_finalize;
+ gtk_object_class->destroy = panel_menu_destroy;
+ widget_class->size_request = panel_menu_size_request;
+ widget_class->size_allocate = gtk_menu_size_allocate;
+ widget_class->expose_event = panel_menu_expose_event;
+ widget_class->style_set = panel_menu_style_set;
+}
+
+static void
+panel_menu_instance_init (PanelMenu *pm)
+{
+ gtk_widget_ensure_style (GTK_WIDGET (pm));
+
+ load_images (pm);
+
+ gtk_widget_add_events (
+ GTK_WIDGET (pm),
+ GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
+ GDK_POINTER_MOTION_MASK);
+}
diff -urN aa/gnome-panel-2.6.0/gnome-panel/panel-menu.h gnome-panel-2.6.0/gnome-panel/panel-menu.h
--- aa/gnome-panel-2.6.0/gnome-panel/panel-menu.h 1970-01-01 01:00:00.000000000 +0100
+++ gnome-panel-2.6.0/gnome-panel/panel-menu.h 2004-03-27 00:29:00.640043704 +0100
@@ -0,0 +1,31 @@
+#include
+#include
+
+typedef struct _PanelMenu PanelMenu;
+typedef struct _PanelMenuClass PanelMenuClass;
+
+#define PANEL_MENU(obj) \
+ GTK_CHECK_CAST (obj, panel_menu_get_type (), PanelMenu)
+#define PANEL_MENU_CLASS(k) \
+ GTK_CHECK_CLASS_CAST (k, panel_menu_get_type (), PanelMenuClass)
+#define PANEL_IS_MENU(obj) \
+ GTK_CHECK_TYPE (obj, panel_menu_get_type ())
+
+
+struct _PanelMenu
+{
+ GtkMenu parent;
+
+ GdkPixbuf *side_image;
+ GdkPixbuf *scaled_image;
+
+ GdkRegion *navigation_region;
+};
+
+struct _PanelMenuClass
+{
+ GtkMenuClass parent_class;
+};
+
+GType panel_menu_get_type (void);
+GtkWidget *panel_menu_evolve (void);