Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Suggestion] Integrate .desktop files in a more standard manner, similar to snaps, flatpak, nix etc #386

Open
codexMechanicus opened this issue Aug 26, 2022 · 20 comments
Labels
enhancement New feature or request

Comments

@codexMechanicus
Copy link
Contributor

codexMechanicus commented Aug 26, 2022

This is similar to a request I made before but is much better thought out and inline with standard XDG practice.

Getting to the point, distrobox app exports could better conform to standard practices by storing exported .desktop files in a directory specifically for distrobox exports, while still showing up in users menu's.

for example $HOME/.distrobox/share
or any where deemed a better location.

To ensure exports show up in the users desktop menus the paths would be added to the users XDG_DATA_DIRS
via a command such as:
`echo export 'XDG_DATA_DIRS=$HOME/.distrobox/share:$HOME/.share:"${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}" ' >> ~/.xsessionrc
(This command sets up default XDG_DATA_DIRS if they are not already set up)

The .desktop files could also be stored in container specific files .distrobox/ubuntu/share and symlinked to .distrobox/share or whatever the chosen path is. Which would help with issue #301 and allow these files to be deleted simply by deleting the folder.

There are reasons other applications that export .desktop files create their own directory and add the directory to XDG_DATA_DIRS, and making it easier to clean up and manage exports I expect is a key aspect of it. This is practised by GNOME devs and others who are involved in discussing XDG/freedesktop.org standards.

I think if this is not standard behaviour it should at least be an available option via config files, or app exports should accept a custom location so this can be implemented simply by users.

Stack Exchange answer where I got the idea: https://unix.stackexchange.com/questions/310666/nix-desktop-files

*PS: If this suggestion is approved of, I can implement it and submit a pull request.

@codexMechanicus codexMechanicus added the enhancement New feature or request label Aug 26, 2022
@89luca89
Copy link
Owner

I really like this idea! It would make life a lot easier thanks 😄

I'll think on how to organize it, but ideas are welcome!

@89luca89 89luca89 pinned this issue Aug 28, 2022
@89luca89
Copy link
Owner

89luca89 commented Aug 28, 2022

What I was thinking is just that managing XDG_DATA_DIRS could be tricky for the installer:

if we're doing a rootful install (package or sudo ./install), we can just put a script in /etc/profile.d/distrobox.sh that sets up the variable
But if we're doing a rootless install (./install in $HOME), we need to find a way to add it to the user's profile without risking on messing up the ~/.profile file

EDIT: This will also be super-handy for the new generate-entry command 😃

@codexMechanicus
Copy link
Contributor Author

codexMechanicus commented Aug 31, 2022

I'm glad you like it Luca! I don't know what generate-entry is yet, (I'm intrigued) but I'm glad it helps there, it also shows that it's a solution which would help everything fall into place!

The command I gave doesn't require root privileges or is the issue the lack of permanence of that command? That the command needs to be triggered on login?

Yes, I did over look something in the initial post and the command I gave wasn't sufficient to make the change persistent, I came across something that is too hacky for my liking:

echo export 'XDG_DATA_DIRS=$HOME/.distrobox/share:$HOME/.share:"${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}" ' >> ~/.xsessionrc

Though it definitely works, is persistent and does not requite root privileges. However, it could lead us in the right direction, what is needed is a destination that more appropriate. I wonder how flatpak/snap and the rest go about this? A look at their source code may be in order there however they may well use root user permissions.

@89luca89
Copy link
Owner

echo export 'XDG_DATA_DIRS=$HOME/.distrobox/share:$HOME/.share:"${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}" ' >> ~/.xsessionrc

Yea I know, we could also use the ~/.profile file, but I'm keen to not touch other people's files if possible 😄

I wonder how flatpak/snap and the rest go about this? A look at their source code may be in order there however they may well use root user permissions.

They just drop the line in a file in /etc/profile.d/flatpak.sh, and that's sourced automatically at login
But that's the part that requires root

@sebastiencs
Copy link

For rootless install, a file could be added to ~/.config/environment.d/ ?

https://www.man7.org/linux/man-pages/man5/environment.d.5.html

@89luca89
Copy link
Owner

89luca89 commented Sep 2, 2022

For rootless install, a file could be added to ~/.config/environment.d/ ?

https://www.man7.org/linux/man-pages/man5/environment.d.5.html

This seems to be systemd specific, and to work with systemd-units
Tried to use for the shell but didn't work

@codexMechanicus
Copy link
Contributor Author

codexMechanicus commented Sep 8, 2022

I'm keen to not touch other people's files if possible

There are a few suggestions here.
https://www.simplified.guide/linux/automatically-run-program-on-startup

A cron job to run the command might be best? Since it's part of Linux-utils and thus supported by sys-v as well as more niche init systems. Cron jobs execute commands as non-root users and I'm guessing it can be set up rootlessly also?

@luc14n0
Copy link
Contributor

luc14n0 commented Sep 20, 2022

Instead of touching $XDG_DATA_DIRS, what about sticking with standard locations: /usr/share/applications/$XDG_DATA_HOME/applications and calling update-desktop-dabase to ensure they appear on the application menu?

We could either use .../applications or .../applications/distrobox/... if organizing by container is preferred.

I don't use distrobox-export but, just as an example, one could add a desktop file to launch gnome-terminal and automatically run a Ubuntu (or whichever distro they want) container inside Tmux:

  1. Drop the desktop file in $XDG_DATA_HOME/applications, distrobox-Ubuntu-22.desktop in this example, with the following content:
[Desktop Entry]
Name=Ubuntu 22.04
GenericName=Distrobox Ubuntu 22.04
Comment=Launch Ubuntu 22.04 container
TryExec=gnome-terminal
Exec=gnome-terminal --maximize -- distrobox-enter -a '--env DISTROBOX=ubuntu' -n ubuntu -- tmux -L dbx-ubuntu new -s Hera
Icon=/home/luc14n0/Pictures/ubuntu-logo32.png
Type=Application
Categories=GNOME;GTK;System;TerminalEmulator;
StartupNotify=true
StartupWMClass=Gnome-terminal
X-GNOME-SingleWindow=false
Actions=preferences;

[Desktop Action preferences]
Name=Preferences
Exec=gnome-terminal --preferences
  1. And finally call $ update-desktop-database $XDG_DATA_HOME/applications. A $ desktop-file-validate our-desktop-file.desktop can help us with checking if we're hurting any Desktop Entry specification. Both tools are provided by Freedesktop's desktop-file-utils package.

Now I have this neat puppy here:

image

@codexMechanicus
Copy link
Contributor Author

codexMechanicus commented Sep 21, 2022

@luc14n0
You can use the new command distrobox generate-entry to add a guest system to your applications menu, to save you from creating your own desktop entry file as you have done here.

to ensure they appear on the application menu?

Exported files and generated entries aught be displayed in app menu's currently, if they don't in your case for whatever reason then this should be raised as a separate issue and an error. This isn't the purpose behind my suggestion, which is a better means of managing exported files from a developers perspective, making cleaning up exports easier, thereby not cluttering up default locations.

@89luca89
Copy link
Owner

I was thinking @codexMechanicus
a middle-of the ground solution, could be using symlinks

I'll export stuff into (for example) ~/.local/share/distrobox/applications/$CONTAINER_NAME
Then link the bin and desktop file, to the canonical paths

On removal of the container, simply remove the $CONTAINER_NAME directory, and remove broken links into the canonical paths bin and applications 🤔

@luc14n0
Copy link
Contributor

luc14n0 commented Sep 22, 2022

@luc14n0 You can use the new command distrobox generate-entry to add a guest system to your applications menu, to save you from creating your own desktop entry file as you have done here.

to ensure they appear on the application menu?

Exported files and generated entries aught be displayed in app menu's currently, if they don't in your case for whatever reason then this should be raised as a separate issue and an error. This isn't the purpose behind my suggestion, which is a better means of managing exported files from a developers perspective, making cleaning up exports easier, thereby not cluttering up default locations.

I was just giving a silly bad example. My main point was that for a standard location to place .desktop files $XDG_DATA_HOME/applications is an option, in rootless setups, instead of using XDG_DATA_DIRS.

@89luca89
Copy link
Owner

@luc14n0 You can use the new command distrobox generate-entry to add a guest system to your applications menu, to save you from creating your own desktop entry file as you have done here.

to ensure they appear on the application menu?

Exported files and generated entries aught be displayed in app menu's currently, if they don't in your case for whatever reason then this should be raised as a separate issue and an error. This isn't the purpose behind my suggestion, which is a better means of managing exported files from a developers perspective, making cleaning up exports easier, thereby not cluttering up default locations.

I was just giving a silly bad example. My main point was that for a standard location to place .desktop files $XDG_DATA_HOME/applications is an option, in rootless setups, instead of using XDG_DATA_DIRS.

that's what it is already done, they are exported in $HOME/.local/share/applications

The idea was to have somewhat a dedicated directory in order to not litter the $XDG_DATA_HOME/applications, and have an easier way to cleanup when we remove a distrobox for example

@codexMechanicus
Copy link
Contributor Author

I was thinking @codexMechanicus a middle-of the ground solution, could be using symlinks

That works and has all the benefits while avoiding the issues faced by other solutions, I can't see any downsides myself! 😄
The original proposal used symlinks partially, so it makes sense to use nothing but symlinks. 👍

@luc14n0
Copy link
Contributor

luc14n0 commented Sep 24, 2022

that's what it is already done, they are exported in $HOME/.local/share/applications

The idea was to have somewhat a dedicated directory in order to not litter the $XDG_DATA_HOME/applications, and have an easier way to cleanup when we remove a distrobox for example

Well, for what is worth in my Tumbleweed system I have:

$ find /usr/share/applications -type d
/usr/share/applications
/usr/share/applications/YaST2
/usr/share/applications/YaST2/groups
/usr/share/applications/screensavers
$ rpm -qf /usr/share/applications/screensavers
xscreensaver-data-6.03-4.2.x86_64

The xscreensaver package, the one that produces xscreensaver-data doesn't trigger any RPM Lint warnings, so it seems that having subfolders in canonical places are permitted.

@codexMechanicus
Copy link
Contributor Author

doesn't trigger any RPM Lint warnings, so it seems that having subfolders in canonical places are permitted.

I don't know if RMP lint would necessarily be checking whether XDG's Desktop Entry Specification is being adhered to.

I think it's best practice not to clutter it whether it's technically permissible or not. Those who work closest to XDG avoid cluttering it, as with Gnomes Flatpak, XDG was pretty much instigated by Gnome devs.

@luc14n0
Copy link
Contributor

luc14n0 commented Sep 26, 2022

I don't know if RMP lint would necessarily be checking whether XDG's Desktop Entry Specification is being adhered to.

I'm sorry you got me wrong here. In the xscreensaver-data example I gave I'm talking specifically about the path where it's installing its desktop file(s). As far as I can tell XDG's Desktop Entry Specification is about the desktop file's content. The only section in the Desktop Entry Specification I see talking about location is Desktop File ID, in File Naming, where it states:

To determine the ID of a desktop file, make its full path relative
to the $XDG_DATA_DIRS component in which the desktop file is
installed, remove the "applications/" prefix, and turn '/' into '-'.

...

If multiple files have the same desktop file ID, the first one in
the $XDG_DATA_DIRS precedence order is used.

...

If the desktop file is not installed in an applications subdirectory
of one of the $XDG_DATA_DIRS components, it does not have an ID.

So, from that, we can infer that desktop files can even not be installed under a relative path to $XDG_DATA_DIRS, but they wont have a desktop file ID in such cases.

My point about RPM Lint was more of whether or not we get a warning/error when using a subfolder under /usr/share/applications. The only relevant check that takes account of $XDG_DATA_DIRS/applications I could find is rpmlint/checks/MenuXDGCheck.py where we see:

class MenuXDGCheck(AbstractFilesCheck):
    """
    Check whether MenuXDG files installed by a package are valid.
    """
    def __init__(self, config, output):
        # desktop file need to be in $XDG_DATA_DIRS
        # $ echo $XDG_DATA_DIRS/applications
        # /var/lib/menu-xdg:/usr/share
        super().__init__(config, output, r'/usr/share/applications/.*\.desktop$')

I think it's best practice not to clutter it whether it's technically permissible or not. Those who work closest to XDG avoid cluttering it, as with Gnomes Flatpak, XDG was pretty much instigated by Gnome devs.

Where desktop files will end, for me it doesn't really matter, as long as it's in a standard place rather than a dark corner that will left traces behind when Distrobox gets uninstalled.

I gave some insights (I hope?) about using /usr/share/applications and ~/.local/share/applications. Now let me say something about adding a custom place to the $XDG_DATA_DIRS env. variable.

The Flatpak way was mentioned earlier, but there was the concern about touching user configuration files, and with good reason as I've experienced Miniconda wiping my entire .zshrc file because of wrong use of redirection (like using > redirection rather than >>, or something else I can't remember right now).

Between user configs and symlinks, my personal preference is user configs. But if choosing so we could either alert users to add the snippet to their configs (and make use of good documentation too) or implement the right logic to automatically add it to the most used shells (good testing is our friend here). And I could give a hand on this if needed.

@codexMechanicus
Copy link
Contributor Author

codexMechanicus commented Sep 26, 2022

What do you have against symlinks? It seems to be the option that needs less work, less tailoring to specific systems etc.

Does it really makes a difference where files are stored from the perspective of uninstallation? Surely if we include our applications folder in an installation package it will be removed by the package management system, and we can reference the directory in the uninstallion script.

@89luca89
Copy link
Owner

@luc14n0

Technically RPMlint allows stuff like /usr/share/applications/distrobox or ~/.local/share/applications/distrobox, but the desktopfiles won't be detected inside there, if you don't add them to XDG_DATA_DIRS anyway

Also, while I agree we could just document and warn the user about it, I'm not so keen to leave to the user this
It will be integral part of the export functionality and already now I'm seeing A LOT of issues or questions where reading the docs would have simply solved it... so I don't trust that some user would deliberately read the docs just to set something in order for distrobox to work 😅

@luc14n0
Copy link
Contributor

luc14n0 commented Sep 30, 2022

What do you have against symlinks? It seems to be the option that needs less work, less tailoring to specific systems etc.

Nothing in particular really, if implemented right and it's working who am I to complain, right? 😄

I just feel they are less systematic to work with, but this is more of a personal opinion/bias than anything else since I never had to implement shell code to manage symlinks before.

Does it really makes a difference where files are stored from the perspective of uninstallation? Surely if we include our applications folder in an installation package it will be removed by the package management system, and we can reference the directory in the uninstallion script.

No, I don't see a difference. Yes, package managers should do the right thing if we don't do anything obscure, and so does the uninstallation script.

@luc14n0
Copy link
Contributor

luc14n0 commented Sep 30, 2022

Luca, you previously said:

I was thinking @codexMechanicus a middle-of the ground solution, could be using symlinks

I'll export stuff into (for example) ~/.local/share/distrobox/applications/$CONTAINER_NAME Then link the bin and desktop file, to the canonical paths

On removal of the container, simply remove the $CONTAINER_NAME directory, and remove broken links into the canonical paths bin and applications thinking

I didn't pay due attention to some of those words before. Now I see some of your concerns clearer and why the temptation of using symlinks: The install/uninstall scripts both have a --prefix option flag that can make one's life less easier in case one chooses ~/My_Applications/GitHub/testing/beta, for example, as a prefix.

Unless this flag is e.g. removed and more standard prefixes are enforced - like / and/or /usr/local for rootful and ~/.local for rootless - which I don't think is the most desired option here because that can cause backward incompatibilities if not handled correctly, which in turn means more work to be done and more hair pulled off one's head 😄 (nonetheless long term should pay off).


Technically RPMlint allows stuff like /usr/share/applications/distrobox or ~/.local/share/applications/distrobox, but the desktopfiles won't be detected inside there, if you don't add them to XDG_DATA_DIRS anyway

Not exactly. $XDG_DATA_DIRS can be thought as a $PATH for desktop files:

There is a set of preference ordered base directories relative to which data files should be searched. This set of directories is defined by the environment variable $XDG_DATA_DIRS

(more details here [1]).

Using $XDG_DATA_DIRS allows desktop files to have ID, which in turn allows a ~/.local/share/applications/foo.desktop takes precedence over /usr/share/applications/foo.desktop. More or less like $PATH, $XDG_DATA_DIRS has a cache to speed things up:

distrobox$ find /usr/share/applications/ -type f -not \( -name '*.desktop' \)
/usr/share/applications/mimeinfo.cache

distrobox$ head /usr/share/applications/mimeinfo.cache
[MIME Cache]
application/bzip2=org.gnome.FileRoller.desktop;org.gnome.Nautilus.desktop;
application/epub+zip=com.github.johnfactotum.Foliate.desktop;
application/gnome-radio=gnome-radio.desktop;
application/gpx+xml=org.gnome.Maps.desktop;
application/gzip=org.gnome.FileRoller.desktop;org.gnome.Nautilus.desktop;
application/illustrator=org.gnome.Evince.desktop;org.inkscape.Inkscape.desktop;
application/mbox=org.gnome.Evolution.desktop;
application/mpeg4-iod=vlc.desktop;
application/mpeg4-muxcodetable=vlc.desktop;

So one way or another someone/something must call update-desktop-database /usr/share/applications at some point so the cache file can catch up. If we don't (I not seeing it in the install/uninstall scripts. Allow me to send an improvement regarding this.) but the standard /usr/share/applications folder is used that's OK-ish because sooner or later when some native package containing a desktop file is going to be installed/updated an update-desktop-database call will kick in. Now if the desktop file end up somewhere else we have the responsibility to make that call ourselves.

Also, while I agree we could just document and warn the user about it, I'm not so keen to leave to the user this It will be integral part of the export functionality and already now I'm seeing A LOT of issues or questions where reading the docs would have simply solved it... so I don't trust that some user would deliberately read the docs just to set something in order for distrobox to work 😅

I have to agree on this. Most of users don't read documentation, I see this all the time.

A suggestion I'd like to make then:

  • We could open a feature request to improve the install/uninstall scripts where we can discuss overall improvements and keep track of progress. A more interactive process for the installation perhaps could solve one thing or two, etc etc. But this would be for the long run so extensive testing could be done.
  • I see Add home prefix #422 and Experiment/library #430 PRs already doing some heavy lifting. I really like the idea to modularize the scripts into functions by the way, it's more systematic and better to handle errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants