I want to edit .desktop files of some nixpkgs for customization, but they are located in /run/current-system/sw/share/applications.. and are readable only.

One possible solution would be to copy them to ~/.local/share/applications but duplicating doesnt sit right with me (this would be my last resort tho).

I would prefer to override the parameters I want to change somehow preferably in my configuration.nix only.

  • Oinks@lemmy.blahaj.zone
    link
    fedilink
    English
    arrow-up
    8
    ·
    edit-2
    20 days ago

    Since the desktop files come directly from a package you’ll need to change the package you’re installing. This works best if you use the postPatch phase of symlinkJoin:

    pkgs.symlinkJoin {
      inherit (pkgs.firefox) pname version;
      paths = [ pkgs.firefox ];
      postPatch = ''
        # String replacement example - will run the app in a terminal
        substituteInPlace "$out/share/applications/firefox.desktop" \
          --replace-fail "Terminal=false" "Terminal=true"
      '';
    }
    

    The reason for using symlinkJoin here is that it creates a package with the same outputs as the original Firefox, but with this bash script having run. You can use this like any other package:

    let
      firefox' = <...>
    in
    {
      environment.systemPackages = [ firefox' ];
      # - or -
      programs.firefox.package = firefox';
    }
    

    Note that symlinkJoin has special handling for postPatch, but ignores all other stdenv phases, so you need to do everything in one bash script. You can use all the parameters for runCommand though, such as buildInputs and nativeBuildInputs - e.g. for compiling sass in a wrapper derivation.

    In some cases it’s useful to also inherit meta or passthru because it’s used in some nixpkgs/nixos sanity checks, but it’s usually not required.

    Another approach would be to use overrideAttrs, which will also work but will cause Nix to rebuild the package from scratch. This might be fine or even desired in some cases, but you probably don’t want to do that in this case.

    • Oinks@lemmy.blahaj.zone
      link
      fedilink
      English
      arrow-up
      5
      ·
      edit-2
      20 days ago

      Another alternative approach would be to add a duplicate desktop file, but to write it declaratively using Home Manager:

      # in home.nix
      home.file.".local/share/applications/firefox.desktop".source =
        pkgs.runCommand "firefox-desktop" { } ''
          cp "${pkgs.firefox}/share/applications/firefox.desktop" "$out"
          substituteInPlace "$out" \
            --replace-fail "Terminal=false" "Terminal=true"
        '';
      
      # - or -
      home.file.".local/share/applications/firefox.desktop".text = ''
        [Desktop Entry]
        Name=Firefox
        Icon=firefox
        Exec=firefox --name firefox %U
      '';
      

      It would be possible to DIY this with user activation scripts, but I don’t really see a value in doing that over the symlinkJoin.

    • Clot@lemmy.zipOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      19 days ago

      Thanks!

      What if I want to append an argument which doesnt already exist? does this also allow to modify multiple lines?

      • Oinks@lemmy.blahaj.zone
        link
        fedilink
        English
        arrow-up
        1
        ·
        edit-2
        19 days ago

        It understands \n if I recall correctly. You can also write regular bash, use templating tools, etc. Just use the nativeBuildInputs parameter if you need a binary that isn’t provided by stdenv.