]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/gtk+/gtk+-2.6.4-1.osso7/gtkmenushell.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 / gtkmenushell.c.diff
1 --- gtk+-2.6.4/gtk/gtkmenushell.c       2005-02-09 18:46:54.000000000 +0200
2 +++ gtk+-2.6.4/gtk/gtkmenushell.c       2005-04-06 16:19:36.999913520 +0300
3 @@ -39,6 +39,8 @@
4  #include "gtkmnemonichash.h"
5  #include "gtktearoffmenuitem.h"
6  #include "gtkwindow.h"
7 +#include "gtkprivate.h"
8 +#include "gtkintl.h"
9  
10  #define MENU_SHELL_TIMEOUT   500
11  
12 @@ -52,6 +54,11 @@
13    LAST_SIGNAL
14  };
15  
16 +enum {
17 +  PROP_0,
18 +  PROP_TAKE_FOCUS
19 +};
20 +
21  typedef void (*GtkMenuShellSignal1) (GtkObject           *object,
22                                      GtkMenuDirectionType arg1,
23                                      gpointer             data);
24 @@ -122,10 +129,20 @@
25  {
26    GtkMnemonicHash *mnemonic_hash;
27    GtkKeyHash *key_hash;
28 +  gboolean activated_submenu;
29 +  gboolean take_focus;
30  };
31  
32  static void gtk_menu_shell_class_init        (GtkMenuShellClass *klass);
33  static void gtk_menu_shell_init              (GtkMenuShell      *menu_shell);
34 +static void gtk_menu_shell_set_property      (GObject           *object,
35 +                                               guint              prop_id,
36 +                                               const GValue      *value,
37 +                                               GParamSpec        *pspec);
38 +static void gtk_menu_shell_get_property      (GObject           *object,
39 +                                               guint              prop_id,
40 +                                               GValue            *value,
41 +                                               GParamSpec        *pspec);
42  static void gtk_menu_shell_realize           (GtkWidget         *widget);
43  static void gtk_menu_shell_finalize          (GObject           *object);
44  static gint gtk_menu_shell_button_press      (GtkWidget         *widget,
45 @@ -176,7 +193,6 @@
46  static GtkContainerClass *parent_class = NULL;
47  static guint menu_shell_signals[LAST_SIGNAL] = { 0 };
48  
49 -
50  GType
51  gtk_menu_shell_get_type (void)
52  {
53 @@ -220,6 +236,8 @@
54    container_class = (GtkContainerClass*) klass;
55  
56    parent_class = g_type_class_peek_parent (klass);
57 +  object_class->set_property = gtk_menu_shell_set_property;
58 +  object_class->get_property = gtk_menu_shell_get_property;
59  
60    object_class->finalize = gtk_menu_shell_finalize;
61  
62 @@ -299,9 +317,15 @@
63  
64  
65    binding_set = gtk_binding_set_by_class (klass);
66 +/* Hildon : The following binding is commented out
67 + * because we want the Escape key to only exit the
68 + * currently opened submenu. Therefore, the handling
69 + * of esc-key will be moved to gtkmenuitem.c */
70 +/*
71    gtk_binding_entry_add_signal (binding_set,
72                                 GDK_Escape, 0,
73                                 "cancel", 0);
74 +*/
75    gtk_binding_entry_add_signal (binding_set,
76                                 GDK_Return, 0,
77                                 "activate_current", 1,
78 @@ -330,7 +354,23 @@
79                                 GDK_F10, GDK_SHIFT_MASK,
80                                 "cycle_focus", 1,
81                                  GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_BACKWARD);
82 -
83 +  /**
84 +   * GtkMenuShell:take-focus:
85 +   *
86 +   * A boolean that determines whether the menu and its submenus grab the
87 +   * keyboard focus. See gtk_menu_shell_set_take_focus() and
88 +   * gtk_menu_shell_get_take_focus().
89 +   *
90 +   * Since: 2.8
91 +   **/
92 +  g_object_class_install_property (object_class,
93 +                                  PROP_TAKE_FOCUS,
94 +                                  g_param_spec_boolean ("take-focus",
95 +                                                        P_("Take Focus"),
96 +                                                        P_("A boolean that determines whether the menu grabs the keyboard focus"),
97 +                                                        TRUE,
98 +                                                        G_PARAM_READWRITE));
99 +  
100    g_type_class_add_private (object_class, sizeof (GtkMenuShellPrivate));
101  }
102  
103 @@ -356,6 +396,46 @@
104  
105    priv->mnemonic_hash = NULL;
106    priv->key_hash = NULL;
107 +  priv->take_focus = TRUE;
108 +  priv->activated_submenu = FALSE;
109 +}
110 +
111 +static void
112 +gtk_menu_shell_set_property (GObject      *object,
113 +                             guint         prop_id,
114 +                             const GValue *value,
115 +                             GParamSpec   *pspec)
116 +{
117 +  GtkMenuShell *menu_shell = GTK_MENU_SHELL (object);
118 +
119 +  switch (prop_id)
120 +    {
121 +    case PROP_TAKE_FOCUS:
122 +      gtk_menu_shell_set_take_focus (menu_shell, g_value_get_boolean (value));
123 +      break;
124 +    default:
125 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
126 +      break;
127 +    }
128 +}
129 +
130 +static void
131 +gtk_menu_shell_get_property (GObject     *object,
132 +                             guint        prop_id,
133 +                             GValue      *value,
134 +                             GParamSpec  *pspec)
135 +{
136 +  GtkMenuShell *menu_shell = GTK_MENU_SHELL (object);
137 +
138 +  switch (prop_id)
139 +    {
140 +    case PROP_TAKE_FOCUS:
141 +      g_value_set_boolean (value, gtk_menu_shell_get_take_focus (menu_shell));
142 +      break;
143 +    default:
144 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
145 +      break;
146 +    }
147  }
148  
149  static void
150 @@ -470,6 +550,7 @@
151  gtk_menu_shell_button_press (GtkWidget      *widget,
152                              GdkEventButton *event)
153  {
154 +  GtkMenuShellPrivate *priv;
155    GtkMenuShell *menu_shell;
156    GtkWidget *menu_item;
157  
158 @@ -479,7 +560,22 @@
159    if (event->type != GDK_BUTTON_PRESS)
160      return FALSE;
161  
162 +  priv = GTK_MENU_SHELL_GET_PRIVATE (widget);
163 +
164    menu_shell = GTK_MENU_SHELL (widget);
165 +  menu_item = gtk_menu_shell_get_item (menu_shell, (GdkEvent*) event);
166 +
167 +  if (menu_shell->active && menu_item &&
168 +      (menu_shell->active_menu_item == menu_item) &&
169 +      _gtk_menu_item_is_selectable (menu_item) &&
170 +      GTK_MENU_ITEM (menu_item)->submenu != NULL &&
171 +      !GTK_WIDGET_VISIBLE (GTK_MENU_ITEM (menu_item)->submenu))
172 +    {
173 +      /* Hildon : We want to be able to activate submenu items. */
174 +      gtk_menu_shell_activate_item (menu_shell, menu_item, FALSE);
175 +
176 +      priv->activated_submenu = TRUE;
177 +    }
178  
179    if (menu_shell->parent_menu_shell)
180      {
181 @@ -491,30 +587,29 @@
182        
183        menu_shell->button = event->button;
184  
185 -      menu_item = gtk_menu_shell_get_item (menu_shell, (GdkEvent *)event);
186 -
187        if (menu_item && _gtk_menu_item_is_selectable (menu_item))
188 -       {
189 -         if ((menu_item->parent == widget) &&
190 -             (menu_item != menu_shell->active_menu_item))
191 -           {
192 -             if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM)
193 -               {
194 -                 menu_shell->activate_time = event->time;
195 -               }
196 +             {
197 +
198 +               if ((menu_item->parent == widget) &&
199 +                   (menu_item != menu_shell->active_menu_item))
200 +                 {
201 +                    if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM)
202 +                            {
203 +                              menu_shell->activate_time = event->time;
204 +                            }
205        
206 -             gtk_menu_shell_select_item (menu_shell, menu_item);
207 -           }
208 -       }
209 +                    gtk_menu_shell_select_item (menu_shell, menu_item);
210 +                  }
211 +             }
212      }
213    else
214      {
215        widget = gtk_get_event_widget ((GdkEvent*) event);
216        if (widget == GTK_WIDGET (menu_shell))
217 -       {
218 -         gtk_menu_shell_deactivate (menu_shell);
219 -         g_signal_emit (menu_shell, menu_shell_signals[SELECTION_DONE], 0);
220 -       }
221 +             {
222 +               gtk_menu_shell_deactivate (menu_shell);
223 +               g_signal_emit (menu_shell, menu_shell_signals[SELECTION_DONE], 0);
224 +             }
225      }
226  
227    return TRUE;
228 @@ -524,13 +619,20 @@
229  gtk_menu_shell_button_release (GtkWidget      *widget,
230                                GdkEventButton *event)
231  {
232 +  GtkMenuShellPrivate *priv;
233    GtkMenuShell *menu_shell;
234    GtkWidget *menu_item;
235    gint deactivate;
236 +  gboolean activated_submenu;
237  
238    g_return_val_if_fail (GTK_IS_MENU_SHELL (widget), FALSE);
239    g_return_val_if_fail (event != NULL, FALSE);
240  
241 +  priv = GTK_MENU_SHELL_GET_PRIVATE (widget);
242 +
243 +  activated_submenu = priv->activated_submenu;
244 +  priv->activated_submenu = FALSE;
245 +
246    menu_shell = GTK_MENU_SHELL (widget);
247    if (menu_shell->active)
248      {
249 @@ -556,11 +658,11 @@
250                   gtk_menu_shell_activate_item (menu_shell, menu_item, TRUE);
251                   return TRUE;
252                 }
253 -             else if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM)
254 -               {
255 -                 gtk_menu_item_select (GTK_MENU_ITEM (menu_item));
256 -                 return TRUE;
257 -               }
258 +              else if (!activated_submenu)
259 +                {
260 +                  /* popdown the submenu if we didn't pop it up in this click */
261 +                  _gtk_menu_item_popdown_submenu (menu_item);
262 +                }
263             }
264           else if (menu_item &&
265                    !_gtk_menu_item_is_selectable (menu_item) &&
266 @@ -630,12 +732,14 @@
267  gtk_menu_shell_enter_notify (GtkWidget        *widget,
268                              GdkEventCrossing *event)
269  {
270 +  GtkMenuShellPrivate *priv;
271    GtkMenuShell *menu_shell;
272    GtkWidget *menu_item;
273  
274    g_return_val_if_fail (GTK_IS_MENU_SHELL (widget), FALSE);
275    g_return_val_if_fail (event != NULL, FALSE);
276  
277 +  priv = GTK_MENU_SHELL_GET_PRIVATE (widget);
278    menu_shell = GTK_MENU_SHELL (widget);
279  
280    if (menu_shell->active)
281 @@ -658,6 +762,17 @@
282               (GTK_WIDGET_STATE (menu_item) != GTK_STATE_PRELIGHT))
283             {
284               gtk_menu_shell_select_item (menu_shell, menu_item);
285 +              
286 +              /* If the pen is down, and there is a submenu that is not
287 +               * yet visible, activate it */
288 +              if ((event->state & GDK_BUTTON1_MASK) &&
289 +                  GTK_MENU_ITEM (menu_item)->submenu != NULL &&
290 +                  !GTK_WIDGET_VISIBLE (GTK_MENU_ITEM (menu_item)->submenu))
291 +                {
292 +                  gtk_menu_shell_activate_item (menu_shell, menu_item, FALSE);
293 +
294 +                  priv->activated_submenu = TRUE;
295 +                }
296             }
297         }
298        else if (menu_shell->parent_menu_shell)
299 @@ -887,8 +1002,14 @@
300    /* This allows the bizarre radio buttons-with-submenus-display-history
301     * behavior
302     */
303 +  /* Hildon modification. We probably won't have those
304 +   * bizarre radio buttons-with-submenus so we don't
305 +   * need this. Also, this functionality interferes with
306 +   * other functionality. */
307 +/*
308    if (GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu)
309      gtk_widget_activate (menu_shell->active_menu_item);
310 +*/
311  }
312  
313  void
314 @@ -919,7 +1040,9 @@
315  
316    g_object_ref (menu_shell);
317  
318 -  if (deactivate)
319 +  /* We don't want to deactivate if we're activating
320 +   * a submenu item. */
321 +  if ((deactivate) && (GTK_MENU_ITEM (menu_item)->submenu == NULL))
322      {
323        GtkMenuShell *parent_menu_shell = menu_shell;
324  
325 @@ -965,29 +1088,30 @@
326        
327        if (distance > 0)
328         {
329 +         /*Hildon: selection no longer wraps around at the
330 +         *bottom of the menu*/
331 +
332           node = node->next;
333 -         while (node != start_node && 
334 -                (!node || !_gtk_menu_item_is_selectable (node->data)))
335 +         while (node && node != start_node && 
336 +                !_gtk_menu_item_is_selectable (node->data))
337             {
338 -             if (!node)
339 -               node = menu_shell->children;
340 -             else
341                 node = node->next;
342             }
343         }
344        else
345         {
346 +         /*Hildon: selection no longer wraps around at the top
347 +         *of the menu*/
348 +
349           node = node->prev;
350 -         while (node != start_node &&
351 -                (!node || !_gtk_menu_item_is_selectable (node->data)))
352 +         while (node && node != start_node &&
353 +                !_gtk_menu_item_is_selectable (node->data))
354             {
355 -             if (!node)
356 -               node = g_list_last (menu_shell->children);
357 -             else
358                 node = node->prev;
359             }
360         }
361        
362 +      /*note: gtk_menu_shell_select_item won't select non-selectable items*/
363        if (node)
364         gtk_menu_shell_select_item (menu_shell, node->data);
365      }
366 @@ -1119,6 +1243,16 @@
367    switch (direction)
368      {
369      case GTK_MENU_DIR_PARENT:
370 +
371 +      if(!parent_menu_shell || GTK_IS_MENU_BAR(parent_menu_shell))
372 +        break;
373 +
374 +      /* hildon-modification - menu should be closed when returning from submenu.
375 +       * WARNING: This function is from GtkMenu, which normally
376 +       * shouldn't be called from GtkMenuShell, but currently
377 +       * there are no better alternatives. */
378 +      gtk_menu_popdown (GTK_MENU (menu_shell));
379 +
380        if (parent_menu_shell)
381         {
382           if (GTK_MENU_SHELL_GET_CLASS (parent_menu_shell)->submenu_placement == 
383 @@ -1151,10 +1285,14 @@
384           _gtk_menu_item_is_selectable (menu_shell->active_menu_item) &&
385           GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu)
386         {
387 +          /* Hildon-modification -- submenu is not opened automatically but needs to be explicitly opened*/
388 +         g_signal_emit (G_OBJECT (menu_shell), menu_shell_signals[ACTIVATE_CURRENT], 0, (gint) FALSE);
389 +
390           if (gtk_menu_shell_select_submenu_first (menu_shell))
391             break;
392         }
393  
394 +#if 0
395        /* Try to find a menu running the opposite direction */
396        while (parent_menu_shell && 
397              (GTK_MENU_SHELL_GET_CLASS (parent_menu_shell)->submenu_placement ==
398 @@ -1173,6 +1311,7 @@
399           gtk_menu_shell_move_selected (parent_menu_shell, 1);
400           gtk_menu_shell_select_submenu_first (parent_menu_shell);
401         }
402 +#endif
403        break;
404        
405      case GTK_MENU_DIR_PREV:
406 @@ -1197,8 +1336,8 @@
407  gtk_real_menu_shell_activate_current (GtkMenuShell      *menu_shell,
408                                       gboolean           force_hide)
409  {
410 -  if (menu_shell->active_menu_item &&
411 -      _gtk_menu_item_is_selectable (menu_shell->active_menu_item))
412 +  if (menu_shell->active_menu_item)/* &&
413 +      _gtk_menu_item_is_selectable (menu_shell->active_menu_item)) */
414    {
415     
416      if (GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu == NULL)
417 @@ -1390,4 +1529,73 @@
418                              keyval, target);
419    gtk_menu_shell_reset_key_hash (menu_shell);
420  }
421 +/**
422 + * gtk_menu_shell_get_take_focus:
423 + * @menu: a #GtkMenuShell
424 + *
425 + * @returns: %TRUE if the menu_shell will take the keyboard focus on popup.
426 + *
427 + * Since: 2.8
428 + **/
429 +gboolean
430 +gtk_menu_shell_get_take_focus (GtkMenuShell *menu_shell)
431 +{
432 +  GtkMenuShellPrivate *priv;
433 +
434 +  g_return_val_if_fail (GTK_IS_MENU_SHELL (menu_shell), FALSE);
435 +
436 +  priv = GTK_MENU_SHELL_GET_PRIVATE (menu_shell);
437 +
438 +  return priv->take_focus;
439 +}
440 +
441 +/**
442 + * gtk_menu_shell_set_take_focus:
443 + * @menu: a #GtkMenuShell
444 + * @take_focus: %TRUE if the menu_shell should take the keyboard focus on popup.
445 + *
446 + * If @take_focus is %TRUE (the default) the menu will take the keyboard focus
447 + * so that it will receive all keyboard events which is needed to enable
448 + * keyboard navigation in menus.
449 + *
450 + * Setting @take_focus to %FALSE is useful only for special applications
451 + * like virtual keyboard implementations which should not take keyboard
452 + * focus.
453 + *
454 + * The @take_focus state of a menu or menu bar is automatically propagated
455 + * to submenus whenever a submenu is popped up, so you don't have to worry
456 + * about recursively setting it for your entire menu hierarchy. Only when
457 + * programmatically picking a submenu and popping it up manually, the
458 + * @take_focus property of the submenu needs to be set explicitely.
459 + *
460 + * Note that setting it to %FALSE has side-effects:
461 + *
462 + * If the focus is in some other app, it keeps the focus and keynav in
463 + * the menu doesn't work. Consequently, keynav on the menu will only
464 + * work if the focus is on some toplevel owned by the onscreen keyboard.
465 + *
466 + * To avoid confusing the user, menus with @take_focus set to %FALSE
467 + * should not display mnemonics or accelerators, since it cannot be
468 + * guaranteed that they will work.
469 + *
470 + * See also gdk_keyboard_grab()
471 + *
472 + * Since: 2.8
473 + **/
474 +void
475 +gtk_menu_shell_set_take_focus (GtkMenuShell *menu_shell,
476 +                               gboolean      take_focus)
477 +{
478 +  GtkMenuShellPrivate *priv;
479 +
480 +  g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
481 +
482 +  priv = GTK_MENU_SHELL_GET_PRIVATE (menu_shell);
483 +
484 +  if (priv->take_focus != take_focus)
485 +    {
486 +      priv->take_focus = take_focus;
487 +      g_object_notify (G_OBJECT (menu_shell), "take-focus");
488 +    }
489 +}
490