summaryrefslogtreecommitdiff
path: root/packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenuitem.c.diff
diff options
context:
space:
mode:
Diffstat (limited to 'packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenuitem.c.diff')
-rw-r--r--packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenuitem.c.diff457
1 files changed, 457 insertions, 0 deletions
diff --git a/packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenuitem.c.diff b/packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenuitem.c.diff
index e69de29bb2..7d8133e891 100644
--- a/packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenuitem.c.diff
+++ b/packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenuitem.c.diff
@@ -0,0 +1,457 @@
+--- gtk+-2.6.4/gtk/gtkmenuitem.c 2004-12-28 09:39:31.000000000 +0200
++++ gtk+-2.6.4/gtk/gtkmenuitem.c 2005-04-06 16:19:36.973917472 +0300
+@@ -24,6 +24,10 @@
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
++/* Modified for Nokia Oyj during 2002-2003. See CHANGES file for list
++ * of changes.
++ */
++
+ #define GTK_MENU_INTERNALS
+
+ #include <config.h>
+@@ -38,6 +42,9 @@
+ #include "gtkmenuitem.h"
+ #include "gtkseparatormenuitem.h"
+
++#define HILDON_HEIGHT_INCREMENT 1
++#define HILDON_ARROW_SPACE 6
++
+ #define MENU_ITEM_CLASS(w) GTK_MENU_ITEM_CLASS (GTK_OBJECT (w)->klass)
+
+ enum {
+@@ -95,6 +102,8 @@
+ guint signal_id);
+
+
++static void _gtk_menu_item_activate_submenus (GtkMenuItem *item);
++
+ static GtkItemClass *parent_class;
+ static guint menu_item_signals[LAST_SIGNAL] = { 0 };
+
+@@ -158,7 +167,9 @@
+ item_class->select = gtk_real_menu_item_select;
+ item_class->deselect = gtk_real_menu_item_deselect;
+
+- klass->activate = NULL;
++ /* Hildon addition : Added this to catch the
++ * activation of meuuitems with submenus. */
++ klass->activate = _gtk_menu_item_activate_submenus;
+ klass->activate_item = gtk_real_menu_item_activate_item;
+ klass->toggle_size_request = gtk_real_menu_item_toggle_size_request;
+ klass->toggle_size_allocate = gtk_real_menu_item_toggle_size_allocate;
+@@ -239,6 +250,16 @@
+ G_MAXINT,
+ 10,
+ G_PARAM_READABLE));
++
++ /* Hildon modification - allow themeing of separator height */
++ gtk_widget_class_install_style_property (widget_class,
++ g_param_spec_int ("separator_height",
++ "Separator height",
++ "Draw a separator graphics with height of x pixels.",
++ 0,
++ G_MAXINT,
++ 5,
++ G_PARAM_READABLE));
+ }
+
+ static void
+@@ -415,6 +436,13 @@
+ g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
+
+ gtk_item_select (GTK_ITEM (menu_item));
++ /* HILDON MOD. This is required as changed focus isn't drawn automatically
++ * and drawing it must be requested. */
++ if ((GTK_WIDGET(menu_item)->parent) && GTK_IS_MENU (GTK_WIDGET(menu_item)->parent))
++ {
++ GtkMenu *menu = GTK_MENU (GTK_WIDGET(menu_item)->parent);
++ if (menu->parent_menu_item) gtk_widget_queue_draw(GTK_WIDGET(menu->parent_menu_item));
++ }
+ }
+
+ void
+@@ -423,6 +451,13 @@
+ g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
+
+ gtk_item_deselect (GTK_ITEM (menu_item));
++ /* HILDON MOD. This is required as changed focus isn't drawn automatically
++ * and drawing it must be requested. */
++ if ((GTK_WIDGET(menu_item)->parent) && GTK_IS_MENU (GTK_WIDGET(menu_item)->parent))
++ {
++ GtkMenu *menu = GTK_MENU (GTK_WIDGET(menu_item)->parent);
++ if (menu->parent_menu_item) gtk_widget_queue_draw(GTK_WIDGET(menu->parent_menu_item));
++ }
+ }
+
+ void
+@@ -531,7 +566,7 @@
+ "arrow_spacing", &arrow_spacing,
+ NULL);
+
+- requisition->width += child_requisition.height;
++ requisition->width += child_requisition.height + HILDON_ARROW_SPACE;
+ requisition->width += arrow_spacing;
+
+ requisition->width = MAX (requisition->width, get_minimum_width (widget));
+@@ -543,6 +578,12 @@
+ requisition->height += 4;
+ }
+
++ /* We get correct focus size if we make the widget a bit bigger.
++ * (If the increment would be big, we should probably adjust the text
++ * position aswell.)
++ */
++ requisition->height += HILDON_HEIGHT_INCREMENT;
++
+ accel_width = 0;
+ gtk_container_foreach (GTK_CONTAINER (menu_item),
+ gtk_menu_item_accel_width_foreach,
+@@ -596,7 +637,8 @@
+ {
+ if (direction == GTK_TEXT_DIR_RTL)
+ child_allocation.x += child_requisition.height;
+- child_allocation.width -= child_requisition.height;
++ /* HILDON Modification. */
++ child_allocation.width -= child_requisition.height + HILDON_ARROW_SPACE;
+ }
+
+ if (child_allocation.width < 1)
+@@ -688,6 +730,7 @@
+ GtkShadowType shadow_type, selected_shadow_type;
+ gint width, height;
+ gint x, y;
++
+ gint border_width = GTK_CONTAINER (widget)->border_width;
+
+ if (GTK_WIDGET_DRAWABLE (widget))
+@@ -704,10 +747,56 @@
+ if ((state_type == GTK_STATE_PRELIGHT) &&
+ (GTK_BIN (menu_item)->child))
+ {
++ gint focus_x = x;
++ gint focus_width = width;
+ gtk_widget_style_get (widget,
+ "selected_shadow_type", &selected_shadow_type,
+ NULL);
+- gtk_paint_box (widget->style,
++
++ if (menu_item->submenu && menu_item->show_submenu_indicator)
++ {
++ GtkRequisition child_requisition;
++ gint arrow_size;
++ /* gint arrow_extent; */
++ gtk_widget_get_child_requisition (GTK_BIN (menu_item)->child,
++ &child_requisition);
++
++ arrow_size = child_requisition.height - 2 * widget->style->ythickness;
++ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) {
++ focus_width = x + width - arrow_size - 2 - HILDON_ARROW_SPACE;
++ }
++ else {
++ focus_x = x + arrow_size + 2 + HILDON_ARROW_SPACE;
++ }
++ }
++
++ /*
++ * Hildon modification:
++ * This draws different focus depending on if it's the toplevel
++ * focused menu item. All items that have submenus that in turn
++ * have an item selected will be drawn with SELECTED - state focus.
++ * If this isn't the case, PRELIGHT - state focus is used. */
++ if (menu_item->submenu)
++ {
++ GtkMenuItem *msi;
++ msi = GTK_MENU_ITEM(GTK_MENU_SHELL(&((GTK_MENU(menu_item->submenu))->menu_shell))->active_menu_item);
++ if ((msi == NULL) || (GTK_WIDGET (msi)->state == 0))
++ gtk_paint_box (widget->style,
++ widget->window,
++ GTK_STATE_PRELIGHT,
++ selected_shadow_type,
++ area, widget, "menuitem",
++ focus_x, y, focus_width, height);
++ else
++ gtk_paint_box (widget->style,
++ widget->window,
++ GTK_STATE_SELECTED,
++ selected_shadow_type,
++ area, widget, "menuitem",
++ focus_x, y, focus_width, height);
++ }
++ else
++ gtk_paint_box (widget->style,
+ widget->window,
+ GTK_STATE_PRELIGHT,
+ selected_shadow_type,
+@@ -747,8 +836,12 @@
+ arrow_extent = arrow_size * 0.8;
+
+ shadow_type = GTK_SHADOW_OUT;
+- if (state_type == GTK_STATE_PRELIGHT)
+- shadow_type = GTK_SHADOW_IN;
++ /*Hildon: only show the pressed arrow if the submenu is visible*/
++ if (state_type == GTK_STATE_PRELIGHT
++ && GTK_WIDGET_VISIBLE( menu_item->submenu))
++ {
++ shadow_type = GTK_SHADOW_IN;
++ }
+
+ if (direction == GTK_TEXT_DIR_LTR)
+ {
+@@ -763,6 +856,9 @@
+
+ arrow_y = y + (height - arrow_extent) / 2;
+
++/* HILDON modification to correct focus drawing with submenu arrow */
++ arrow_x = arrow_x - 4;
++
+ gtk_paint_arrow (widget->style, widget->window,
+ state_type, shadow_type,
+ area, widget, "menuitem",
+@@ -772,18 +868,20 @@
+ }
+ else if (!GTK_BIN (menu_item)->child)
+ {
+- guint horizontal_padding;
++ guint horizontal_padding, separator_height;
+
+ gtk_widget_style_get (widget,
+ "horizontal_padding", &horizontal_padding,
++ "separator_height", &separator_height,
+ NULL);
+
+- gtk_paint_hline (widget->style, widget->window, GTK_STATE_NORMAL,
+- area, widget, "menuitem",
+- widget->allocation.x + horizontal_padding + widget->style->xthickness,
+- widget->allocation.x + widget->allocation.width - horizontal_padding - widget->style->xthickness - 1,
+- widget->allocation.y + (widget->allocation.height -
+- widget->style->ythickness) / 2);
++ /* themable menuitem for menu separators */
++ gtk_paint_box (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
++ area, widget, "separator",
++ widget->allocation.x + horizontal_padding + widget->style->xthickness,
++ widget->allocation.y + (widget->allocation.height - widget->style->ythickness) / 2,
++ widget->allocation.x + widget->allocation.width - horizontal_padding - widget->style->xthickness - 1,
++ separator_height);
+ }
+ }
+ }
+@@ -839,6 +937,7 @@
+ (!GTK_WIDGET_MAPPED (menu_item->submenu) ||
+ GTK_MENU (menu_item->submenu)->tearoff_active))
+ {
++ GdkEvent *event = gtk_get_current_event ();
+ gint popup_delay;
+
+ if (menu_item->timer)
+@@ -851,26 +950,40 @@
+ popup_delay = get_popup_delay (menu_item);
+
+ if (popup_delay > 0)
+- {
+- GdkEvent *event = gtk_get_current_event ();
+-
+- menu_item->timer = g_timeout_add (popup_delay,
+- gtk_menu_item_select_timeout,
+- menu_item);
+- if (event &&
+- event->type != GDK_BUTTON_PRESS &&
+- event->type != GDK_ENTER_NOTIFY)
+- menu_item->timer_from_keypress = TRUE;
+- else
+- menu_item->timer_from_keypress = FALSE;
+-
+- if (event)
+- gdk_event_free (event);
+- }
++ {
++ /* OK, Here comes the contender for the 2003 Ugly Award
++ * The popup delay is set small enough to be unnoticable, but high enough to not
++ * notice the flickering which occurs when we close all the deepest menu's Gtk+ helpfully
++ * expands but are not needed
++ * This does not fix the mouse navigation yet (bug 18) but should take care of 442
++ * NOTE: test the delay factor on different CPU speeds
++ */
++ popup_delay = 3;
++ /* Hildon: Disabling the automatic opening of submenus. */
++
++ if (event &&
++ event->type != GDK_BUTTON_PRESS &&
++ event->type != GDK_ENTER_NOTIFY &&
++ event->type != GDK_MOTION_NOTIFY) /*hildon: for some reason, the event is sometimes this and not enter!*/
++ menu_item->timer_from_keypress = TRUE;
++ else if (event)
++ {
++ /* mouse/pen events */
++ /* here is a problem -- when a menu item with sub menus gets a mouse event,
++ another event is generated for the submenu (and further its submenu etc.)
++ This leads to a behaviour which does not comply to the hildon spec. */
++ menu_item->timer_from_keypress = FALSE;
++ }
++ else /* does this really happen? */
++ menu_item->timer_from_keypress = FALSE;
++ }
+ else
+- _gtk_menu_item_popup_submenu (GTK_WIDGET (menu_item));
++ _gtk_menu_item_popup_submenu (menu_item);
++
++ if (event)
++ gdk_event_free (event);
+ }
+-
++
+ gtk_widget_set_state (GTK_WIDGET (menu_item), GTK_STATE_PRELIGHT);
+ gtk_widget_queue_draw (GTK_WIDGET (menu_item));
+ }
+@@ -878,25 +991,16 @@
+ static void
+ gtk_real_menu_item_deselect (GtkItem *item)
+ {
+- GtkMenuItem *menu_item;
++ GtkWidget *menu_item;
+
+ g_return_if_fail (GTK_IS_MENU_ITEM (item));
+
+- menu_item = GTK_MENU_ITEM (item);
++ menu_item = GTK_WIDGET (item);
+
+- if (menu_item->submenu)
+- {
+- if (menu_item->timer)
+- {
+- g_source_remove (menu_item->timer);
+- menu_item->timer = 0;
+- }
+- else
+- gtk_menu_popdown (GTK_MENU (menu_item->submenu));
+- }
++ _gtk_menu_item_popdown_submenu (menu_item);
+
+- gtk_widget_set_state (GTK_WIDGET (menu_item), GTK_STATE_NORMAL);
+- gtk_widget_queue_draw (GTK_WIDGET (menu_item));
++ gtk_widget_set_state (menu_item, GTK_STATE_NORMAL);
++ gtk_widget_queue_draw (menu_item);
+ }
+
+ static gboolean
+@@ -941,10 +1045,7 @@
+ _gtk_menu_shell_activate (menu_shell);
+
+ gtk_menu_shell_select_item (GTK_MENU_SHELL (widget->parent), widget);
+- _gtk_menu_item_popup_submenu (widget);
+-
+- gtk_menu_shell_select_first (GTK_MENU_SHELL (menu_item->submenu), TRUE);
+- submenu = GTK_MENU_SHELL (menu_item->submenu);
++ /* Hildon mod: automatic submenu opening has been removed */
+ }
+ }
+ }
+@@ -983,7 +1084,7 @@
+ {
+ _gtk_menu_item_popup_submenu (GTK_WIDGET (menu_item));
+ if (menu_item->timer_from_keypress && menu_item->submenu)
+- GTK_MENU_SHELL (menu_item->submenu)->ignore_enter = TRUE;
++ GTK_MENU_SHELL (menu_item->submenu)->ignore_enter = TRUE;
+ }
+
+ GDK_THREADS_LEAVE ();
+@@ -1002,7 +1103,16 @@
+ g_source_remove (menu_item->timer);
+ menu_item->timer = 0;
+
++ /* HILDON MOD. This is required as changed submenu arrow isn't drawn automatically
++ * and drawing it must be requested. */
++ gtk_widget_queue_draw (widget);
++
+ if (GTK_WIDGET_IS_SENSITIVE (menu_item->submenu))
++ {
++ gboolean take_focus;
++ take_focus = gtk_menu_shell_get_take_focus (GTK_MENU_SHELL (widget->parent));
++ gtk_menu_shell_set_take_focus (GTK_MENU_SHELL (menu_item->submenu),take_focus);
++
+ gtk_menu_popup (GTK_MENU (menu_item->submenu),
+ widget->parent,
+ widget,
+@@ -1010,6 +1120,28 @@
+ menu_item,
+ GTK_MENU_SHELL (widget->parent)->button,
+ 0);
++ }
++}
++
++void
++_gtk_menu_item_popdown_submenu (GtkWidget *widget)
++{
++ GtkMenuItem *menu_item;
++
++ menu_item = GTK_MENU_ITEM (widget);
++
++ if (menu_item->submenu)
++ {
++ if (menu_item->timer)
++ {
++ g_source_remove (menu_item->timer);
++ menu_item->timer = 0;
++ }
++ else
++ gtk_menu_popdown (GTK_MENU (menu_item->submenu));
++ }
++
++ gtk_widget_queue_draw (widget);
+ }
+
+ static void
+@@ -1092,14 +1224,17 @@
+ tx += widget->allocation.width - twidth;
+ }
+
++/* HILDON modifications
++ * Here we make the submenu of an menubar appear under the menubar.
++ * The only exception is when the resulting menu would be under 100 pixels
++ * high. In that case, the menu is made 100 pixels high.
++ */
+ if ((ty + widget->allocation.height + theight) <= monitor.y + monitor.height)
+ ty += widget->allocation.height;
+- else if ((ty - theight) >= monitor.y)
+- ty -= theight;
+- else if (monitor.y + monitor.height - (ty + widget->allocation.height) > ty)
++ else if ((ty + widget->allocation.height) < monitor.y + monitor.height - 120)
+ ty += widget->allocation.height;
+ else
+- ty -= theight;
++ ty = monitor.y + monitor.height - 120;
+ break;
+
+ case GTK_LEFT_RIGHT:
+@@ -1404,3 +1539,30 @@
+
+ return TRUE;
+ }
++
++/* Hildon modification :
++ * This function exists only for opening submenus on
++ * activation. */
++static void
++_gtk_menu_item_activate_submenus (GtkMenuItem *item)
++{
++ GdkEvent *event;
++
++ g_return_if_fail (GTK_IS_MENU_ITEM (item));
++
++ if (!GTK_IS_MENU (item->submenu) ||
++ GTK_WIDGET_VISIBLE (item->submenu))
++ return;
++
++ event = gtk_get_current_event ();
++ _gtk_menu_item_popup_submenu (item);
++
++ /* We don't want to select first item if the submenu
++ * is opened with mouse release because the selection
++ * would move straigh back under the cursor. */
++ if ((event == NULL) || (event->type != GDK_BUTTON_RELEASE))
++ gtk_menu_shell_select_first (GTK_MENU_SHELL (item->submenu), TRUE);
++
++ if (event)
++ gdk_event_free (event);
++}