summaryrefslogtreecommitdiffstats
path: root/meta/packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenu.c.diff
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenu.c.diff')
-rw-r--r--meta/packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenu.c.diff1223
1 files changed, 1223 insertions, 0 deletions
diff --git a/meta/packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenu.c.diff b/meta/packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenu.c.diff
new file mode 100644
index 0000000000..16fac1b155
--- /dev/null
+++ b/meta/packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenu.c.diff
@@ -0,0 +1,1223 @@
1--- gtk+-2.6.4/gtk/gtkmenu.c 2005-03-01 08:28:56.000000000 +0200
2+++ gtk+-2.6.4/gtk/gtkmenu.c 2005-04-06 16:19:36.921925376 +0300
3@@ -24,10 +24,16 @@
4 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
5 */
6
7+/* Modified for Nokia Oyj during 2002-2005. See CHANGES file for list
8+ * of changes.
9+ */
10+
11 #define GTK_MENU_INTERNALS
12
13 #include <config.h>
14 #include <string.h> /* memset */
15+#include <math.h>
16+#include <stdlib.h>
17 #include "gdk/gdkkeysyms.h"
18 #include "gtkalias.h"
19 #include "gtkaccellabel.h"
20@@ -44,7 +50,11 @@
21 #include "gtkvscrollbar.h"
22 #include "gtksettings.h"
23 #include "gtkintl.h"
24+#include "gtkcombobox.h"
25
26+/* Hildon : We need this to figure out if menu should have
27+ * corners etc. */
28+#include "gtkmenubar.h"
29
30 #define MENU_ITEM_CLASS(w) GTK_MENU_ITEM_GET_CLASS (w)
31
32@@ -55,16 +65,43 @@
33 * extends below the submenu
34 */
35
36+/* HILDON:
37+ * Urgh, nasty thing to hard-code things like these :p
38+ * One should really do some rewriting here...
39+ */
40+
41 #define MENU_SCROLL_STEP1 8
42 #define MENU_SCROLL_STEP2 15
43-#define MENU_SCROLL_ARROW_HEIGHT 16
44-#define MENU_SCROLL_FAST_ZONE 8
45+#define MENU_SCROLL_ARROW_HEIGHT 20 /* This used to be: 23; This hard-coding should be
46+ * changed. Add arrow_height style property into
47+ * commongtkrc and read it from there everywhere
48+ * where a reference to MENU_SCROLL_ARROW_HEIGHT
49+ * is made.
50+ * If these changes are made, please modify also
51+ * gtkcombobox.c.
52+ */
53+#define MENU_SCROLL_FAST_ZONE MENU_SCROLL_ARROW_HEIGHT /* Was originally 8 */
54 #define MENU_SCROLL_TIMEOUT1 50
55 #define MENU_SCROLL_TIMEOUT2 20
56
57 #define ATTACH_INFO_KEY "gtk-menu-child-attach-info-key"
58 #define ATTACHED_MENUS "gtk-attached-menus"
59
60+/* HILDON: */
61+#define HILDON_MENU_NAME_SHARP "menu_with_corners"
62+
63+/* needed to allow different themeing for first level menus */
64+#define HILDON_MENU_NAME_ROUND_FIRST_LEVEL "menu_without_corners_first_level"
65+#define HILDON_MENU_NAME_ROUND "menu_without_corners"
66+#define HILDON_MENU_NAME_FORCE_SHARP "menu_force_with_corners"
67+#define HILDON_MENU_NAME_FORCE_ROUND "menu_force_without_corners"
68+
69+/* maximum sizes for menus when attached to comboboxes */
70+#define HILDON_MENU_COMBO_MAX_WIDTH 406
71+#define HILDON_MENU_COMBO_MIN_WIDTH 66
72+#define HILDON_MENU_COMBO_MAX_HEIGHT 305
73+#define HILDON_MENU_COMBO_MIN_HEIGHT 70
74+
75 typedef struct _GtkMenuAttachData GtkMenuAttachData;
76 typedef struct _GtkMenuPrivate GtkMenuPrivate;
77
78@@ -92,6 +129,15 @@
79 gboolean have_layout;
80 gint n_rows;
81 gint n_columns;
82+
83+ /* Arrow states */
84+ GtkStateType lower_arrow_state;
85+ GtkStateType upper_arrow_state;
86+
87+ /* For context menu behavior */
88+ gboolean context_menu;
89+ int popup_pointer_x;
90+ int popup_pointer_y;
91 };
92
93 typedef struct
94@@ -108,6 +154,7 @@
95
96 enum {
97 MOVE_SCROLL,
98+ CLOSE_CURRENT,
99 LAST_SIGNAL
100 };
101
102@@ -191,7 +238,8 @@
103 static void gtk_menu_handle_scrolling (GtkMenu *menu,
104 gint event_x,
105 gint event_y,
106- gboolean enter);
107+ gboolean enter,
108+ gboolean motion);
109 static void gtk_menu_set_tearoff_hints (GtkMenu *menu,
110 gint width);
111 static void gtk_menu_style_set (GtkWidget *widget,
112@@ -232,6 +280,9 @@
113 guint signal_id);
114 static void _gtk_menu_refresh_accel_paths (GtkMenu *menu,
115 gboolean group_changed);
116+static gboolean gtk_menu_check_name (GtkWidget *widget);
117+
118+static void _gtk_menu_close_current (GtkMenu *menu);
119
120 static GtkMenuShellClass *parent_class = NULL;
121 static const gchar attach_data_key[] = "gtk-menu-attach-data";
122@@ -496,7 +547,6 @@
123 widget_class->hide_all = gtk_menu_hide_all;
124 widget_class->enter_notify_event = gtk_menu_enter_notify;
125 widget_class->leave_notify_event = gtk_menu_leave_notify;
126- widget_class->motion_notify_event = gtk_menu_motion_notify;
127 widget_class->style_set = gtk_menu_style_set;
128 widget_class->focus = gtk_menu_focus;
129 widget_class->can_activate_accel = gtk_menu_real_can_activate_accel;
130@@ -521,6 +571,15 @@
131 _gtk_marshal_VOID__ENUM,
132 G_TYPE_NONE, 1,
133 GTK_TYPE_SCROLL_TYPE);
134+
135+ menu_signals[CLOSE_CURRENT] =
136+ _gtk_binding_signal_new ("close_current",
137+ G_OBJECT_CLASS_TYPE (object_class),
138+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
139+ G_CALLBACK (_gtk_menu_close_current),
140+ NULL, NULL,
141+ _gtk_marshal_VOID__VOID,
142+ G_TYPE_NONE, 0);
143
144 g_object_class_install_property (gobject_class,
145 PROP_TEAROFF_TITLE,
146@@ -606,6 +665,11 @@
147 G_PARAM_READWRITE));
148
149 binding_set = gtk_binding_set_by_class (class);
150+ /* Hildon : We moved handling of escape-key here because we need it to
151+ * work like closing a submenu, not closing all the menus. */
152+ gtk_binding_entry_add_signal (binding_set,
153+ GDK_Escape, 0,
154+ "close_current", 0);
155 gtk_binding_entry_add_signal (binding_set,
156 GDK_Up, 0,
157 "move_current", 1,
158@@ -709,6 +773,25 @@
159 DEFAULT_POPDOWN_DELAY,
160 G_PARAM_READWRITE));
161
162+ /* Hildon addition : border width was
163+ replaced with horizontal-padding and
164+ vertical-padding (which already is an style
165+ property for GtkMenu). */
166+ gtk_widget_class_install_style_property (widget_class,
167+ g_param_spec_int ("horizontal-padding",
168+ P_("Horizontal Padding"),
169+ P_("Extra space at the left and right edges of the menu"),
170+ 0,
171+ G_MAXINT,
172+ 0, /* 1, */
173+ G_PARAM_READABLE));
174+
175+ gtk_widget_class_install_style_property (widget_class,
176+ g_param_spec_boolean ("double_arrows",
177+ P_("Double Arrows"),
178+ P_("When scrolling, always show both arrows."),
179+ FALSE,
180+ G_PARAM_READABLE));
181 }
182
183
184@@ -884,13 +967,14 @@
185 menu->toggle_size = 0;
186
187 menu->toplevel = g_object_connect (g_object_new (GTK_TYPE_WINDOW,
188- "type", GTK_WINDOW_POPUP,
189- "child", menu,
190- NULL),
191+ "type", GTK_WINDOW_POPUP,
192+ "child", menu,
193+ NULL),
194 "signal::event", gtk_menu_window_event, menu,
195 "signal::size_request", gtk_menu_window_size_request, menu,
196 "signal::destroy", gtk_widget_destroyed, &menu->toplevel,
197 NULL);
198+
199 gtk_window_set_resizable (GTK_WINDOW (menu->toplevel), FALSE);
200 gtk_window_set_mnemonic_modifier (GTK_WINDOW (menu->toplevel), 0);
201
202@@ -919,6 +1003,15 @@
203 menu->lower_arrow_visible = FALSE;
204 menu->upper_arrow_prelight = FALSE;
205 menu->lower_arrow_prelight = FALSE;
206+
207+ /* <Hildon> */
208+ priv->upper_arrow_state = GTK_STATE_NORMAL;
209+ priv->lower_arrow_state = GTK_STATE_NORMAL;
210+
211+ priv->context_menu = FALSE;
212+ priv->popup_pointer_x = -1;
213+ priv->popup_pointer_y = -1;
214+ /* </hildon */
215
216 priv->have_layout = FALSE;
217 }
218@@ -1220,7 +1313,8 @@
219
220 static gboolean
221 popup_grab_on_window (GdkWindow *window,
222- guint32 activate_time)
223+ guint32 activate_time,
224+ gboolean grab_keyboard)
225 {
226 if ((gdk_pointer_grab (window, TRUE,
227 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
228@@ -1228,7 +1322,8 @@
229 GDK_POINTER_MOTION_MASK,
230 NULL, NULL, activate_time) == 0))
231 {
232- if (gdk_keyboard_grab (window, TRUE,
233+ if (!grab_keyboard ||
234+ gdk_keyboard_grab (window, TRUE,
235 activate_time) == 0)
236 return TRUE;
237 else
238@@ -1282,6 +1377,7 @@
239 GtkWidget *parent;
240 GdkEvent *current_event;
241 GtkMenuShell *menu_shell;
242+ gboolean grab_keyboard;
243 GtkMenuPrivate *priv = gtk_menu_get_private (menu);
244
245 g_return_if_fail (GTK_IS_MENU (menu));
246@@ -1333,10 +1429,28 @@
247 * probably could just leave the grab on the other window, with a
248 * little reorganization of the code in gtkmenu*).
249 */
250+
251+ grab_keyboard = gtk_menu_shell_get_take_focus (menu_shell);
252+ gtk_window_set_accept_focus (GTK_WINDOW (menu->toplevel), grab_keyboard);
253+
254 if (xgrab_shell && xgrab_shell != widget)
255 {
256- if (popup_grab_on_window (xgrab_shell->window, activate_time))
257+ if (popup_grab_on_window (xgrab_shell->window, activate_time, grab_keyboard))
258 GTK_MENU_SHELL (xgrab_shell)->have_xgrab = TRUE;
259+
260+ /* HILDON:
261+ * Check wheter parent is GtkMenuBar. If so,
262+ * then we need sharp upper corners for this menu.
263+ */
264+ if (gtk_menu_check_name (widget))
265+ {
266+ if (GTK_IS_MENU_BAR (parent_menu_shell))
267+ gtk_widget_set_name (widget, HILDON_MENU_NAME_SHARP);
268+ else if (GTK_IS_MENU (parent_menu_shell))
269+ gtk_widget_set_name( widget, HILDON_MENU_NAME_ROUND);
270+ else
271+ gtk_widget_set_name (widget, HILDON_MENU_NAME_ROUND_FIRST_LEVEL);
272+ }
273 }
274 else
275 {
276@@ -1344,8 +1458,14 @@
277
278 xgrab_shell = widget;
279 transfer_window = menu_grab_transfer_window_get (menu);
280- if (popup_grab_on_window (transfer_window, activate_time))
281+ if (popup_grab_on_window (transfer_window, activate_time, grab_keyboard))
282 GTK_MENU_SHELL (xgrab_shell)->have_xgrab = TRUE;
283+
284+ /* HILDON:
285+ * We want this menu to have round corners (Used by default)
286+ */
287+ if (gtk_menu_check_name (widget))
288+ gtk_widget_set_name (widget, HILDON_MENU_NAME_ROUND_FIRST_LEVEL);
289 }
290
291 if (!GTK_MENU_SHELL (xgrab_shell)->have_xgrab)
292@@ -1409,6 +1529,23 @@
293
294 /* Position the menu, possibly changing the size request
295 */
296+ if (GTK_IS_COMBO_BOX (gtk_menu_get_attach_widget (menu)))
297+ {
298+ /* Hildon - limit the size if the menu is attached to a ComboBox */
299+ GtkRequisition req;
300+ gint width, height;
301+
302+ gtk_widget_set_size_request (widget, -1, -1);
303+ gtk_widget_size_request (widget, &req);
304+
305+ width = MAX (MIN (req.width, HILDON_MENU_COMBO_MAX_WIDTH),
306+ HILDON_MENU_COMBO_MIN_WIDTH);
307+ height = MAX (MIN (req.height, HILDON_MENU_COMBO_MAX_HEIGHT),
308+ HILDON_MENU_COMBO_MIN_HEIGHT);
309+
310+ gtk_widget_set_size_request (widget, width, height);
311+ }
312+
313 gtk_menu_position (menu);
314
315 /* Compute the size of the toplevel and realize it so we
316@@ -1430,13 +1567,29 @@
317
318 gtk_menu_scroll_to (menu, menu->scroll_offset);
319
320+ if (priv->context_menu)
321+ {
322+ /* Save position of the pointer during popup */
323+ /* currently not-multihead safe */
324+ GdkScreen *screen;
325+ GdkDisplay *display;
326+
327+ screen = gtk_widget_get_screen (widget);
328+ display = gdk_screen_get_display (screen);
329+
330+ gdk_display_get_pointer (display, NULL,
331+ &priv->popup_pointer_x,
332+ &priv->popup_pointer_y,
333+ NULL);
334+ }
335+
336 /* Once everything is set up correctly, map the toplevel window on
337 the screen.
338 */
339 gtk_widget_show (menu->toplevel);
340
341 if (xgrab_shell == widget)
342- popup_grab_on_window (widget->window, activate_time); /* Should always succeed */
343+ popup_grab_on_window (widget->window, activate_time, grab_keyboard); /* Should always succeed */
344 gtk_grab_add (GTK_WIDGET (menu));
345 }
346
347@@ -1996,6 +2149,7 @@
348 GtkWidget *child;
349 GList *children;
350 guint vertical_padding;
351+ guint horizontal_padding;
352
353 g_return_if_fail (GTK_IS_MENU (widget));
354
355@@ -2025,9 +2179,10 @@
356
357 gtk_widget_style_get (GTK_WIDGET (menu),
358 "vertical-padding", &vertical_padding,
359+ "horizontal-padding", &horizontal_padding,
360 NULL);
361
362- attributes.x = border_width + widget->style->xthickness;
363+ attributes.x = border_width + widget->style->xthickness + horizontal_padding;
364 attributes.y = border_width + widget->style->ythickness + vertical_padding;
365 attributes.width = MAX (1, widget->allocation.width - attributes.x * 2);
366 attributes.height = MAX (1, widget->allocation.height - attributes.y * 2);
367@@ -2040,11 +2195,14 @@
368 if (menu->lower_arrow_visible)
369 attributes.height -= MENU_SCROLL_ARROW_HEIGHT;
370
371+ attributes.window_type = GDK_WINDOW_CHILD;
372+
373 menu->view_window = gdk_window_new (widget->window, &attributes, attributes_mask);
374 gdk_window_set_user_data (menu->view_window, menu);
375
376 attributes.x = 0;
377 attributes.y = 0;
378+ attributes.width = MAX (1, widget->requisition.width - (border_width + widget->style->xthickness + horizontal_padding) * 2);
379 attributes.height = MAX (1, widget->requisition.height - (border_width + widget->style->ythickness + vertical_padding) * 2);
380
381 menu->bin_window = gdk_window_new (menu->view_window, &attributes, attributes_mask);
382@@ -2164,6 +2322,10 @@
383 guint vertical_padding;
384 GtkRequisition child_requisition;
385 GtkMenuPrivate *priv;
386+ guint horizontal_padding;
387+ GdkScreen *screen;
388+ GdkRectangle monitor;
389+ gint monitor_num;
390
391 g_return_if_fail (GTK_IS_MENU (widget));
392 g_return_if_fail (requisition != NULL);
393@@ -2182,6 +2344,16 @@
394 priv->heights = g_new0 (guint, gtk_menu_get_n_rows (menu));
395 priv->heights_length = gtk_menu_get_n_rows (menu);
396
397+/* Hildon addition to find out the monitor width */
398+ screen = gtk_widget_get_screen (widget);
399+ if (widget->window != NULL)
400+ monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
401+ else
402+ monitor_num = 0;
403+ if (monitor_num < 0)
404+ monitor_num = 0;
405+ gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
406+
407 children = menu_shell->children;
408 while (children)
409 {
410@@ -2223,15 +2395,18 @@
411
412 requisition->width += max_toggle_size + max_accel_width;
413 requisition->width *= gtk_menu_get_n_columns (menu);
414- requisition->width += (GTK_CONTAINER (menu)->border_width +
415- widget->style->xthickness) * 2;
416
417 gtk_widget_style_get (GTK_WIDGET (menu),
418+ "horizontal-padding", &horizontal_padding,
419 "vertical-padding", &vertical_padding,
420 NULL);
421+ requisition->width += (GTK_CONTAINER (menu)->border_width + horizontal_padding +
422+ widget->style->xthickness) * 2;
423 requisition->height += (GTK_CONTAINER (menu)->border_width + vertical_padding +
424 widget->style->ythickness) * 2;
425
426+/* Hildon addition to not make the menu too wide for the screen. */
427+ requisition->width = MIN (requisition->width, monitor.width);
428 menu->toggle_size = max_toggle_size;
429
430 /* Don't resize the tearoff if it is not active, because it won't redraw (it is only a background pixmap).
431@@ -2253,6 +2428,7 @@
432 GList *children;
433 gint x, y;
434 gint width, height;
435+ guint horizontal_padding;
436 guint vertical_padding;
437
438 g_return_if_fail (GTK_IS_MENU (widget));
439@@ -2266,10 +2442,11 @@
440 gtk_widget_get_child_requisition (GTK_WIDGET (menu), &child_requisition);
441
442 gtk_widget_style_get (GTK_WIDGET (menu),
443+ "horizontal-padding", &horizontal_padding,
444 "vertical-padding", &vertical_padding,
445 NULL);
446
447- x = GTK_CONTAINER (menu)->border_width + widget->style->xthickness;
448+ x = GTK_CONTAINER (menu)->border_width + widget->style->xthickness + horizontal_padding;
449 y = GTK_CONTAINER (menu)->border_width + widget->style->ythickness + vertical_padding;
450
451 width = MAX (1, allocation->width - x * 2);
452@@ -2407,27 +2584,32 @@
453 GdkEventExpose *event)
454 {
455 GtkMenu *menu;
456- gint width, height;
457- gint border_x, border_y;
458- guint vertical_padding;
459
460 g_return_if_fail (GTK_IS_MENU (widget));
461
462 menu = GTK_MENU (widget);
463
464- gtk_widget_style_get (GTK_WIDGET (menu),
465- "vertical-padding", &vertical_padding,
466- NULL);
467-
468- border_x = GTK_CONTAINER (widget)->border_width + widget->style->xthickness;
469- border_y = GTK_CONTAINER (widget)->border_width + widget->style->ythickness + vertical_padding;
470- gdk_drawable_get_size (widget->window, &width, &height);
471-
472 if (event->window == widget->window)
473 {
474+ gint width, height;
475+ gint border_x, border_y;
476+ guint vertical_padding;
477+ guint horizontal_padding;
478+ GtkMenuPrivate *priv;
479 gint arrow_space = MENU_SCROLL_ARROW_HEIGHT - 2 * widget->style->ythickness;
480 gint arrow_size = 0.7 * arrow_space;
481
482+ priv = gtk_menu_get_private (menu);
483+
484+ gtk_widget_style_get (GTK_WIDGET (menu),
485+ "vertical-padding", &vertical_padding,
486+ "horizontal-padding", &horizontal_padding,
487+ NULL);
488+
489+ border_x = GTK_CONTAINER (widget)->border_width + widget->style->xthickness + horizontal_padding;
490+ border_y = GTK_CONTAINER (widget)->border_width + widget->style->ythickness + vertical_padding;
491+ gdk_drawable_get_size (widget->window, &width, &height);
492+
493 gtk_paint_box (widget->style,
494 widget->window,
495 GTK_STATE_NORMAL,
496@@ -2436,21 +2618,9 @@
497 0, 0, -1, -1);
498 if (menu->upper_arrow_visible && !menu->tearoff_active)
499 {
500- gtk_paint_box (widget->style,
501- widget->window,
502- menu->upper_arrow_prelight ?
503- GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
504- GTK_SHADOW_OUT,
505- NULL, widget, "menu",
506- border_x,
507- border_y,
508- width - 2 * border_x,
509- MENU_SCROLL_ARROW_HEIGHT);
510-
511 gtk_paint_arrow (widget->style,
512 widget->window,
513- menu->upper_arrow_prelight ?
514- GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
515+ priv->upper_arrow_state,
516 GTK_SHADOW_OUT,
517 NULL, widget, "menu_scroll_arrow_up",
518 GTK_ARROW_UP,
519@@ -2462,21 +2632,9 @@
520
521 if (menu->lower_arrow_visible && !menu->tearoff_active)
522 {
523- gtk_paint_box (widget->style,
524- widget->window,
525- menu->lower_arrow_prelight ?
526- GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
527- GTK_SHADOW_OUT,
528- NULL, widget, "menu",
529- border_x,
530- height - border_y - MENU_SCROLL_ARROW_HEIGHT,
531- width - 2*border_x,
532- MENU_SCROLL_ARROW_HEIGHT);
533-
534 gtk_paint_arrow (widget->style,
535 widget->window,
536- menu->lower_arrow_prelight ?
537- GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
538+ priv->lower_arrow_state,
539 GTK_SHADOW_OUT,
540 NULL, widget, "menu_scroll_arrow_down",
541 GTK_ARROW_DOWN,
542@@ -2516,18 +2674,82 @@
543 GTK_WIDGET_CLASS (parent_class)->show (widget);
544 }
545
546+static GtkWidget *
547+find_active_menu_item (GdkEventButton *event)
548+{
549+ GtkWidget *menu_item;
550+
551+ menu_item = gtk_get_event_widget ((GdkEvent*) event);
552+ while (menu_item && !GTK_IS_MENU_ITEM (menu_item))
553+ menu_item = menu_item->parent;
554+
555+ return menu_item;
556+}
557+
558+static gboolean
559+pointer_in_menu_tree (GtkWidget *widget)
560+{
561+ GtkMenuShell *mshell;
562+ int width, height, x, y;
563+
564+ mshell = GTK_MENU_SHELL (widget);
565+
566+ gdk_window_get_pointer (widget->window, &x, &y, NULL);
567+ gdk_drawable_get_size (widget->window, &width, &height);
568+
569+ if ((x <= width) && (x >= 0) && (y <= height) && (y >= 0))
570+ return TRUE;
571+
572+ if ((mshell->parent_menu_shell != NULL) &&
573+ GTK_IS_MENU (mshell->parent_menu_shell))
574+ return pointer_in_menu_tree (mshell->parent_menu_shell);
575+
576+ return FALSE;
577+}
578+
579+static int
580+distance_traveled (GtkWidget *widget)
581+{
582+ GtkMenuPrivate *priv;
583+ GdkScreen *screen;
584+ GdkDisplay *display;
585+ int x, y, dx, dy;
586+
587+ priv = gtk_menu_get_private (GTK_MENU (widget));
588+
589+ screen = gtk_widget_get_screen (widget);
590+ display = gdk_screen_get_display (screen);
591+
592+ gdk_display_get_pointer (display, NULL, &x, &y, NULL);
593+
594+ dx = (priv->popup_pointer_x - x);
595+ dy = (priv->popup_pointer_y - y);
596+
597+ return abs ((int) sqrt ((double) (dx * dx + dy * dy)));
598+}
599+
600 static gboolean
601 gtk_menu_button_press (GtkWidget *widget,
602- GdkEventButton *event)
603+ GdkEventButton *event)
604 {
605- /* Don't pop down the menu for releases over scroll arrows
606- */
607- if (GTK_IS_MENU (widget))
608+ GtkWidget *menu_item;
609+
610+ menu_item = find_active_menu_item (event);
611+ if (menu_item == NULL)
612 {
613 GtkMenu *menu = GTK_MENU (widget);
614
615- if (menu->upper_arrow_prelight || menu->lower_arrow_prelight)
616- return TRUE;
617+ if (menu->upper_arrow_prelight || menu->lower_arrow_prelight)
618+ {
619+ gtk_menu_handle_scrolling (GTK_MENU (widget), event->x_root, event->y_root, TRUE, FALSE);
620+
621+ return TRUE;
622+ }
623+
624+ /* Don't pass down to menu shell if a non-menuitem part
625+ * of the menu was clicked. */
626+ if (pointer_in_menu_tree (widget))
627+ return TRUE;
628 }
629
630 return GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, event);
631@@ -2537,14 +2759,44 @@
632 gtk_menu_button_release (GtkWidget *widget,
633 GdkEventButton *event)
634 {
635- /* Don't pop down the menu for releases over scroll arrows
636- */
637- if (GTK_IS_MENU (widget))
638+ GtkMenuPrivate *priv;
639+ GtkWidget *menu_item;
640+
641+ priv = gtk_menu_get_private (GTK_MENU (widget));
642+
643+ menu_item = find_active_menu_item (event);
644+ if (menu_item == NULL)
645 {
646 GtkMenu *menu = GTK_MENU (widget);
647
648- if (menu->upper_arrow_prelight || menu->lower_arrow_prelight)
649- return TRUE;
650+ if (menu->upper_arrow_prelight || menu->lower_arrow_prelight)
651+ {
652+ gtk_menu_handle_scrolling (GTK_MENU (widget), event->x_root, event->y_root, FALSE, FALSE);
653+
654+ return TRUE;
655+ }
656+
657+ if (priv->context_menu &&
658+ (priv->popup_pointer_x >= 0) &&
659+ (priv->popup_pointer_y >= 0))
660+ {
661+ int distance;
662+
663+ distance = distance_traveled (widget);
664+
665+ priv->popup_pointer_x = -1;
666+ priv->popup_pointer_y = -1;
667+
668+ /* Don't popdown if we traveled less than 20px since popup point,
669+ * as per the specs. */
670+ if (distance < 20)
671+ return TRUE;
672+ }
673+
674+ /* Don't pass down to menu shell if a non-menuitem part
675+ * of the menu was clicked. */
676+ if (pointer_in_menu_tree (widget))
677+ return TRUE;
678 }
679
680 return GTK_WIDGET_CLASS (parent_class)->button_release_event (widget, event);
681@@ -2765,7 +3017,7 @@
682 gboolean need_enter;
683
684 if (GTK_IS_MENU (widget))
685- gtk_menu_handle_scrolling (GTK_MENU (widget), event->x_root, event->y_root, TRUE);
686+ gtk_menu_handle_scrolling (GTK_MENU (widget), event->x_root, event->y_root, TRUE, TRUE);
687
688 /* We received the event for one of two reasons:
689 *
690@@ -2779,7 +3031,27 @@
691 menu_item = gtk_get_event_widget ((GdkEvent*) event);
692 if (!menu_item || !GTK_IS_MENU_ITEM (menu_item) ||
693 !GTK_IS_MENU (menu_item->parent))
694- return FALSE;
695+ {
696+ GtkMenuPrivate *priv;
697+
698+ priv = gtk_menu_get_private (GTK_MENU (widget));
699+
700+ if (priv->context_menu)
701+ {
702+ /* Context menu mode. If we dragged out of the menu,
703+ * close the menu, as by the specs. */
704+ if (!pointer_in_menu_tree (widget) &&
705+ (distance_traveled (widget) >= 20) &&
706+ (event->state & GDK_BUTTON1_MASK))
707+ {
708+ gtk_menu_deactivate (GTK_MENU_SHELL (widget));
709+
710+ return TRUE;
711+ }
712+ }
713+
714+ return FALSE;
715+ }
716
717 menu_shell = GTK_MENU_SHELL (menu_item->parent);
718 menu = GTK_MENU (menu_shell);
719@@ -2795,6 +3067,11 @@
720 */
721 if (gtk_menu_navigating_submenu (menu, event->x_root, event->y_root))
722 return TRUE;
723+/* HILDON MOD.
724+ * Close the submenus that are two levels down from the currently selected.
725+ * This ensures that the focus is correct all the time.*/
726+ if (GTK_MENU_ITEM(menu_item)->submenu != NULL)
727+ gtk_menu_shell_deselect (GTK_MENU_SHELL(&(GTK_MENU(GTK_MENU_ITEM(menu_item)->submenu)->menu_shell)));
728
729 /* Make sure we pop down if we enter a non-selectable menu item, so we
730 * don't show a submenu when the cursor is outside the stay-up triangle.
731@@ -2828,6 +3105,7 @@
732 send_event->crossing.y_root = event->y_root;
733 send_event->crossing.x = event->x;
734 send_event->crossing.y = event->y;
735+ send_event->crossing.state = event->state;
736
737 /* We send the event to 'widget', the currently active menu,
738 * instead of 'menu', the menu that the pointer is in. This
739@@ -2852,17 +3130,24 @@
740 GtkWidget *widget;
741 gint offset;
742 gint view_width, view_height;
743+ gboolean double_arrows;
744
745 widget = GTK_WIDGET (menu);
746 offset = menu->scroll_offset + step;
747
748+ /* get double_arrows style property */
749+ gtk_widget_style_get (widget,
750+ "double_arrows", &double_arrows,
751+ NULL);
752+
753 /* If we scroll upward and the non-visible top part
754 * is smaller than the scroll arrow it would be
755 * pretty stupid to show the arrow and taking more
756 * screen space than just scrolling to the top.
757 */
758- if ((step < 0) && (offset < MENU_SCROLL_ARROW_HEIGHT))
759- offset = 0;
760+ if (!double_arrows)
761+ if ((step < 0) && (offset < MENU_SCROLL_ARROW_HEIGHT))
762+ offset = 0;
763
764 /* Don't scroll over the top if we weren't before: */
765 if ((menu->scroll_offset >= 0) && (offset < 0))
766@@ -2874,6 +3159,12 @@
767 if (menu->scroll_offset > 0)
768 view_height -= MENU_SCROLL_ARROW_HEIGHT;
769
770+ /* When both arrows are always shown, reduce
771+ * view height even more.
772+ */
773+ if (double_arrows)
774+ view_height -= MENU_SCROLL_ARROW_HEIGHT;
775+
776 if ((menu->scroll_offset + view_height <= widget->requisition.height) &&
777 (offset + view_height > widget->requisition.height))
778 offset = widget->requisition.height - view_height;
779@@ -2922,18 +3213,21 @@
780 gtk_menu_handle_scrolling (GtkMenu *menu,
781 gint x,
782 gint y,
783- gboolean enter)
784+ gboolean enter,
785+ gboolean motion)
786 {
787 GtkMenuShell *menu_shell;
788+ GtkMenuPrivate *priv;
789 gint width, height;
790 gint border;
791 GdkRectangle rect;
792- gboolean in_arrow;
793 gboolean scroll_fast = FALSE;
794 guint vertical_padding;
795 gint top_x, top_y;
796 gint win_x, win_y;
797
798+ priv = gtk_menu_get_private (menu);
799+
800 menu_shell = GTK_MENU_SHELL (menu);
801
802 gdk_drawable_get_size (GTK_WIDGET (menu)->window, &width, &height);
803@@ -2946,10 +3240,11 @@
804 GTK_WIDGET (menu)->style->ythickness + vertical_padding;
805
806 gdk_window_get_position (menu->toplevel->window, &top_x, &top_y);
807+ x -= top_x;
808+ y -= top_y;
809+
810 gdk_window_get_position (GTK_WIDGET (menu)->window, &win_x, &win_y);
811- win_x += top_x;
812- win_y += top_y;
813-
814+
815 if (menu->upper_arrow_visible && !menu->tearoff_active)
816 {
817 rect.x = win_x;
818@@ -2957,35 +3252,49 @@
819 rect.width = width;
820 rect.height = MENU_SCROLL_ARROW_HEIGHT + border;
821
822- in_arrow = FALSE;
823+ menu->upper_arrow_prelight = FALSE;
824 if ((x >= rect.x) && (x < rect.x + rect.width) &&
825 (y >= rect.y) && (y < rect.y + rect.height))
826- {
827- in_arrow = TRUE;
828- scroll_fast = (y < rect.y + MENU_SCROLL_FAST_ZONE);
829- }
830-
831- if (enter && in_arrow &&
832- (!menu->upper_arrow_prelight || menu->scroll_fast != scroll_fast))
833- {
834- menu->upper_arrow_prelight = TRUE;
835- menu->scroll_fast = scroll_fast;
836- gdk_window_invalidate_rect (GTK_WIDGET (menu)->window, &rect, FALSE);
837-
838- /* Deselect the active item so that any submenus are poped down */
839- gtk_menu_shell_deselect (menu_shell);
840+ menu->upper_arrow_prelight = TRUE;
841
842- gtk_menu_remove_scroll_timeout (menu);
843- menu->scroll_step = (scroll_fast) ? -MENU_SCROLL_STEP2 : -MENU_SCROLL_STEP1;
844- menu->timeout_id = g_timeout_add ((scroll_fast) ? MENU_SCROLL_TIMEOUT2 : MENU_SCROLL_TIMEOUT1,
845- gtk_menu_scroll_timeout,
846- menu);
847- }
848- else if (!enter && !in_arrow && menu->upper_arrow_prelight)
849+ if (priv->upper_arrow_state != GTK_STATE_INSENSITIVE)
850 {
851- gdk_window_invalidate_rect (GTK_WIDGET (menu)->window, &rect, FALSE);
852-
853- gtk_menu_stop_scrolling (menu);
854+ if (enter && menu->upper_arrow_prelight &&
855+ (menu->timeout_id == 0 || menu->scroll_fast != scroll_fast))
856+ {
857+ menu->scroll_fast = scroll_fast;
858+
859+ /* Deselect the active item so that any submenus are poped down */
860+ gtk_menu_shell_deselect (menu_shell);
861+
862+ gtk_menu_remove_scroll_timeout (menu);
863+ menu->scroll_step = (scroll_fast) ? -MENU_SCROLL_STEP2 : -MENU_SCROLL_STEP1;
864+
865+ if (!motion)
866+ {
867+ /* Only do stuff on click. */
868+ GtkSettings *settings;
869+ guint timeout;
870+
871+ settings = gtk_settings_get_default ();
872+ g_object_get (settings, "gtk-update-timeout", &timeout, NULL);
873+
874+ menu->timeout_id = g_timeout_add (timeout / 2, gtk_menu_scroll_timeout, menu);
875+
876+ priv->upper_arrow_state = GTK_STATE_ACTIVE;
877+ }
878+
879+ gdk_window_invalidate_rect (GTK_WIDGET (menu)->window, &rect, FALSE);
880+ }
881+ else if (!enter)
882+ {
883+ gtk_menu_stop_scrolling (menu);
884+
885+ priv->upper_arrow_state = menu->upper_arrow_prelight ?
886+ GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
887+
888+ gdk_window_invalidate_rect (GTK_WIDGET (menu)->window, &rect, FALSE);
889+ }
890 }
891 }
892
893@@ -2996,36 +3305,50 @@
894 rect.width = width;
895 rect.height = MENU_SCROLL_ARROW_HEIGHT + border;
896
897- in_arrow = FALSE;
898+ menu->lower_arrow_prelight = FALSE;
899 if ((x >= rect.x) && (x < rect.x + rect.width) &&
900 (y >= rect.y) && (y < rect.y + rect.height))
901- {
902- in_arrow = TRUE;
903- scroll_fast = (y > rect.y + rect.height - MENU_SCROLL_FAST_ZONE);
904- }
905+ menu->lower_arrow_prelight = TRUE;
906
907- if (enter && in_arrow &&
908- (!menu->lower_arrow_prelight || menu->scroll_fast != scroll_fast))
909+ if (priv->lower_arrow_state != GTK_STATE_INSENSITIVE)
910 {
911- menu->lower_arrow_prelight = TRUE;
912- menu->scroll_fast = scroll_fast;
913- gdk_window_invalidate_rect (GTK_WIDGET (menu)->window, &rect, FALSE);
914+ if (enter && menu->lower_arrow_prelight &&
915+ (menu->timeout_id == 0 || menu->scroll_fast != scroll_fast))
916+ {
917+ menu->scroll_fast = scroll_fast;
918
919- /* Deselect the active item so that any submenus are poped down */
920- gtk_menu_shell_deselect (menu_shell);
921+ /* Deselect the active item so that any submenus are poped down */
922+ gtk_menu_shell_deselect (menu_shell);
923
924- gtk_menu_remove_scroll_timeout (menu);
925- menu->scroll_step = (scroll_fast) ? MENU_SCROLL_STEP2 : MENU_SCROLL_STEP1;
926- menu->timeout_id = g_timeout_add ((scroll_fast) ? MENU_SCROLL_TIMEOUT2 : MENU_SCROLL_TIMEOUT1,
927- gtk_menu_scroll_timeout,
928- menu);
929- }
930- else if (!enter && !in_arrow && menu->lower_arrow_prelight)
931- {
932- gdk_window_invalidate_rect (GTK_WIDGET (menu)->window, &rect, FALSE);
933-
934- gtk_menu_stop_scrolling (menu);
935- }
936+ gtk_menu_remove_scroll_timeout (menu);
937+ menu->scroll_step = (scroll_fast) ? MENU_SCROLL_STEP2 : MENU_SCROLL_STEP1;
938+
939+ if (!motion)
940+ {
941+ /* Only do stuff on click. */
942+ GtkSettings *settings;
943+ guint timeout;
944+
945+ settings = gtk_settings_get_default ();
946+ g_object_get (settings, "gtk-update-timeout", &timeout, NULL);
947+
948+ menu->timeout_id = g_timeout_add (timeout / 2, gtk_menu_scroll_timeout, menu);
949+
950+ priv->lower_arrow_state = GTK_STATE_ACTIVE;
951+ }
952+
953+ gdk_window_invalidate_rect (GTK_WIDGET (menu)->window, &rect, FALSE);
954+ }
955+ else if (!enter)
956+ {
957+ gtk_menu_stop_scrolling (menu);
958+
959+ priv->lower_arrow_state = menu->lower_arrow_prelight ?
960+ GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
961+
962+ gdk_window_invalidate_rect (GTK_WIDGET (menu)->window, &rect, FALSE);
963+ }
964+ }
965 }
966 }
967
968@@ -3041,7 +3364,7 @@
969 GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget);
970
971 if (!menu_shell->ignore_enter)
972- gtk_menu_handle_scrolling (GTK_MENU (widget), event->x_root, event->y_root, TRUE);
973+ gtk_menu_handle_scrolling (GTK_MENU (widget), event->x_root, event->y_root, TRUE, TRUE);
974 }
975
976 if (menu_item && GTK_IS_MENU_ITEM (menu_item))
977@@ -3106,7 +3429,7 @@
978 if (gtk_menu_navigating_submenu (menu, event->x_root, event->y_root))
979 return TRUE;
980
981- gtk_menu_handle_scrolling (menu, event->x_root, event->y_root, FALSE);
982+ gtk_menu_handle_scrolling (menu, event->x_root, event->y_root, FALSE, TRUE);
983
984 event_widget = gtk_get_event_widget ((GdkEvent*) event);
985
986@@ -3611,7 +3934,13 @@
987 requisition.width, requisition.height);
988 }
989
990- menu->scroll_offset = scroll_offset;
991+ /* Hildon hack for menu in comboboxes:
992+ * in case the menu in attached to a ComboBox, the scroll_offset is
993+ * calculated in the positioning function so we dont't overwrite it
994+ * with the value calculated above (in this function) */
995+ if ( !GTK_IS_COMBO_BOX(gtk_menu_get_attach_widget(menu)) )
996+ menu->scroll_offset = scroll_offset;
997+
998 }
999
1000 static void
1001@@ -3628,9 +3957,6 @@
1002 gtk_menu_stop_scrolling (GtkMenu *menu)
1003 {
1004 gtk_menu_remove_scroll_timeout (menu);
1005-
1006- menu->upper_arrow_prelight = FALSE;
1007- menu->lower_arrow_prelight = FALSE;
1008 }
1009
1010 static void
1011@@ -3644,6 +3970,8 @@
1012 gboolean last_visible;
1013 gint menu_height;
1014 guint vertical_padding;
1015+ guint horizontal_padding;
1016+ gboolean double_arrows;
1017
1018 widget = GTK_WIDGET (menu);
1019
1020@@ -3663,19 +3991,93 @@
1021
1022 gtk_widget_style_get (GTK_WIDGET (menu),
1023 "vertical-padding", &vertical_padding,
1024+ "horizontal-padding", &horizontal_padding,
1025+ "double_arrows", &double_arrows,
1026 NULL);
1027
1028 border_width = GTK_CONTAINER (menu)->border_width;
1029- view_width -= (border_width + widget->style->xthickness) * 2;
1030+ view_width -= (border_width + widget->style->xthickness + horizontal_padding) * 2;
1031 view_height -= (border_width + widget->style->ythickness + vertical_padding) * 2;
1032 menu_height = widget->requisition.height -
1033 (border_width + widget->style->ythickness + vertical_padding) * 2;
1034
1035- x = border_width + widget->style->xthickness;
1036+ x = border_width + widget->style->xthickness + horizontal_padding;
1037 y = border_width + widget->style->ythickness + vertical_padding;
1038
1039+ if (double_arrows && !menu->tearoff_active && (view_height < menu_height))
1040+ {
1041+ GtkMenuPrivate *priv;
1042+ GtkStateType upper_arrow_previous_state, lower_arrow_previous_state;
1043+
1044+ priv = gtk_menu_get_private (menu);
1045+
1046+ upper_arrow_previous_state = priv->upper_arrow_state;
1047+ lower_arrow_previous_state = priv->lower_arrow_state;
1048+
1049+ if (!menu->upper_arrow_visible || !menu->lower_arrow_visible)
1050+ gtk_widget_queue_draw (GTK_WIDGET (menu));
1051+
1052+ view_height -= 2*MENU_SCROLL_ARROW_HEIGHT;
1053+ y += MENU_SCROLL_ARROW_HEIGHT;
1054+
1055+ menu->upper_arrow_visible = menu->lower_arrow_visible = TRUE;
1056+ if (priv->upper_arrow_state == GTK_STATE_INSENSITIVE)
1057+ {
1058+ priv->upper_arrow_state = menu->upper_arrow_prelight ?
1059+ GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
1060+ }
1061+ if (priv->lower_arrow_state == GTK_STATE_INSENSITIVE)
1062+ {
1063+ priv->lower_arrow_state = menu->lower_arrow_prelight ?
1064+ GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
1065+ }
1066+
1067+ if (offset <= 0)
1068+ {
1069+ offset = 0;
1070+ priv->upper_arrow_state = GTK_STATE_INSENSITIVE;
1071+ }
1072+ if (offset >= menu_height - view_height)
1073+ {
1074+ offset = menu_height - view_height;
1075+ priv->lower_arrow_state = GTK_STATE_INSENSITIVE;
1076+ }
1077+
1078+ if ((priv->upper_arrow_state != upper_arrow_previous_state) ||
1079+ (priv->lower_arrow_state != lower_arrow_previous_state))
1080+ gtk_widget_queue_draw (GTK_WIDGET (menu));
1081+
1082+ if (upper_arrow_previous_state != GTK_STATE_INSENSITIVE &&
1083+ priv->upper_arrow_state == GTK_STATE_INSENSITIVE)
1084+ {
1085+ /* If we hid the upper arrow, possibly remove timeout */
1086+ if (menu->scroll_step < 0)
1087+ {
1088+ gtk_menu_stop_scrolling (menu);
1089+ gtk_widget_queue_draw (GTK_WIDGET (menu));
1090+ }
1091+ }
1092+
1093+ if (lower_arrow_previous_state != GTK_STATE_INSENSITIVE &&
1094+ priv->lower_arrow_state == GTK_STATE_INSENSITIVE)
1095+ {
1096+ /* If we hid the lower arrow, possibly remove timeout */
1097+ if (menu->scroll_step > 0)
1098+ {
1099+ gtk_menu_stop_scrolling (menu);
1100+ gtk_widget_queue_draw (GTK_WIDGET (menu));
1101+ }
1102+ }
1103+ }
1104+ else
1105 if (!menu->tearoff_active)
1106 {
1107+ if (offset <= 0)
1108+ offset = 0;
1109+
1110+ if (offset >= menu_height - view_height)
1111+ offset = menu_height - view_height;
1112+
1113 last_visible = menu->upper_arrow_visible;
1114 menu->upper_arrow_visible = offset > 0;
1115
1116@@ -3685,8 +4087,6 @@
1117 if ( (last_visible != menu->upper_arrow_visible) &&
1118 !menu->upper_arrow_visible)
1119 {
1120- menu->upper_arrow_prelight = FALSE;
1121-
1122 /* If we hid the upper arrow, possibly remove timeout */
1123 if (menu->scroll_step < 0)
1124 {
1125@@ -3704,8 +4104,6 @@
1126 if ( (last_visible != menu->lower_arrow_visible) &&
1127 !menu->lower_arrow_visible)
1128 {
1129- menu->lower_arrow_prelight = FALSE;
1130-
1131 /* If we hid the lower arrow, possibly remove timeout */
1132 if (menu->scroll_step > 0)
1133 {
1134@@ -3792,12 +4190,14 @@
1135 &child_offset, &child_height, &last_child))
1136 {
1137 guint vertical_padding;
1138+ gboolean double_arrows;
1139
1140 y = menu->scroll_offset;
1141 gdk_drawable_get_size (GTK_WIDGET (menu)->window, &width, &height);
1142
1143 gtk_widget_style_get (GTK_WIDGET (menu),
1144 "vertical-padding", &vertical_padding,
1145+ "double_arrows", &double_arrows,
1146 NULL);
1147
1148 height -= 2*GTK_CONTAINER (menu)->border_width + 2*GTK_WIDGET (menu)->style->ythickness + 2*vertical_padding;
1149@@ -3820,11 +4220,11 @@
1150 if (child_offset + child_height > y + height - arrow_height)
1151 {
1152 arrow_height = 0;
1153- if (!last_child && !menu->tearoff_active)
1154+ if ((!last_child && !menu->tearoff_active) || (double_arrows))
1155 arrow_height += MENU_SCROLL_ARROW_HEIGHT;
1156
1157 y = child_offset + child_height - height + arrow_height;
1158- if ((y > 0) && !menu->tearoff_active)
1159+ if (((y > 0) && !menu->tearoff_active) || (double_arrows))
1160 {
1161 /* Need upper arrow */
1162 arrow_height += MENU_SCROLL_ARROW_HEIGHT;
1163@@ -4374,3 +4774,60 @@
1164 return list;
1165 }
1166
1167+/* Little help function for making some sanity tests on this menu.
1168+ * Checks that given widget really is a menu and that it has no name
1169+ * assigned to it yet.
1170+ * Names used to do hildon theming:
1171+ * HILDON_MENU_NAME_SHARP for menu with sharp upper corners
1172+ * HILDON_MENU_NAME_ROUND for menu with round corners
1173+ */
1174+static gboolean
1175+gtk_menu_check_name (GtkWidget *widget)
1176+{
1177+ gboolean legal_name = FALSE;
1178+ gchar **tmp = NULL;
1179+ const gchar *name = NULL;
1180+ static gchar *menu_names[] = { "GtkMenu",
1181+ HILDON_MENU_NAME_SHARP,
1182+ HILDON_MENU_NAME_ROUND,
1183+ HILDON_MENU_NAME_ROUND_FIRST_LEVEL,
1184+ NULL };
1185+ if (GTK_IS_MENU (widget) &&
1186+ (name = gtk_widget_get_name (widget)))
1187+ {
1188+ if (!g_ascii_strcasecmp (name, HILDON_MENU_NAME_FORCE_SHARP) || !g_ascii_strcasecmp (name, HILDON_MENU_NAME_FORCE_ROUND))
1189+ return FALSE;
1190+ for (tmp = menu_names; *tmp; tmp++)
1191+ if (!g_ascii_strcasecmp (name, *tmp ))
1192+ {
1193+ legal_name = TRUE;
1194+ break;
1195+ }
1196+ }
1197+
1198+ return legal_name;
1199+}
1200+
1201+/* A function called when esc-key is pressed. */
1202+static void
1203+_gtk_menu_close_current (GtkMenu * menu)
1204+{
1205+ GtkMenuShell * shell = GTK_MENU_SHELL (menu);
1206+
1207+ /* Check is a submenu of current menu item is visible.
1208+ * If it is, close that first. */
1209+ if (shell->active_menu_item && (GTK_MENU_ITEM (shell->active_menu_item)->submenu) && GTK_WIDGET_VISIBLE (GTK_MENU_ITEM (shell->active_menu_item)->submenu))
1210+ gtk_menu_popdown (GTK_MENU (GTK_MENU_ITEM (shell->active_menu_item)->submenu));
1211+ else
1212+ gtk_menu_popdown (menu);
1213+
1214+}
1215+
1216+/* Hildon function to make context menus behave according to spec */
1217+void
1218+_gtk_menu_enable_context_menu_behavior (GtkMenu *menu)
1219+{
1220+ GtkMenuPrivate *priv = gtk_menu_get_private (menu);
1221+
1222+ priv->context_menu = TRUE;
1223+}