]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenuitem.c.diff
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / gtk+ / gtk+-2.6.4-1.osso7 / gtkmenuitem.c.diff
1 --- gtk+-2.6.4/gtk/gtkmenuitem.c        2004-12-28 09:39:31.000000000 +0200
2 +++ gtk+-2.6.4/gtk/gtkmenuitem.c        2005-04-06 16:19:36.973917472 +0300
3 @@ -24,6 +24,10 @@
4   * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
5   */
6  
7 +/* Modified for Nokia Oyj during 2002-2003. See CHANGES file for list
8 + * of changes.
9 + */
10 +
11  #define GTK_MENU_INTERNALS
12  
13  #include <config.h>
14 @@ -38,6 +42,9 @@
15  #include "gtkmenuitem.h"
16  #include "gtkseparatormenuitem.h"
17  
18 +#define HILDON_HEIGHT_INCREMENT  1
19 +#define HILDON_ARROW_SPACE       6
20 +
21  #define MENU_ITEM_CLASS(w)  GTK_MENU_ITEM_CLASS (GTK_OBJECT (w)->klass)
22  
23  enum {
24 @@ -95,6 +102,8 @@
25                                                   guint      signal_id);
26  
27  
28 +static void _gtk_menu_item_activate_submenus (GtkMenuItem *item);
29 +
30  static GtkItemClass *parent_class;
31  static guint menu_item_signals[LAST_SIGNAL] = { 0 };
32  
33 @@ -158,7 +167,9 @@
34    item_class->select = gtk_real_menu_item_select;
35    item_class->deselect = gtk_real_menu_item_deselect;
36  
37 -  klass->activate = NULL;
38 +  /* Hildon addition : Added this to catch the 
39 +   * activation of meuuitems with submenus. */
40 +  klass->activate = _gtk_menu_item_activate_submenus;
41    klass->activate_item = gtk_real_menu_item_activate_item;
42    klass->toggle_size_request = gtk_real_menu_item_toggle_size_request;
43    klass->toggle_size_allocate = gtk_real_menu_item_toggle_size_allocate;
44 @@ -239,6 +250,16 @@
45                                                              G_MAXINT,
46                                                              10,
47                                                              G_PARAM_READABLE));
48 +
49 +   /* Hildon modification - allow themeing of separator height */
50 +   gtk_widget_class_install_style_property (widget_class,
51 +                                          g_param_spec_int ("separator_height",
52 +                                                            "Separator height",
53 +                                                            "Draw a separator graphics with height of x pixels.",
54 +                                                            0,
55 +                                                           G_MAXINT,
56 +                                                           5,
57 +                                                            G_PARAM_READABLE));
58  }
59  
60  static void
61 @@ -415,6 +436,13 @@
62    g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
63    
64    gtk_item_select (GTK_ITEM (menu_item));
65 +  /* HILDON MOD. This is required as changed focus isn't drawn automatically
66 +   * and drawing it must be requested. */
67 +  if ((GTK_WIDGET(menu_item)->parent) && GTK_IS_MENU (GTK_WIDGET(menu_item)->parent))
68 +    {
69 +      GtkMenu *menu = GTK_MENU (GTK_WIDGET(menu_item)->parent);
70 +      if (menu->parent_menu_item) gtk_widget_queue_draw(GTK_WIDGET(menu->parent_menu_item));
71 +    }
72  }
73  
74  void
75 @@ -423,6 +451,13 @@
76    g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
77    
78    gtk_item_deselect (GTK_ITEM (menu_item));
79 +  /* HILDON MOD. This is required as changed focus isn't drawn automatically
80 +   * and drawing it must be requested. */
81 +  if ((GTK_WIDGET(menu_item)->parent) && GTK_IS_MENU (GTK_WIDGET(menu_item)->parent))
82 +    {
83 +      GtkMenu *menu = GTK_MENU (GTK_WIDGET(menu_item)->parent);
84 +      if (menu->parent_menu_item) gtk_widget_queue_draw(GTK_WIDGET(menu->parent_menu_item));
85 +    }
86  }
87  
88  void
89 @@ -531,7 +566,7 @@
90                                 "arrow_spacing", &arrow_spacing,
91                                 NULL);
92  
93 -         requisition->width += child_requisition.height;
94 +         requisition->width += child_requisition.height + HILDON_ARROW_SPACE;
95           requisition->width += arrow_spacing;
96  
97           requisition->width = MAX (requisition->width, get_minimum_width (widget));
98 @@ -543,6 +578,12 @@
99        requisition->height += 4;
100      }
101  
102 +   /* We get correct focus size if we make the widget a bit bigger.
103 +    * (If the increment would be big, we should probably adjust the text
104 +    * position aswell.)
105 +    */
106 +   requisition->height += HILDON_HEIGHT_INCREMENT;
107 +
108    accel_width = 0;
109    gtk_container_foreach (GTK_CONTAINER (menu_item),
110                          gtk_menu_item_accel_width_foreach,
111 @@ -596,7 +637,8 @@
112         {
113           if (direction == GTK_TEXT_DIR_RTL)
114             child_allocation.x += child_requisition.height;
115 -         child_allocation.width -= child_requisition.height;
116 +          /* HILDON Modification. */
117 +         child_allocation.width -= child_requisition.height + HILDON_ARROW_SPACE;
118         }
119        
120        if (child_allocation.width < 1)
121 @@ -688,6 +730,7 @@
122    GtkShadowType shadow_type, selected_shadow_type;
123    gint width, height;
124    gint x, y;
125 +
126    gint border_width = GTK_CONTAINER (widget)->border_width;
127  
128    if (GTK_WIDGET_DRAWABLE (widget))
129 @@ -704,10 +747,56 @@
130        if ((state_type == GTK_STATE_PRELIGHT) &&
131           (GTK_BIN (menu_item)->child))
132         {
133 +         gint focus_x = x;
134 +         gint focus_width = width;
135           gtk_widget_style_get (widget,
136                                 "selected_shadow_type", &selected_shadow_type,
137                                 NULL);
138 -         gtk_paint_box (widget->style,
139 +
140 +          if (menu_item->submenu && menu_item->show_submenu_indicator)
141 +           {
142 +             GtkRequisition child_requisition;
143 +             gint arrow_size;
144 +             /* gint arrow_extent; */
145 +             gtk_widget_get_child_requisition (GTK_BIN (menu_item)->child,
146 +                                               &child_requisition);
147 +      
148 +             arrow_size = child_requisition.height - 2 * widget->style->ythickness;
149 +             if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) {
150 +               focus_width = x + width - arrow_size - 2 - HILDON_ARROW_SPACE;
151 +             }
152 +             else {
153 +               focus_x = x + arrow_size + 2 + HILDON_ARROW_SPACE;
154 +             }
155 +           }
156 +         
157 +          /*
158 +          * Hildon modification:
159 +          * This draws different focus depending on if it's the toplevel
160 +          * focused menu item. All items that have submenus that in turn
161 +          * have an item selected will be drawn with SELECTED - state focus.
162 +          * If this isn't the case, PRELIGHT - state focus is used. */
163 +         if (menu_item->submenu)
164 +           {
165 +             GtkMenuItem *msi;
166 +             msi = GTK_MENU_ITEM(GTK_MENU_SHELL(&((GTK_MENU(menu_item->submenu))->menu_shell))->active_menu_item);
167 +             if ((msi == NULL) || (GTK_WIDGET (msi)->state == 0))
168 +                gtk_paint_box (widget->style,
169 +                        widget->window,
170 +                        GTK_STATE_PRELIGHT,
171 +                        selected_shadow_type,
172 +                        area, widget, "menuitem",
173 +                        focus_x, y, focus_width, height);
174 +             else
175 +                gtk_paint_box (widget->style,
176 +                        widget->window,
177 +                        GTK_STATE_SELECTED,
178 +                        selected_shadow_type,
179 +                        area, widget, "menuitem",
180 +                        focus_x, y, focus_width, height);
181 +           }
182 +         else
183 +            gtk_paint_box (widget->style,
184                          widget->window,
185                          GTK_STATE_PRELIGHT,
186                          selected_shadow_type,
187 @@ -747,8 +836,12 @@
188           arrow_extent = arrow_size * 0.8;
189           
190           shadow_type = GTK_SHADOW_OUT;
191 -         if (state_type == GTK_STATE_PRELIGHT)
192 -           shadow_type = GTK_SHADOW_IN;
193 +         /*Hildon: only show the pressed arrow if the submenu is visible*/
194 +         if (state_type == GTK_STATE_PRELIGHT  
195 +           && GTK_WIDGET_VISIBLE( menu_item->submenu))
196 +           {
197 +             shadow_type = GTK_SHADOW_IN;
198 +           }
199  
200           if (direction == GTK_TEXT_DIR_LTR)
201             {
202 @@ -763,6 +856,9 @@
203  
204           arrow_y = y + (height - arrow_extent) / 2;
205  
206 +/* HILDON modification to correct focus drawing with submenu arrow */
207 +          arrow_x = arrow_x - 4;
208 +         
209           gtk_paint_arrow (widget->style, widget->window,
210                            state_type, shadow_type, 
211                            area, widget, "menuitem", 
212 @@ -772,18 +868,20 @@
213         }
214        else if (!GTK_BIN (menu_item)->child)
215         {
216 -         guint horizontal_padding;
217 +         guint horizontal_padding, separator_height;
218  
219           gtk_widget_style_get (widget,
220                                 "horizontal_padding", &horizontal_padding,
221 +                               "separator_height", &separator_height,
222                                 NULL);
223           
224 -         gtk_paint_hline (widget->style, widget->window, GTK_STATE_NORMAL,
225 -                          area, widget, "menuitem",
226 -                          widget->allocation.x + horizontal_padding + widget->style->xthickness,
227 -                          widget->allocation.x + widget->allocation.width - horizontal_padding - widget->style->xthickness - 1,
228 -                          widget->allocation.y + (widget->allocation.height -
229 -                                                  widget->style->ythickness) / 2);
230 +         /* themable menuitem for menu separators */
231 +         gtk_paint_box (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
232 +                        area, widget, "separator",
233 +                        widget->allocation.x + horizontal_padding + widget->style->xthickness,
234 +                        widget->allocation.y + (widget->allocation.height - widget->style->ythickness) / 2,
235 +                        widget->allocation.x + widget->allocation.width - horizontal_padding - widget->style->xthickness - 1,
236 +                        separator_height);
237         }
238      }
239  }
240 @@ -839,6 +937,7 @@
241        (!GTK_WIDGET_MAPPED (menu_item->submenu) ||
242         GTK_MENU (menu_item->submenu)->tearoff_active))
243      {
244 +      GdkEvent *event = gtk_get_current_event ();
245        gint popup_delay;
246  
247        if (menu_item->timer)
248 @@ -851,26 +950,40 @@
249         popup_delay = get_popup_delay (menu_item);
250        
251        if (popup_delay > 0)
252 -       {
253 -         GdkEvent *event = gtk_get_current_event ();
254 -         
255 -         menu_item->timer = g_timeout_add (popup_delay,
256 -                                           gtk_menu_item_select_timeout,
257 -                                           menu_item);
258 -         if (event &&
259 -             event->type != GDK_BUTTON_PRESS &&
260 -             event->type != GDK_ENTER_NOTIFY)
261 -           menu_item->timer_from_keypress = TRUE;
262 -         else
263 -           menu_item->timer_from_keypress = FALSE;
264 -
265 -         if (event)
266 -           gdk_event_free (event);
267 -       }
268 +        {
269 +          /* OK, Here comes the contender for the 2003 Ugly Award
270 +           * The popup delay is set small enough to be unnoticable, but high enough to not
271 +           * notice the flickering which occurs when we close all the deepest menu's Gtk+ helpfully
272 +           * expands but are not needed
273 +           * This does not fix the mouse navigation yet (bug 18) but should take care of 442
274 +           * NOTE: test the delay factor on different CPU speeds
275 +           */
276 +          popup_delay = 3;
277 +          /* Hildon: Disabling the automatic opening of submenus. */
278 +
279 +          if (event &&
280 +              event->type != GDK_BUTTON_PRESS &&
281 +              event->type != GDK_ENTER_NOTIFY &&
282 +              event->type != GDK_MOTION_NOTIFY) /*hildon: for some reason, the event is sometimes this and not enter!*/
283 +            menu_item->timer_from_keypress = TRUE;
284 +          else if (event)
285 +            {
286 +              /* mouse/pen events */
287 +              /* here is a problem -- when a menu item with sub menus gets a mouse event,
288 +                 another event is generated for the submenu (and further its submenu etc.)
289 +                 This leads to a behaviour which does not comply to the hildon spec. */
290 +              menu_item->timer_from_keypress = FALSE;
291 +            }
292 +          else /* does this really happen? */
293 +            menu_item->timer_from_keypress = FALSE;
294 +        }
295        else
296 -       _gtk_menu_item_popup_submenu (GTK_WIDGET (menu_item));
297 +        _gtk_menu_item_popup_submenu (menu_item);
298 +
299 +      if (event)
300 +        gdk_event_free (event);
301      }
302 -  
303 +
304    gtk_widget_set_state (GTK_WIDGET (menu_item), GTK_STATE_PRELIGHT);
305    gtk_widget_queue_draw (GTK_WIDGET (menu_item));
306  }
307 @@ -878,25 +991,16 @@
308  static void
309  gtk_real_menu_item_deselect (GtkItem *item)
310  {
311 -  GtkMenuItem *menu_item;
312 +  GtkWidget *menu_item;
313  
314    g_return_if_fail (GTK_IS_MENU_ITEM (item));
315  
316 -  menu_item = GTK_MENU_ITEM (item);
317 +  menu_item = GTK_WIDGET (item);
318  
319 -  if (menu_item->submenu)
320 -    {
321 -      if (menu_item->timer)
322 -       {
323 -         g_source_remove (menu_item->timer);
324 -         menu_item->timer = 0;
325 -       }
326 -      else
327 -       gtk_menu_popdown (GTK_MENU (menu_item->submenu));
328 -    }
329 +  _gtk_menu_item_popdown_submenu (menu_item);
330  
331 -  gtk_widget_set_state (GTK_WIDGET (menu_item), GTK_STATE_NORMAL);
332 -  gtk_widget_queue_draw (GTK_WIDGET (menu_item));
333 +  gtk_widget_set_state (menu_item, GTK_STATE_NORMAL);
334 +  gtk_widget_queue_draw (menu_item);
335  }
336  
337  static gboolean
338 @@ -941,10 +1045,7 @@
339           _gtk_menu_shell_activate (menu_shell);
340  
341           gtk_menu_shell_select_item (GTK_MENU_SHELL (widget->parent), widget); 
342 -         _gtk_menu_item_popup_submenu (widget); 
343 -
344 -         gtk_menu_shell_select_first (GTK_MENU_SHELL (menu_item->submenu), TRUE);
345 -         submenu = GTK_MENU_SHELL (menu_item->submenu);
346 +          /* Hildon mod: automatic submenu opening has been removed */
347         }
348      }
349  }
350 @@ -983,7 +1084,7 @@
351      {
352        _gtk_menu_item_popup_submenu (GTK_WIDGET (menu_item));
353        if (menu_item->timer_from_keypress && menu_item->submenu)
354 -       GTK_MENU_SHELL (menu_item->submenu)->ignore_enter = TRUE;
355 +        GTK_MENU_SHELL (menu_item->submenu)->ignore_enter = TRUE;
356      }
357  
358    GDK_THREADS_LEAVE ();
359 @@ -1002,7 +1103,16 @@
360      g_source_remove (menu_item->timer);
361    menu_item->timer = 0;
362  
363 +  /* HILDON MOD. This is required as changed submenu arrow isn't drawn automatically
364 +   * and drawing it must be requested. */
365 +  gtk_widget_queue_draw (widget);
366 +
367    if (GTK_WIDGET_IS_SENSITIVE (menu_item->submenu))
368 +  {
369 +    gboolean take_focus;
370 +    take_focus = gtk_menu_shell_get_take_focus (GTK_MENU_SHELL (widget->parent));
371 +    gtk_menu_shell_set_take_focus (GTK_MENU_SHELL (menu_item->submenu),take_focus);
372 +    
373      gtk_menu_popup (GTK_MENU (menu_item->submenu),
374                     widget->parent,
375                     widget,
376 @@ -1010,6 +1120,28 @@
377                     menu_item,
378                     GTK_MENU_SHELL (widget->parent)->button,
379                     0);
380 +  }
381 +}
382 +
383 +void
384 +_gtk_menu_item_popdown_submenu (GtkWidget *widget)
385 +{
386 +  GtkMenuItem *menu_item;
387 +
388 +  menu_item = GTK_MENU_ITEM (widget);
389 +
390 +  if (menu_item->submenu)
391 +    {
392 +      if (menu_item->timer)
393 +        {
394 +          g_source_remove (menu_item->timer);
395 +          menu_item->timer = 0;
396 +        }
397 +      else
398 +        gtk_menu_popdown (GTK_MENU (menu_item->submenu));
399 +    }
400 +
401 +  gtk_widget_queue_draw (widget);
402  }
403  
404  static void
405 @@ -1092,14 +1224,17 @@
406           tx += widget->allocation.width - twidth;
407         }
408  
409 +/* HILDON modifications
410 + * Here we make the submenu of an menubar appear under the menubar.
411 + * The only exception is when the resulting menu would be under 100 pixels
412 + * high. In that case, the menu is made 100 pixels high.
413 + */
414        if ((ty + widget->allocation.height + theight) <= monitor.y + monitor.height)
415         ty += widget->allocation.height;
416 -      else if ((ty - theight) >= monitor.y)
417 -       ty -= theight;
418 -      else if (monitor.y + monitor.height - (ty + widget->allocation.height) > ty)
419 +      else if ((ty + widget->allocation.height) < monitor.y + monitor.height - 120)
420         ty += widget->allocation.height;
421        else
422 -       ty -= theight;
423 +       ty = monitor.y + monitor.height - 120;
424        break;
425  
426      case GTK_LEFT_RIGHT:
427 @@ -1404,3 +1539,30 @@
428  
429    return TRUE;
430  }
431 +
432 +/* Hildon modification :
433 + * This function exists only for opening submenus on
434 + * activation. */
435 +static void
436 +_gtk_menu_item_activate_submenus (GtkMenuItem *item)
437 +{
438 +  GdkEvent *event;
439 +
440 +  g_return_if_fail (GTK_IS_MENU_ITEM (item));
441 +  
442 +  if (!GTK_IS_MENU (item->submenu) ||
443 +      GTK_WIDGET_VISIBLE (item->submenu)) 
444 +    return;
445 +
446 +  event = gtk_get_current_event ();
447 +  _gtk_menu_item_popup_submenu (item);
448 +      
449 +  /* We don't want to select first item if the submenu
450 +   * is opened with mouse release because the selection
451 +   * would move straigh back under the cursor. */
452 +  if ((event == NULL) || (event->type != GDK_BUTTON_RELEASE))
453 +    gtk_menu_shell_select_first (GTK_MENU_SHELL (item->submenu), TRUE);
454 +      
455 +  if (event)
456 +    gdk_event_free (event);
457 +}