Diary and notebook of whatever tech problems are irritating me at the moment.

20130926

Cleaning up the Ubuntu and Linux Mint game menus

Most kids love games.  Thanks to F/OSS developers, Humble Bundle, Desura, Steam, and a variety of cross-platform Kickstarter and Indiegogo projects they now have many to choose from with more on the way.

But when I set up a system and start loading dozens of games the desktop menus become quite a mess.  Some games are not listed, or are listed in only in the main "Games" menu but not the correct sub-menus, or are listed in multiple sub-menus, or missing icons, or fail to function.

This is on top of the usual problems with broken packages, bitrot with old closed-source games (Loki titles in particular), conflicts with PulseAudio, and a lack of documentation combined with unusual keyboard key assignments.  The latter is really annoying when a game launches full screen and the user is unable to figure out how to exit it.

Obviously some problems are much more difficult to resolve than others but the desktop menus are fairly easy to fix.  I have fixed dozens and you can do the same.  The link to the archive with my changes is at the bottom of this post but before you get into that you need to understand how the menu system works.

Originally all window managers and desktop environments used their own menu configuration files.  One legacy menu structure is located in /usr/share/applnk.  Debian created a standard for their distro where a menu file was created once in /usr/share/menu and then exported dynamically as needed for each menu system.  Later, freedesktop.org (formerly named the X Desktop Group) developed a new standard that has been adopted by Gnome, KDE, Xfce, and others.

With the fdo/XDG standard the menu entries are created as INI files according to the Desktop Menu Specification (*.menu) and Desktop Entry Specification (*.desktop).  The latter standard also defines how to specify the names and icons of the menus themselves (*.directory).  Most desktop environments follow v1.0 of the standard but a v1.1 draft is in development.  The *.menu files are located in /etc/xdg/menus.  The *.desktop files are located in /usr/share/applications or /usr/local/share/applications.  The *.directory files are located in /usr/share/desktop-directories or /usr/local/share/desktop-directories.

A note about /usr, /usr/local, and /opt.  Their structure is defined by the Filesystem Hierarchy Standard. The first two follow the traditional *nix structure where binaries, libraries, documentation, and support files are organized into specific subdirectories by type and may be shared with other programs (especially libraries).  Files for programs in /opt are organized by provider and are generally contained entirely within their own subdirectory and not shared with other programs.  In practice, /usr is where files "managed" by a package manager (apt) are located.  Unmanaged files are in /usr/local and are usually not registered with the package manger.  Files in /opt may be managed or unmanaged depending on their source (an install script or a deb package).

Unfortunately some games don't follow the FHS properly.  Some managed packages put their files in /usr/local and some installers put their unmanaged files in  /usr.  Other installers add their files and then ask to "register" with the package management system for easier removal, resulting in a mix of managed and unmanaged files.  Managed files can be identified using dpkg-query:

dpkg-query -S /path/to/filename

If dpkg-query doesn't find the file then it's not managed.

Desktop entries are organized according to rules in the *.menu files.  While a *.desktop file can be specified directly, most are arranged by matching "Categories" values in the files.  According to the standard there are both "Main" and "Additional" categories.  A desktop entry file should have one Main category except as required (for example, "Audio" or "Video" mandates "AudioVideo") and an Additional category for more precise organizing.  Most of the Additional categories are reserved for specific Main categories.  Obviously sub-menus have have to be defined before they can be used else everything lands in the primary menus.  Linux Mint's Xfce menu configuration doesn't define the game secondary sub-menus by default (mint-artwork-xfce package) so the games menu gets very crowded.  My menu configuration defines sub-menus for all standard game categories.

Desktop entry files with multiple Main and Additional categories specified is an occasional problem.  While some programs can arguably fit into more than one category, doing this in the desktop entry file often causes duplicates in the menus.  Duplication can be suppressed with menu rules but it's much easier to avoid the problem in the first place.  Some desktop entry files don't specify an Additional category and as a result the menu entry lands in the primary sub-menu, not in the secondaries with similar programs.  Occasionally there will be a standards-compliant combination of Main and Additional categories that are not handled properly in the menu definition files which results in an entry erroneously stuck in the main menu or under an "Other" sub-menu.  But errors in the desktop entry files are the root cause most of the time.

Another problem is the categories themselves.  The video game genres are somewhat ambiguous and many games overlap multiple genres.  Even the main category "Game" can be a problem with some.  Emulators, for example, can be specific to a game console (PCSX) or general-purpose (QEMU).  The fdo/XDG standards only cover a few game genres, some of which are very narrow while others are overly broad.  These are my interpretations:

ActionGame: A catch-all for anything that requires reflexes that doesn't fit in a more specific category.

AdventureGame: Point-and-click adventures and interactive stories.  If it requires reflexes then it doesn't belong here.  Even so, there are some games which have a mixture of both so it becomes a judgment call as to developer intent (Full Throttle).

ArcadeGame: An ambiguous genre unless you restrict it to games that were found in coin-operated arcades at some point.  I included games with simplistic gameplay and a minimalistic storyline, if any.  If it has a point-based "high score" then it's probably an arcade game.

BoardGame: Board games and games that could reasonably be board games or were derived from one.

BlocksGame: Tile-matching and Tetris types, as per the Wikipedia article.

CardGame: Probably the easiest to figure out although gtali is a bit of an oddball.

KidsGame: Another non-genre genre.  I included any game with a theme that is heavily slanted towards young children.  However, some also fall into the Educational main category (GCompris).

LogicGame: Slightly odd name as it includes puzzles.  Again there are some platformers that combine this with action (EDGE, Stealth Bastard).

RolePlaying: If it doesn't have a character development system then it's not a role-playing game.  Having a fantasy theme is not good enough.  Waste's Edge is an example of a game that says it's a role-playing game when it obviously is an adventure game.  It's nothing more than a long dialog puzzle.  It's not a bad puzzle and has a good story, but it's not a role-playing game.

Simulation: Vehicle, economic, and environment simulations including cars, cities, and space.  Car racing games are often marketed as sports games but that never seems to include airplane racing games.  Some vehicle simulations have cinematic physics and may belong elsewhere (ArcadeGame, ActionGame).

SportsGame: Traditional sports not involving vehicles.  Includes "fantasy" sports management applications.  Real sports management applications probably belong elsewhere, perhaps Office/ProjectManagement.

StrategyGame: Some are obvious, some not.  The problematic ones are those that require tactics but not quite long-term strategic thinking (Atom Zombie Smasher).  I tend to follow the developer's opinion but not always.

Amusement: Snowing desktops (xsnow), eye-candy (xdesktopwaves), and the like.  Doesn't have a defined Main category but I set all the ones I found to Games since that is the most logical option.  Creating a new primary sub-menu didn't make sense.

Shooters: This is new in the v1.1 draft specification.  Again it is a bit too broad of category but because the ActionGame category is so crowded I decided to support it, just not by default.  I wrote the "set-shooter-categories" script which changes some of my desktop entries to this category (mostly first-person shooters) but the targets are all hard-coded.  It doesn't have a reversion option so keep a backup copy of the original *.desktop files.  I defined a Shooters sub-menu in my replacement menu definitions (applications.menu, xfce-applications.menu) and included an icon and the shooters.directory file.

Adding to the problems are programs that represent many games including the Steam client, Desurium, and gtkboard (which includes Tetris and Mastermind).  I normally just leave these in Games by not specifying an Additional category.

Some games in the repos have the old Debian menu files but not the newer fdo/XDG files.  There is an optional "Debian menu" that can be merged with the newer menu files to create a "Debian" sub-menu with all the old menu entries.  However it has a different structure and is mostly redundant with the main menus - overkill for just getting some games to show up.  I encountered the missing *.desktop file problem often enough that I wrote the "deb-menu-conv" script to export old Debian menu files as something that resembles the new fdo/XDG files.  While deb-menu-conv handles the basics, some things like categories (called "sections" in the Debian menus) do not translate directly.  It has some hard-coded conversions for games but most anything else will need manual editing.  Debian menu files also allowed multiple menu entries per file while the fdo/XDG standard does not.  All entries found in a menu file are exported by deb-menu-conv and have to be split manually into separate *.desktop files.  This script saved me a whole bunch of time but some packages were still a pain (xmpuzzles, xteddy, x11-apps) due to the number of entries their old menu files contained.  I excluded most terminal and text-mode entries.

Some of the programs in the Debian menus are obsolete but I included them as a test of deb-menu-conv.  Many of the amusement-type programs (xfireworks, xsnow, xpenguins) require direct access to the primary X window (root window) that is commonly controlled by a desktop manager in modern desktop environments (xfdesktop in Xfce).  They can be used on Xfce if xfdesktop is terminated first (Settings Manager > Session and Startup > Session > xfdesktop > Quit Program).  Log out and back in again or create a launcher in a desktop panel to restart xfdesktop afterwards.

I also fixed some other bugs via the desktop entry files.  Doom3 doesn't get along with PulseAudio so I added pasuspender to the Exec line in its file.  Some games have both 32-bit and 64-bit versions but their installer only adds one or the other and they have different names.  This meant that a single menu entry couldn't support both so I had to replace it with two different files.  For several of the games with undocumented keys and lack of built-in help I added additional menu entries that open man pages, Readme documents, and web sites with relevant information. 

One parameter that is very useful is "TryExec".  This is a test where the menu system looks for the target file and only shows the menu entry if it is found.  Since it is targeting executables it can be used to check for both file and directory targets.  All of my desktop entry files have this set so that if they are all installed they won't crowd the menus with entries for unavailable programs.  This is also handy for menu entries that target the 32-bit and 64-bit versions of a binary.  However, if a game normally installs both then only one entry is used and it points to a script that dynamically loads the correct binary based on the system architecture.  I wrote or modified several game loading scripts for this reason (and to fix other bugs).

Installing a modified menu or desktop entry file is easy if it is unmanaged - just overwrite the original.  However, managed files are more complicated.  If an update is installed by the package manager then the modified file may be overwritten.  The solution is to divert the original file to a different location with dpkg-divert.  When apt applies the update it will then redirect the diverted file to the new location, leaving the modified one intact.

The installation of the modified files is easy when only a few files are involved.  But I ended up with dozens which I realized would be error-prone and time-consuming to install.  So I wrote the "file-overrides" script to handle installation automatically, make backups of replaced files, and be able to revert changes.  It has built-in help but I will summarize the basics here.

Overrides are located in a subdirectory structure that mimics the actual targets.  The default directory is /usr/local/share/file-overrides.d which contains two subdirectories, managed and unmanaged.  The difference is that managed targets are diverted (and moved) by dpkg-divert while unmanged targets are moved directly.  These subdirectories must exist else the script will abort.

The diversions and backups are located in /usr/share/Diversions/file-overrides by default and this directory must also exist.  The script will create "managed" and "unmanaged" directories as needed and will remove their contents automatically during reversions.

The structures are relative so that a replacement for managed file:

/usr/share/appications/quake3.desktop

is located at:

/usr/share/Diversions/file-overrides/managed/usr/share/applications/quake3.desktop

During an override operation the original will be moved/diverted to:

/usr/share/Diversions/file-overrides/managed/usr/share/applications/quake3.desktop

prior to being replaced.  During a reversion the sequence is reversed, more or less.  While intended for fixing menu entries the script can be used to replace any file on the system.  It does have some special support for the *.desktop files.  Normally the script will only install an override file if the target already exists to keep the directories clean.  However, if the file is a desktop entry file with TryExec set, and the target executable exists, then the override will be applied even if the target *.desktop file does not exist.  The --force parameter applies all overrides regardless.

Another special case is with override files that are zero bytes in size.  This causes the target to be moved/diverted but not replaced, essentially causing a deletion.

See the readme.txt file for more info on included icons and such.

The archive contains everything.  Note that it has been developed and tested on Ubuntu 12.04 (Precise Pangolin)/Linus Mint 13 (maya) with Xfce 4.10.  It will probably work with newer releases (and Debian) and other desktop environments with the exception of the menu files which may need adjusting.  Compare them to the originals in /etc/xdg/menus.


file-overrides.d_v1.1.tar.bz2

md5sum: b15e343fe9c901f4556bed27fbce8cf8

1 comment:

Unknown said...

Ubuntu is one of the lightest operating system that's why they are used for gaming and accessing internet facility.

Thanks
Bruce Hammerson

Hammer Bits

About Me

Omnifarious Implementer = I do just about everything. With my usual occupations this means anything an electrical engineer does not feel like doing including PCB design, electronic troubleshooting and repair, part sourcing, inventory control, enclosure machining, label design, PC support, network administration, plant maintenance, janitorial, etc. Non-occupational includes residential plumbing, heating, electrical, farming, automotive and small engine repair. There is plenty more but you get the idea.