obmenu-generator

obmenu-generator is a simple, lightweight, easily configurable Perl script that generates a full Openbox XML-menu based upon the information present in *.desktop application files (related to fbmenugen and menutray).


It has full support for icons (respecting the current icon theme) and can generate either a static or a dynamic menu.

The parsing of the *.desktop files is provided by the Linux::DesktopFiles module.

In a dynamic menu, the entries are updated automatically when a new application is installed or when the current icon theme is changed by the user.

Starting with version 0.61, obmenu-generator introduced a new smart-cache system which will store all the required data from the *.destkop files in a new cache.db file, which is also updated automatically when a new application is (re)installed or when the config.pl or schema.pl are changed. With the new cache-system in place, a full menu with icons is generated in ~8ms (compared to ~60ms before).

In version 0.80, we introduced yet another layer of caching, which scales down and converts each menu icon to a PNG icon at a predefined size specified in the configuration file. This optimization makes a dynamic menu with SVG icons many times faster, as no conversions are needed to be done by Openbox when the menu is loaded.

Version 0.80 also introduced a new dependency, Gtk2, which is used for resolving the absolute paths for icons in a more reliable and predictable way.

Starting with version 0.82, obmenu-generator can provide locale support if the File::DesktopEntry module is installed.

To generate a static menu with icons, execute:
   obmenu-generator -i -s -c

To generate a dynamic menu with icons, execute:
   obmenu-generator -i -p

For more details, see: obmenu-generator -h

BONUS: Check out another nice script, which can be used with obmenu-generator, called obbrowser.

AUR Linkhttps://aur.archlinux.org/packages/obmenu-generator/

See also: https://erikdubois.be/how-to-make-an-openbox-menu-with-obmenu-generator-and-use-your-favorite-icons/

Comments

  1. Hi!
    Thanks for this great utility.
    I am using it, but I have a problem: the generated menu does not seems to respect my icon-theme...Any ideas?

    ReplyDelete
    Replies
    1. Hi,
      It should respect it... Make sure that is specified in ~/.gtkrc-2.0 as gtk-icon-theme-name="IconTheme" and your $IconTheme directory must exists either in:
      /usr/share/icons/$IconTheme
      $home_dir/.icons/$IconTheme
      $home_dir/.local/share/icons/$IconTheme

      Delete
  2. Thank you very much for this fast reply!

    All those requirements are all right.
    It seems that the menu has some problem with themes that inherits other icon-theme, i.e Faience (inherits Faenza) or Gnome-Brave (inherits gnome-colors-common).
    The menu correctly shows icons contained in Faience, but fail to show icons from Faenza. The problem is that the menu seems to replace the icons that i can't find with the first one that it find in the system: on this machine, Gnome icon theme, on another one with Awoken (the first theme in alphabetical order).

    Here a screenshot to clarify: http://ompldr.org/vY3dzag

    As you can see, some icons respect Faience icon theme, some do not.

    Thank you very very much

    ReplyDelete
    Replies
    1. Take a look at lines 427-460. As you can see, it stores icons from $personal_theme (a stored icon is not replaced by others), and as a 'backup plan', the script looks for icons in /usr/share/pixmaps/, /usr/share/icons/hicolor/ and icons from $home_dir (if directories exists). So, the conclusion is that the script cannot find needed icons in $personal_theme, so it uses icons from the 'backup plan'. (You can try to add your icon directories there)

      Delete
    2. Thank you very much...now I have the correct icons in the menu, after follow your suggestion and editing the script like this:

      File::Find::find(
      \&store_icons,
      grep({-d $_} "$home_dir/.icons/Faience",
      '/usr/share/icons/Faenza',
      '/usr/share/pixmaps/',
      '/usr/share/icons/hicolor/', "$home_dir/.local/share/icons",
      "$home_dir/.icons/")
      );

      if (-d '/usr/share/icons/gnome/' and not $icon_theme =~ /^gnome$/i) {
      File::Find::find(\&store_icons, '/usr/share/icons/gnome/');
      }
      }
      else {
      File::Find::find(
      \&store_icons,
      grep ({-d $_} "$home_dir/.icons/Faience",
      '/usr/share/icons/Faenza',
      '/usr/share/pixmaps/',
      "$home_dir/.local/share/icons",
      "$home_dir/.icons/", '/usr/share/icons/')
      );
      }
      }

      By the way, I still do not understand why it does not set the icons by himself...

      Delete
    3. It does, but not when an icon theme provides multiple icon directories... Maybe I should add this option into config file where to provide some 'first to look' directories...
      Thank you for reporting this!

      Delete
  3. You're welcome, thanks to you!!
    You're doing a great job, keep up with the good work ;)

    ReplyDelete
  4. I see that you update the script with said modification...I just wanted to say that it work great! Thank you very much for your efforts :)

    Can I request another little feature?
    I really like the "Openbox Settings" Submenu and I modified the script adding some entries to it like nitrogen for the wallpaper and others.
    It is not difficult to do it, but I was wondering if it would be possible to add to the config file an option where to provide personal entries for the submenu, like you do for the icon directories.

    I think it would be very handy.

    Thanks again, bye!

    ReplyDelete
    Replies
    1. Hmm... That's pretty hard to implement...
      Take a look at 'raw' option.
      Add in config something like this:
      {raw => <<"SUBMENU"},
      <separator/>
      <menu id="Openbox Settings" label="Openbox Settings">
      <item label="Reconfigure Openbox"><action name="Reconfigure" /></item>
      </menu>
      SUBMENU

      Delete
  5. That looks impressive. I am pretty new to the whole Openbox enviroment and just transfered from various Gnome 3 distros to crunchbang. Could you make a step by step guide for this script? I really wanna learn how to do this. Hope it's not asking to much.
    In advance, thank you very much.

    ReplyDelete
    Replies
    1. Thanks :)

      Well, it's pretty simple:
      1) copy anything from /etc/xdg/openbox/ into ~/.config/openbox/
      2) install this script in $PATH (install -Dm 755 obmenu-generator /usr/bin)
      3) open a terminal and run: obmenu-generator -i -p && obmenu-generator -R
      4) right click on Destkop
      5) enjoy it! :D

      Delete
  6. i dont understand how this script works. since i already use XDG for piping. do i add to the menu config file or something?, im so confused about how this works, im used to using the obmenu to add xdg

    ReplyDelete
    Replies
    1. All you need to do is to install and execute this script as "obmenu-generator -i -p", and reconfigure Openbox with "obmenu-generator -R". After doing this, when you right click on the desktop, the script will generate in real time a valid XML output, based on the .desktop files from /usr/share/applications, which will be used by the Openbox to generate create the graphical menu.

      Delete
  7. Would like to use obmenu-generator to create a pipe-menu (which it does) but it wipes out my menu.xml with its own version. Want to simply use created pipe-menu with my own root-menu. Is this possible? Everything else configures fine, really want to use this as a replacement of openbox-menu.

    ReplyDelete
    Replies
    1. Hello Mr Green,

      Sorry for this late answer. If you didn't figure it out, which I'm sure you did, you can add in your menu.xml a pipe call to obmenu-generator, something like this:
      <menu id="obmenu-generator" label="Applications" execute="/usr/bin/obmenu-generator -i"/>

      Only when using the "-p" option, the menu.xml is wiped out. If "-p" option is not provided, the script just prints to the standard output a valid XML menu, which can be used by Openbox.

      Best regards,
      Trizen

      Delete
    2. We did figure it out thanks, did think about a pure obmenu-generator menu but in the end we decided that applications menu is all we wanted in ArchBang.

      Delete
  8. Hello there,

    First, thanks for your hard work to produce such a fantastic package!

    I am wondering if you would perhaps consider adding some kind of "ignore" option in the config files. I ask as some packages will download so-called dependencies that will also show up in the menu. For example, thunar will also result in an "about xfce" item in the menu. It would be great to configure the menu to ignore desktop files like that.

    Thank you,

    Carl

    ReplyDelete
    Replies
    1. Hello Carl,

      Ignore options are already implemented. You just need to configure them in ~/.config/obmenu-generator/config.pl

      Change the value of 'skip_file_name_re' to something like this: qr{^xfce4-about}.

      You can skip more files, if you want to:
      skip_file_name_re => qr{^(?>avahi|sakura|pcmanfm|dconf|b(?>vnc|ssh)|gconf|xfce4-about)},

      There are also three more options for ignoring desktop files:
      skip_app_command_re
      skip_app_name_re
      skip_file_content_re

      The Config Documentation says:

      skip_app_command_re => REGEX
      - Skip the application if its command name matches the regex.

      skip_app_name_re => REGEX
      - Skip the application if its name matches the regex.

      skip_file_content_re => REGEX
      - Skip the application if the content of the *.desktop
      file matches the regex.

      skip_file_name_re => REGEX
      - Skip the application if its file name matches the regex.
      Name is from the last slash to the end. (example: file.desktop)


      Best regards,
      Trizen

      Delete
    2. This comment has been removed by the author.

      Delete
    3. This comment has been removed by the author.

      Delete
    4. Much thanks - yes, Mr. Green worked it out. I plan on putting up a Manjaro wiki page about configuring obmenu.

      Unfortunately it would seem there are still problems getting the menu to change its icon theme to match that selected for the system. ~/.gtkrc-2.0 is fine, and icons are listed in /user/share/icons. However, the default remains the same. Here is an example where I have tried even to specifically list the "HighContrast" icon set:

      icon_dirs_first => ["/usr/share/icons"],
      icon_dirs_last => [],
      icon_dirs_second => ["/usr/share/icons/HighContrast"],

      Also notable that although an app called "Octopi" has an icon listed in /usr/share/icons, it has no icon in the menu. Any advice would be much appreciated.

      Delete
    5. If icon_dirs_first is set to ["/usr/share/icons"], any subdirectory is searched for icons. This is a very bad thing to do, because the icon_theme may, or may not be the first subdirectory which is scanned, and, once an icon is found, it will not be replace by another.

      If Linux::DesktopFiles is updated to a version >= 0.07, you can safely say:
      gtk_rc_filename => undef,
      icon_dirs_first => undef,
      icon_dirs_last => undef,
      icon_dirs_second => undef,

      If Linux::DesktopFiles is still 0.06, then I would suggest the following configuration:
      gtk_rc_filename => undef,
      icon_dirs_first => ['/usr/share/icons/CURRENT_ICON_THEME_NAME'],
      icon_dirs_last => ['/usr/share/icons/gnome'],
      icon_dirs_second => ['/usr/share/icons/Faenza'],

      One more thing: after the icon theme is changed, you need to manually delete ~/.config/obmenu-generator/icons.db, or run obmenu-generator -i -d to generate a new icons database.

      "Octopi" should not have an icon inside the directory /usr/share/icons, unless it specifies the full path to the icon inside the .desktop file. If it does not, then you might want to contact the author/maintainer of the application to move the icon to a more standard path, like /usr/share/pixmaps (if the icon is .xpm format), or to /usr/share/icons/hicolor/[WITH]x[HEIGHT]/apps

      Best regards,
      Trizen

      Delete
    6. Excellent - worked a treat. OK, will let you know when wiki page is up. May prove helpful for any future questions or problems people have!

      Delete
  9. I'm a big fan of obmenu-generator and your other Perl programs. Your scripts help produce the perfect Arch Linux Openbox desktop.

    I've decided to include obmenu-generator as the default Openbox menu in an Arch Linux ISO build system called bitpkg. Do you have any availability to help out with bitpkg development? I'm atweiden@AUR, and atweiden on #archlinux@Freenode.

    ReplyDelete
  10. How could I cutomize the order of display & the content of the "obmenu-generator" ? Because I just have some strange applications that put crap in the menu, and it's just NOT nice :/
    Thanks again.

    ReplyDelete
  11. thanks from me, too.
    i've tried a few menugenerators on a minimalistic arch/openbox install, and this one is best!
    it's fast, but i like it even faster, so i made it create a menu file at login, that gets loaded by openbox.
    for this i had to hack into the script in /usr/bin; so here's my feature request: a command line switch to give custom id's (other than root-menu) to menus and another one to save it to a different file than the default ~/.config/openbox/menu.xml.

    ReplyDelete
    Replies
    1. Thanks. I've just released the version 0.56 which includes this options, along with many fixes and performance improvements.

      -m : menu id (default: 'root-menu')
      -o : static menu file (default: ~/.config/openbox/menu.xml)

      Each switch will take an argument.

      Delete
    2. At the top level generated menu where the default menu id can be overridden with -m switch it would be nice to have the ability to override the text of the label if you don't want the generated menu called "Applications". In my case, I want to leave a customized popup root-menu with all the submenus and options the repo developer gave it, but add to it a generated menu called "All Applications" which will popup the menu and submenus generated by your program.

      Do you think you could add another switch for the label text that corresponds to the -m menu id? perhaps -t "text of label" or something like that?

      Delete
    3. Actually, I went and found the code and saw that it was in plain text. I don't know Perl, but was able to add the capability to your code, starting based on the 0.59 version I got from the repo. I can send the modified code to you. I will look around here to see if your email address is available, and send it. If you don't get it, leave me a message here.

      Delete
  12. http://crunchbang.org/forums/viewtopic.php?pid=330811#p330811

    ReplyDelete
  13. Hi, thanks for your great work.
    I want to change the "Exit" option with oblogout, which one should I change on config file? I've tried to change "{exit => ['Exit', 'exit']}," but nothing happen.

    ReplyDelete
    Replies
    1. Hello, Renodesper.
      To use 'oblogout' instead of the default 'Exit', you can change "{exit => ['Exit', 'exit']}," into "{item => ['oblogout', 'Exit', 'exit']},". (first element is the command to be executed, the second is the label shown in menu and the third element is the icon name)

      Delete
  14. Thank you for writing such an excellent and useful script.

    Is there any way to to invoke the script, or a config key that would only generate icons when they are explicitly named? Or is there a way to exclude the icon for a specific item? Or for items within a category?

    I have several items that open config files in a text editor, and I'd like to list them without any icon in the menu.
    I can't figure out how to skip generating the icons for these items. I always end up with the default missing icon image. I suppose I could just create a blank icon and point the items to that, but (I think) the menu entry will still leave an empty space before the label.

    Do you think this feature might be tivial/worthwile to implement?

    ReplyDelete
    Replies
    1. This issue has been fixed in version 0.59; when an icon is not specified for an item, no icon will be used. Thanks for reporting this.

      Delete
  15. Whats the difference betwen static and dyanamic menu??

    ReplyDelete
    Replies
    1. Dynamic menu (or pipe menu) is created on fly when the user right-clicks the desktop. On the other hand, the static menu is generated once and will be used until it is manually regenerated. The advantage of the dynamic menu is that you don't have to worry about it being out-of-date; any new application will appear automatically in menu after its installation.

      Delete
  16. Hi,
    Thanks for this great script.

    I'm trying use the wine apps schema but is not working, i uncommented this line in schema.pl:

    # LABEL ICON
    {wine_apps => ['Wine apps', 'applications-other']},

    and is not showing.
    Is any other thing to do?

    TIA

    ReplyDelete
  17. Hello,

    Unfortunately, the 'wine_apps' key has been removed in the latest versions of obmenu-generator. To see the wine applications inside the menu, take a look at defaut schema file on github and make the needed changes: add the wine dirs which contain .desktop files inside the config file and add the substitution required for wine apps.

    A working example can be found here: https://github.com/trizen/config-files/tree/master/.config/obmenu-generator

    ReplyDelete
    Replies
    1. Thanks for your answer,

      Best regards,
      Jerry.

      Delete
  18. Hello,

    many Thanks for your work, there is a manner to abtain localizated names of the applications?

    Regards

    Carlo

    ReplyDelete
  19. you mus translate the categoies names in your ~/.config/obmenu-generator/schema.pl file
    and change the line "name_keys" in your ~/.config/obmenu-generator/config.pl file

    "name_keys" => ["Name[es]", "GenericName[es]", "Name"],

    obtain the translation to spanish. [es]
    [it] [it] will be italian etc...........

    ReplyDelete
  20. How would one create a menu listing all the apps (without the categories)?

    ReplyDelete
    Replies
    1. If you're using one of the latest versions of obmenu-generator (>= 0.59), you can delete all {cat => ...} entries from your schema.pl file (~/.config/obmenu-generator/schema.pl), except {cat => ['other', ...]}. In this category will get stored any application that don't belong to any listed category.

      Example of the schema.pl file:

      require "$ENV{HOME}/.config/obmenu-generator/config.pl";

      our $SCHEMA = [

      # some items here....

      # NAME LABEL ICON
      {cat => ['other', 'All applications', 'start-here']},

      # some other items here...
      ];

      Delete
    2. Thanks, I'm almost there.

      In schema.pl :
      our $SCHEMA = [ {cat => ['other', 'Other', 'applications-other']}, ]

      In menu.xml :
      menu id="generator" label="All" execute="obmenu-generator" /

      I do this because I don't want to spend the time I put into menu.xml doing the same thing in schema.pl (with manually added "{items..."). I end up with a pipe menu labeled "All" in which there is another menu labeled "Other", and then the list of applications found by obmenu-generator.

      Clearly, I am missing something. Also, I understand that categories are declared by applications in their .desktop file, but how can you do "{begin_cat => ['Obmenu-Generator', 'menu-editor']}" or "{obgenmenu => ['Openbox Settings', 'applications-engineering']}" ? I sense this could help do something like :
      menu id="generator" label="All" execute="obmenu-generator --category=other" /

      Am I being delusionnal or just tired?

      Delete
    3. Ok I just realized "menu-editor" and "applications-engineering" are icons. Questions hold, though. Thanks!

      Delete
    4. I understand what you are asking: to get the list of applicationd outside a category. Unfortunately, this is not possible in the current version of obmenu-generator, but you can delete from the output the lines that begin and end the 'other' category by using sed or grep on output generated by obmenu-generator, something like: obmenu-generator | grep -v '' # untested

      Delete
    5. Thanks. I ended up copying the output of obmenu-generator and deleting the menu lines. Leaves me with only the items. You could also replace the menu tags with separators.

      Delete
  21. Thanks for this awesome software :)

    Oh and the Arch Linux AUR link you posted is broken, the correct one is https://aur.archlinux.org/packages/obmenu-generator/

    ReplyDelete
    Replies
    1. No problem. :)

      Ups, I haven't noticed this. Updated now. Thanks!

      Delete
  22. obmenu-generator -i -p && obmenu-generator -R
    Can't locate Linux/DesktopFiles.pm in @INC (you may need to install the Linux::DesktopFiles module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.20.2 /usr/local/share/perl/5.20.2 /usr/lib/x86_64-linux-gnu/perl5/5.20 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.20 /usr/share/perl/5.20 /usr/local/lib/site_perl .) at /usr/bin/obmenu-generator line 34.

    What does above mean? How to get out of this problem?
    Thanks!

    ReplyDelete
    Replies
    1. You need to install the Perl module, called "Linux::DesktopFiles".

      Execute the following command:

      sudo perl -MCPAN -e 'CPAN::Shell->install(q{Linux::DesktopFiles})'

      and follow the instructions.

      Delete
  23. Hi there. I hope that you are still answering questions. I've gobe through this whole page and haven't seen this addressed. I'm guessing that I'm doing something wrong but I am trying to skip desktop files that contain 'NotShowIn=Openbox'. I'm using the 'skip_entry' option and this is what my string looks like:
    [{key => 'NotShowIn', re => qr/Openbox/},],

    If I use the term 'exec' this exact same expression works perfectly. For example if my string is:
    [{key => 'Exec', re => qr/xfce4-about/},],

    That works perfectly. Is the 'NotShowIn' desktop key not recognized by obmenu-generator?

    ReplyDelete

Post a Comment