FrapMenu menu/item ordering

Jannis Pohlmann jannis at xfce.org
Wed Feb 21 20:19:55 CET 2007


Hey,

On Tue, 20 Feb 2007 17:49:44 -0800, Brian J. Tarricone wrote:

> Hey Jannis,
>
> I'm playing with FrapMenu a bit, trying to see what it takes to
> integrate it into xfdesktop and make it generate a menu that sorta
> somewhat resembles the default menu we have now.  It actually wasn't
> that hard to set up (cool!), but I'm running into a limitation: when a
> menu contains both items and menus, I can't seem to figure out how to
> define an ordering between the two.  For example, say I want to create
> a menu that looks like this:
>
> Foo Application (menu item)
> Bar Application (menu item)
> Random Stuff (submenu)
> More Random Stuff (submenu)
> Baz Application (menu item)
>
> How would I do this?  frap_menu_get_menus() and frap_menu_get_items()
> returns the list of menus and items, respectively, but there doesn't
> seem to be a way to create a mixed ordering.  So I either end up with
> all the menus, then all the items, or the reverse, depending on the
> order I add them in my code.

True. The first thing coming to my mind would be something like this:

  gint
  compare_children (gconstpointer a,
                    gconstpointer b)
  {
    FrapMenuDirectory *dir1;
    FrapMenuDirectory *dir2;
    FrapMenuItem      *item1;
    FrapMenuItem      *item2;

    if (FRAP_IS_MENU (a))
      {
        dir1 = frap_menu_get_directory (FRAP_MENU (a));
        if (FRAP_IS_MENU (b))
          {
            dir2 = frap_menu_get_directory (FRAP_MENU (b));
            return g_utf8_collate (frap_menu_directory_get_name (a),
                                   frap_menu_directory_get_name (b));
          }
        else
          {
            item2 = FRAP_MENU_ITEM (b);
            return g_utf8_collate (frap_menu_directory_get_name (dir1),
                                   frap_menu_item_get_name (item2));
          }
    else
      {
        item1 = FRAP_MENU_ITEM (a);
        if (FRAP_IS_MENU_ITEM (b))
          {
            item2 = FRAP_MENU_ITEM (b);
            return g_utf8_collate (frap_menu_item_get_name (item1),
                                   frap_menu_item_get_name (item2));
          }
        else
          {
            dir2 = frap_menu_get_directory (FRAP_MENU (b));
            return g_utf8_collate (frap_menu_item_get_name (item1),
                                   frap_menu_directory_get_name (dir2));
          }
      }
  }

  GList *children;
  children = frap_menu_get_menus (menu);
  children = g_list_concat (children, frap_menu_get_items (menu));
  g_list_sort (children, (GCompareFunc) compare_children);

I know this is a little messy, but it should work. As I don't treat
menus and items as XML nodes like gnome-menus does, there's no easy way
to mix them (unless I implement a special node interface).

> Also, how are the items from frap_menu_get_items() returned?  It looks
> like they are just pulled in hash table "order", which doesn't seem to
> guarantee any kind of ordering at all.

They're unsorted as the order is unimportant for internal use.
Comparing them by names is really easy with the help of a GCompareFunc
as you can see above.

> I just committed what I've been doing to xfdesktop trunk, so you can
> look at the menu file I'm using here:
> http://svn.xfce.org/svn/xfce/xfdesktop/trunk/modules/menu/menu-data/xfce-applications.menu.in
> (The stuff I'm including with <Filename> blocks is installed to
> @EXTRA_MENU_DATA_DIR at .)
>
> I also have a more menu-spec-related question, but maybe you'd know
> since you've worked with the spec quite a bit.  I want to create a
> catch-all "Other" submenu to put everything that wasn't sorted into
> one of the other submenus.  I tried using <OnlyUnallocated/> but that
> didn't seem to work; then I tried <All/> in conjunction with
> <OnlyUnallocated/>, and also both of those inside and <And></And>
> pair, but that didn't work either.  Any ideas?

<OnlyUnallocated/> only works directly below <Menu> elements, not
inside <Include>/<Exclude> rules. From my understanding something like
this should do the job (I actually have something similar in
my /etc/xdg/menus/applications.menu and it works):

  ...
  <Menu>
    <Name>Other</Name>
    <Directory>Other.directory</Directory>
    <OnlyUnallocated/>
    <Include>
      <All/>
    </Include>
  </Menu>
  ...

If it does not I probably broke something lately. Just let me know in
that case.

> Oh, and on a side note, FrapMenu tends to segfault a lot on things
> like bad menu files and whatnot.  I'll file bugs for you later, or
> something.

Yeah, that's likely to happen. I haven't added any checks to the XML
parsing process yet.

HTH,
  Jannis
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://mail.xfce.org/pipermail/xfce4-dev/attachments/20070221/60cd4ceb/attachment.pgp>


More information about the Xfce4-dev mailing list