nix-darwin icon indicating copy to clipboard operation
nix-darwin copied to clipboard

How to add applications so they show up in Applications (or Launchpad search)

Open spease opened this issue 4 years ago • 19 comments

It seems if I add applications in the user configuration file, they end up in ~/Applications rather than in the system Applications. I there a way to add packages to the system so the symlinks will show up in the root Applications, or at least will be searchable with Launchpad?

I couldn't find any "Getting Started" documentation with nix-darwin that would answer this question, but I'm very interested in getting more hands-on experience with the nix ecosystem

spease avatar Aug 06 '20 21:08 spease

@spease It's currently bugged in nix-darwin. There is a workaround at https://github.com/LnL7/nix-darwin/issues/139#issuecomment-666771621. Hopefully it will get a fix soon - it should be easy to make a PR for it.

jsravn avatar Aug 25 '20 09:08 jsravn

Note that the linked comment is about making the apps show up in LaunchPad etc., but they still live in ~/Applications. There was other discussion in that issue about the wider question of /Applications vs. ~/Applications, and a corresponding PR was opened (#153) and later abandoned.

purcell avatar Aug 25 '20 20:08 purcell

I’m not as worried about that particular aspect, it’s more having a GUI app behave ergonomically once it’s included in the environment. I’m installing things for my user profile so far, not the system, so it makes sense to me that they show up in ~ instead of /.

spease avatar Aug 25 '20 23:08 spease

Yeah, moving the system applications out of the home folder would be good.

LnL7 avatar Aug 26 '20 16:08 LnL7

I applied the mentioned patch https://github.com/LnL7/nix-darwin/issues/139#issuecomment-666771621, and can see ~/Applications with the .apps. Spotlight and Launchpad still do not see the apps though. Is that expected? I'm on Catalina if that makes any difference.

wangkev avatar Aug 28 '20 11:08 wangkev

I applied the mentioned patch #139 (comment), and can see ~/Applications with the .apps. Spotlight and Launchpad still do not see the apps though. Is that expected? I'm on Catalina if that makes any difference.

Some applications in ~/Applications (my own derivations) are listed in LaunchPad; however to get Emacs.app to show up in LaunchPad, I had to create the alias in /Applications. I think there must be some metadata that is different WRT Emacs.app, as opposed to other application bundles.

what-the-functor avatar Oct 01 '20 04:10 what-the-functor

I would definitely be in favor of some method for linking system installed GUI apps into /Applications instead of ~/Applications. Finder, Alfred etc can't find symlinks in ~/Applications even if they can be made to show up in Launchpad

webframp avatar Nov 17 '20 21:11 webframp

I have the same issue. There is a symlink of Nix Apps under ~/Applications. In Nix Apps linked folder, there is a Kitty.app symlink. Spotlight doesn't show Kitty.

I did some experiment, it seems the problem is the symlinks. If I copy the Kitty.app file into ~/Applications, it works. Even if I put the Kitty.app symlink in /Applications, Spotlight still doesn't see the app. It seems Spotlight simply doesn't support symlinks.

I'm not sure what is the difference between symlinks and aliases in macOS. But even I tried with aliases, Spotlight doesn't see it either.

leira avatar Jan 20 '22 04:01 leira

Folders symlinked to ~/Applications do not show up in spotlight, and copying them seems like a waste of disk space. Not to mention that it can take a while too if you have a lot of packages.

I found a workaround using APFS aliases, those show up in spotlight and barely take any disk space. Note that aliases dont show up under the "Applications" section of spotlight search, but rather "Other". That makes them have a pretty low priority, so they don't show up as the top option. Might be able to work around that by giving them a tag, which AFAIK moves up their priority.

This is my activation script:

  # Nix-darwin does not link installed applications to the user environment. This means apps will not show up
  # in spotlight, and when launched through the dock they come with a terminal window. This is a workaround.
  # Upstream issue: https://github.com/LnL7/nix-darwin/issues/214
  system.activationScripts.applications.text = lib.mkForce ''
    echo "setting up ~/Applications..." >&2
    applications="$HOME/Applications"
    nix_apps="$applications/Nix Apps"

    # Needs to be writable by the user so that home-manager can symlink into it
    if ! test -d "$applications"; then
        mkdir -p "$applications"
        chown ${username}: "$applications"
        chmod u+w "$applications"
    fi

    # Delete the directory to remove old links
    rm -rf "$nix_apps"
    mkdir -p "$nix_apps"
    find ${config.system.build.applications}/Applications -maxdepth 1 -type l -exec readlink '{}' + |
        while read src; do
            # Spotlight does not recognize symlinks, it will ignore directory we link to the applications folder.
            # It does understand MacOS aliases though, a unique filesystem feature. Sadly they cannot be created
            # from bash (as far as I know), so we use the oh-so-great Apple Script instead.
            /usr/bin/osascript -e "
                set fileToAlias to POSIX file \"$src\" 
                set applicationsFolder to POSIX file \"$nix_apps\"
                tell application \"Finder\"
                    make alias file to fileToAlias at applicationsFolder
                    # This renames the alias; 'mpv.app alias' -> 'mpv.app'
                    set name of result to \"$(rev <<< "$src" | cut -d'/' -f1 | rev)\"
                end tell
            " 1>/dev/null
        done
  '';

I have done something similar for home-manager, which integrates with this just fine.

Commit from my dotfiles: https://github.com/IvarWithoutBones/dotfiles/commit/0b3faad8bd1d0e1af6103caf59b206666ab742f4

IvarWithoutBones avatar Aug 29 '22 19:08 IvarWithoutBones

Folders symlinked to ~/Applications do not show up in spotlight, and copying them seems like a waste of disk space. Not to mention that it can take a while too if you have a lot of packages.

What about taking advantage of APFS's copy-on-write functionality to make a clone of the app bundle? That should avoid wasting resources, and it's as easy as cp -c.

The cloned bundles will have to be deleted and recreated before each update. This may cause issues with apps that store user data within their bundles, though, which is bad practice and uncommon.

hacker1024 avatar Oct 23 '22 23:10 hacker1024

@IvarWithoutBones's solution worked for applications installed with environment.systemPackages, but unfortunately the home-manager version of the script only works on previous home-manager generations' ~/Applications/Home Manager Apps.

I just spent most of my Sunday experimenting with the various already-posted solutions, if anybody wants to catch up on it you can see my comment here

cdmistman avatar Feb 27 '23 01:02 cdmistman

Hi,

I have encountered another issue: when the apps are linked, as now do both nix-darwin and home-manager, file associations don't get updated on switch. That is, when I right-click-open a file with an application, which is linked from the generation X, then switch, and then again right-click-open the same file with the same-name application, the instance from the generation X is picked up, not from the generation X+1. It changes only after manually opening the X+1-generation app.

jcszymansk avatar Jul 26 '23 06:07 jcszymansk

 # Spotlight does not recognize symlinks, it will ignore directory we link to the applications folder.
            # It does understand MacOS aliases though, a unique filesystem feature. Sadly they cannot be created
            # from bash (as far as I know), so we use the oh-so-great Apple Script instead.

Bit late to the party, can confirm using APFS aliases works. You can avoid AppleScript with a tiny ObjC helper:

https://github.com/vs49688/mkalias/blob/master/mkalias.m

vs49688 avatar Nov 15 '23 17:11 vs49688

So, these two snippets work

  # see https://github.com/LnL7/nix-darwin/blob/master/modules/system/activation-scripts.nix
  system.activationScripts.postUserActivation.text = ''
    app_folder="$HOME/Applications/Nix Trampolines"
    rm -rf "$app_folder"
    mkdir -p "$app_folder"
    for app in $(find "${config.system.build.applications}/Applications" -type l); do
        app_target="$app_folder/$(basename $app)"
        real_app="$(readlink $app)"
        echo "mkalias \"$real_app\" \"$app_target\"" >&2
        ${pkgs.mkalias}/bin/mkalias "$real_app" "$app_target"
    done
  '';

home-manager:

  # don't forget to add 'com.apple.alias-file' without quotes into alfred's Extras
  home.activation = {
    aliasHomeManagerApplications = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
      app_folder="${config.home.homeDirectory}/Applications/Home Manager Trampolines"
      rm -rf "$app_folder"
      mkdir -p "$app_folder"
      for app in $(find "$genProfilePath/home-path/Applications" -type l); do
          app_target="$app_folder/$(basename $app)"
          real_app="$(readlink $app)"
          echo "mkalias \"$real_app\" \"$app_target\"" >&2
          $DRY_RUN_CMD ${pkgs.mkalias}/bin/mkalias "$real_app" "$app_target"
      done
    '';
  };

Although there are at least two issues:

  1. Permissions (e.g. Full Disk Access) do not survive package version updates because they are given directly to the apps in nix store
  2. Spotlight depresses the search results and Alfred needs additional configuration to even make the results visible.

pshirshov avatar Apr 10 '24 21:04 pshirshov

There is a supposedly better version of my snippet: https://github.com/nix-community/home-manager/issues/1341#issuecomment-2049723843

pshirshov avatar Apr 11 '24 14:04 pshirshov

Another approach (https://gist.github.com/berryp/7af4a1f534027807b26fff706a61b1ce):

  home.activation = {
    rsync-home-manager-applications = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
      rsyncArgs="--archive --checksum --chmod=-w --copy-unsafe-links --delete"
      apps_source="$genProfilePath/home-path/Applications"
      moniker="Home Manager Trampolines"
      app_target_base="${config.home.homeDirectory}/Applications"
      app_target="$app_target_base/$moniker"
      mkdir -p "$app_target"
      ${pkgs.rsync}/bin/rsync $rsyncArgs "$apps_source/" "$app_target"
    '';
  };
  system.activationScripts.postUserActivation.text = ''
    rsyncArgs="--archive --checksum --chmod=-w --copy-unsafe-links --delete"
    apps_source="${config.system.build.applications}/Applications"
    moniker="Nix Trampolines"
    app_target_base="$HOME/Applications"
    app_target="$app_target_base/$moniker"
    mkdir -p "$app_target"
    ${pkgs.rsync}/bin/rsync $rsyncArgs "$apps_source/" "$app_target"
  '';

pshirshov avatar Apr 11 '24 16:04 pshirshov