+ GtkMenuItemPrivate *priv = menu_item->priv;
+
+ g_return_if_fail (priv->submenu == (GtkWidget*) menu);
+
+ priv->submenu = NULL;
+}
+
+static void
+get_arrow_size (GtkWidget *widget,
+ GtkWidget *child,
+ gint *size,
+ gint *spacing)
+{
+ PangoContext *context;
+ PangoFontMetrics *metrics;
+ gfloat arrow_scaling;
+ gint arrow_spacing;
+
+ g_assert (size);
+
+ gtk_widget_style_get (widget,
+ "arrow-scaling", &arrow_scaling,
+ "arrow-spacing", &arrow_spacing,
+ NULL);
+
+ if (spacing != NULL)
+ *spacing = arrow_spacing;
+
+ context = gtk_widget_get_pango_context (child);
+
+ metrics = pango_context_get_metrics (context,
+ pango_context_get_font_description (context),
+ pango_context_get_language (context));
+
+ *size = (PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
+ pango_font_metrics_get_descent (metrics)));
+
+ pango_font_metrics_unref (metrics);
+
+ *size = *size * arrow_scaling;
+}
+
+
+static void
+gtk_menu_item_accel_width_foreach (GtkWidget *widget,
+ gpointer data)
+{
+ guint *width = data;
+
+ if (GTK_IS_ACCEL_LABEL (widget))
+ {
+ guint w;
+
+ w = gtk_accel_label_get_accel_width (GTK_ACCEL_LABEL (widget));
+ *width = MAX (*width, w);
+ }
+ else if (GTK_IS_CONTAINER (widget))
+ gtk_container_foreach (GTK_CONTAINER (widget),
+ gtk_menu_item_accel_width_foreach,
+ data);
+}
+
+static gint
+get_minimum_width (GtkWidget *widget)
+{
+ PangoContext *context;
+ PangoFontMetrics *metrics;
+ gint width;
+ gint width_chars;
+
+ context = gtk_widget_get_pango_context (widget);
+
+ metrics = pango_context_get_metrics (context,
+ pango_context_get_font_description (context),
+ pango_context_get_language (context));
+
+ width = pango_font_metrics_get_approximate_char_width (metrics);
+
+ pango_font_metrics_unref (metrics);
+
+ gtk_widget_style_get (widget, "width-chars", &width_chars, NULL);
+
+ return PANGO_PIXELS (width_chars * width);
+}
+
+static void
+gtk_menu_item_get_preferred_width (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GtkMenuItem *menu_item = GTK_MENU_ITEM (widget);
+ GtkMenuItemPrivate *priv = menu_item->priv;
+ GtkBin *bin;
+ GtkWidget *child;
+ GtkWidget *parent;
+ guint accel_width;
+ guint border_width;
+ gint min_width, nat_width;
+ GtkStyleContext *context;
+ GtkStateFlags state;
+ GtkBorder padding;
+
+ min_width = nat_width = 0;
+ bin = GTK_BIN (widget);
+ parent = gtk_widget_get_parent (widget);
+
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+
+ context = gtk_widget_get_style_context (widget);
+ state = gtk_widget_get_state_flags (widget);
+ gtk_style_context_get_padding (context, state, &padding);
+
+ min_width = (border_width * 2) + padding.left + padding.right;
+ nat_width = min_width;
+
+ child = gtk_bin_get_child (bin);
+
+ if (child != NULL && gtk_widget_get_visible (child))
+ {
+ GtkMenuItemPrivate *priv = menu_item->priv;
+ gint child_min, child_nat;
+
+ gtk_widget_get_preferred_width (child, &child_min, &child_nat);
+
+ if ((menu_item->priv->submenu && !GTK_IS_MENU_BAR (parent)) || priv->reserve_indicator)
+ {
+ gint arrow_spacing, arrow_size;
+
+ get_arrow_size (widget, child, &arrow_size, &arrow_spacing);
+
+ min_width += arrow_size;
+ min_width += arrow_spacing;
+
+ min_width = MAX (min_width, get_minimum_width (widget));
+ nat_width = min_width;
+ }
+
+ min_width += child_min;
+ nat_width += child_nat;
+ }
+
+ accel_width = 0;
+ gtk_container_foreach (GTK_CONTAINER (menu_item),
+ gtk_menu_item_accel_width_foreach,
+ &accel_width);
+ priv->accelerator_width = accel_width;
+
+ if (minimum_size)
+ *minimum_size = min_width;
+
+ if (natural_size)
+ *natural_size = nat_width;
+}
+
+static void
+gtk_menu_item_real_get_height (GtkWidget *widget,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GtkMenuItem *menu_item = GTK_MENU_ITEM (widget);
+ GtkMenuItemPrivate *priv = menu_item->priv;
+ GtkBin *bin;
+ GtkStyleContext *context;
+ GtkStateFlags state;
+ GtkBorder padding;
+ GtkWidget *child;
+ GtkWidget *parent;
+ guint accel_width;
+ guint border_width;
+ gint min_height, nat_height;
+ gint avail_size = 0;
+
+ min_height = nat_height = 0;
+
+ context = gtk_widget_get_style_context (widget);
+ state = gtk_widget_get_state_flags (widget);
+ gtk_style_context_get_padding (context, state, &padding);
+
+ bin = GTK_BIN (widget);
+ parent = gtk_widget_get_parent (widget);
+
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+ min_height = (border_width * 2) + padding.top + padding.bottom;
+
+ if (for_size != -1)
+ {
+ avail_size = for_size;
+ avail_size -= (border_width * 2) + padding.left + padding.right;
+ }
+
+ nat_height = min_height;