Linux – are the application.desktop files not showing up in Linux application menu

desktoplinux

I've written quite a few open source programs over the years, but not very recently, and I've never had this problem before. The menu items for my new project simply refuse to show up in menus on either gnome or kde.

I originally just installed the .desktop files to /usr/share/applications but later modified it to use desktop-file-utils – all to no avail. I've add update-desktop-database to my postinst script… nothing

I've validated the entries, and in the file manager they are correct, I've tried giving them execute permissions… I can't find anything wrong but they just won't show up. Is there something new one has to do to get your app's menu items to show these days ?

The .desktop files are:

silentcoder@ravenriley ~/SOURCE/ezdm $ cat ezdm.desktop 
[Desktop Entry]
Type=Application
Name=EZDM
GenericName=Easy Dungeon Master
Comment=A tookit for AD&D Dungeon Master
TryExec=/usr/games/ezdm
Exec=/usr/games/ezdm
Categories=Game;RolePlaying;
Icon=/usr/share/icons/hicolor/128x128/ezdm.png
Terminal=false

cat ezdmconsole.desktop

[Desktop Entry]
Type=Application
Name=EZDM-Console
GenericName=Easy Dungeon Master (Console version)
Comment=A tookit for AD&D Dungeon Master
TryExec=/usr/games/ezdm --console
Exec=/usr/games/ezdm --console
Categories=Game;RolePlaying;
Icon=/usr/share/icons/hicolor/128x128/ezdm-console.png
Terminal=1
X-Desktop-File-Install-Version=0.20

And if any of the other code might be useful, it's all browseable on github: https://github.com/ajventer/ezdm

UPDATE: The mystery deepens, if I copy the files to /usr/share/applications/kde4 (which I obviously don't want to do in my package – after all, it should work in gnome too) then suddenly ezdm.desktop does show up in the menu, but ezdm-console.desktop still refuses to.

UPDATE: since it may be relevant:
From Makefile:

install:
                $(PYTHON) setup.py install --prefix=/${PREFIX} --root $(DESTDIR) --install-scripts=/${PREFIX}/games/ --no-compile --force --record .install.record --install-layout=deb
                mkdir -p ${DESTDIR}/${PREFIX}/share/applications
                mkdir -p ${DESTDIR}/${PREFIX}/share/icons/hicolor/128x128/
                desktop-file-install --dir=${DESTDIR}/${PREFIX}/share/applications/ ezdm.desktop 
                desktop-file-install --dir=${DESTDIR}/${PREFIX}/share/applications/ ezdm-console.desktop 
                install -g root -o root -m 0666 ezdm.png ${DESTDIR}/${PREFIX}/share/icons/hicolor/128x128/ezdm.png
                install -g root -o root -m 0666 ezdm-console.png ${DESTDIR}/${PREFIX}/share/icons/hicolor/128x128/ezdm-console.png 
                update-desktop-database ${DESTDIR}/${PREFIX}/share/applications

And debian/postinst:

cat debian/postinst 
#!/bin/bash -x
ln -sf /usr/games/ezdm* /usr/bin
for I in /usr/lib/python2.7/dist-packages/ezdm_libs/*.py; do
        python -m compileall $I
done
update-desktop-database
#DEBHELPER#

Best Answer

There is very insidious desktop file key - TryExec. According to docs:

TryExec

Path to an executable file on disk used to determine if the program is actually installed. If the path is not an absolute path, the file is looked up in the $PATH environment variable. If the file is not present or if it is not executable, the entry may be ignored (not be used in menus, for example).

So, it may result in missing menu entry if it is not filled properly. And by "properly" I mean that it always must point to actual executable.

Surprisingly, if you trying to launch your program in modified environment using env, it stops working. Here is example of invalid desktop file from my distro's package:

TryExec=env FONTCONFIG_FILE=/usr/share/fonts/fonts.conf telegram -noupdate
Exec=env FONTCONFIG_FILE=/usr/share/fonts/fonts.conf telegram -noupdate -- %u

It doesn't work because DE looks for env FONTCONFIG_FILE=/usr/share/fonts/fonts.conf telegram -noupdate executable, treating whole string (including spaces) as file path, which is missing, of course.

The solution is also simple: just specify path to actual executable (even relative):

TryExec=telegram
Related Question