The patch attached to adds keyboard navigation to the menu using the
first character of the menu label. It automatically executes anything
with a single entry in the menu and just activates those that have
multiple entries. If you don't like it's behaviour I can change it.

The patch is based on successful application of the patch from my
previous mail, as it's just too messy (it is a little bit already),
without accurate menu list item tracking.

One item that I'm not happy with, and I can't seem to see the issue is
that when hitting an item with a submenu and the submenu is activated,
the first item is not highlighted. I don't quite understand this as it's
using the same function as pressing the right arrow on the keyboard. It
can be a little bit confusing without the marker.

One REALLY useful feature of having menus like this is, say the Favorite
Applications menu is shown by Win+C. If Firefox is in the menu then
Win+C, F, will launch firefox.

Again, let me know what you think and if it needs mods, I'm happy to
make them.

metrics
--- e_menu.c.old        2006-09-27 12:48:58.000000000 +1000
+++ e_menu.c    2006-09-27 15:12:24.000000000 +1000
@@ -53,6 +53,7 @@
 static void _e_menu_item_activate_first           (void);
 static void _e_menu_item_activate_last            (void);
 static void _e_menu_item_activate_nth             (int n);
+static void _e_menu_item_activate_char            (char * key_compose);
 static void _e_menu_activate_next                 (void);
 static void _e_menu_activate_previous             (void);
 static void _e_menu_activate_first                (void);
@@ -2070,6 +2071,104 @@
 }
 
 static void
+_e_menu_item_activate_char(char * key_compose)
+{
+   E_Menu *m;
+   E_Menu_Item *mi;
+   Evas_List *ll, *ll_orig;
+   int match_count = 0;
+
+   /* Ignore modifiers and such. */
+   if (!key_compose) return;
+
+   /* Check we've got a menu and it's active. */
+   m = _e_menu_active_get();
+   if (!m) 
+     {
+       if (!_e_active_menus) return;
+       m = _e_active_menus->data;
+       if (!m) return;
+     }
+
+   /* Count the number of items that match */
+   ll = m->items;
+   while (ll) 
+     {
+       mi = ll->data;
+       if (!mi->separator && !strncasecmp(key_compose, mi->label, 
strlen(key_compose)))
+         match_count++;
+       ll = ll->next;
+     }
+
+   if (!match_count) return;
+
+   ll = _e_menu_list_item_active_get();
+   /* If we don't have an active item, start from the top of the list. */
+   if (!ll)
+     {
+       ll = m->items;
+       mi = ll->data;
+       /* Only check the current item if it wasn't active before. */
+       if (!mi->separator && mi->label && !strncasecmp(key_compose, mi->label, 
strlen(key_compose))) 
+         {
+            e_menu_item_active_set(mi, 1);
+            _e_menu_item_ensure_onscreen(mi);
+            if (match_count <= 1)
+              {
+                 if (mi->submenu) 
+                   _e_menu_activate_next();
+                 else
+                   {
+                      _e_menu_active_call();
+                      _e_menu_deactivate_all();
+                   }
+              }
+            return;
+         }
+     }
+
+   mi = ll->data;
+   if (!(ll->next)) 
+     ll = mi->menu->items;
+   else
+     ll = ll->next;
+   mi = ll->data;
+
+   /* While we don't have a label OR we don't match */
+   while ((!mi->label || strncasecmp(key_compose, mi->label, 
strlen(key_compose))))
+     {
+       if (!(ll->next)) 
+         ll = mi->menu->items;
+       else
+         ll = ll->next;
+       mi = ll->data;
+
+       while (mi->separator)
+         { 
+            if (!(ll->next)) 
+              ll = mi->menu->items;
+            else
+              ll = ll->next;
+            mi = ll->data;
+         }
+     }
+
+   e_menu_item_active_set(mi, 1);
+   _e_menu_item_ensure_onscreen(mi);
+   if (match_count <= 1)
+     {
+       if (mi->submenu) 
+         _e_menu_activate_next();
+       else
+         {
+            _e_menu_active_call();
+            _e_menu_deactivate_all();
+         }
+     }
+   return;
+}
+
+static void
 _e_menu_activate_next(void)
 {
    E_Menu_Item *mi;
@@ -2531,6 +2630,8 @@
      _e_menu_item_activate_nth(8);
    else if ((!strcmp(ev->keysymbol, "0")) || (!strcmp(ev->keysymbol, "KP_0")))
      _e_menu_item_activate_last();
+   else if (ev->key_compose)
+     _e_menu_item_activate_char(ev->key_compose);
    return 1;
 }
 
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to