Automatically launching alacritty using nixGL

Hi!

I’m on PopOS with an AMD graphics card, so neither the alacritty nor alacritty-graphics packages work for me out of the box when installed using nix profile add nixpkgs#alacritty-graphics. (They simply refuse to launch.)

I installed nixGL using nix profile install github:guibou/nixGL --impure. This allows me to successfully launch alacritty using the command nixGL alacritty at the terminal. However, hopefully you see the circular dependency here, and I would like to be able to launch it using the cosmic-launcher, as normal.

As far as I understand, this means that I need to change the last line of ~/.nix-profile/share/applications/alacritty.desktop from Exec=alacritty to Exec=nixGL alacritty. However, like all files managed by Nix, this is a read-only symlink into the nix store, so it cannot be manually modified.

The approach that I’m trying to use to tackle this problem is by creating a flake that defines an overlay that adds a preInstall script that modifies that last line using substituteInPlace.

Here’s what I have so far:
flake.nix

{
  description = "Installs a modified alacritty that uses nixGL.";

  inputs = {
      nixpkgs.url = "https://releases.nixos.org/nixos/25.11/nixos-25.11.4506.078d69f03934";
      nixgl.url = "github:nix-community/nixGL";
  };

  outputs = { self, nixpkgs, nixgl, alacritty }:
    let
      system = "x86_64-linux";
      pkgs = import nixpkgs {
        inherit system;
        overlays = [ self.overlays.default ];
        config = { };
      };
    in
    {
      packages.${system}.alacritty = pkgs.alacritty;
      packages.${system}.nixgl = pkgs.nixGL;

      overlays.default = import ./overlay.nix;
    };
}

overlay.nix

final: prev: {
  alacritty = prev.alacritty-graphics.overrideAttrs (oldAttrs: {
    preInstall = ''
      substituteInPlace extra/linux/Alacritty.desktop \
      --replace 'Exec=alacritty' 'Exec=nixGL alacritty'
    '';
    });
  ];
}

However, when I try to install this overlay using nix profile add . inside the directory that contains both of the above files, I get this error:

error:
       … while updating the lock file of flake 'git+file:///home/rahzael/Git/alacritty-nixGL-patch'

       … while updating the flake input 'alacritty'

       error: cannot find flake 'flake:alacritty' in the flake registries

So for some reason it doesn’t seem to be able to grab alacritty from nixpkgs?

What am I missing here?

You don’t have an alacritty flake input. Get rid of that from there.

1 Like

That helped, thanks!

There was a couple of other things wrong, but I was able to get them straightened out.

The final files:
flake.nix

{
  description = "Installs a modified alacritty that uses nixGL.";

  inputs = {
      nixpkgs.url = "https://channels.nixos.org/nixos-26.05/nixexprs.tar.xz";
      nixgl.url = "github:nix-community/nixGL";
  };

  outputs = { self, nixpkgs, nixgl }:
    let
      system = "x86_64-linux";
      pkgs = import nixpkgs {
        inherit system;
        overlays = [ self.overlays.default ];
        config = { };
      };
    in
    {
      packages.${system}.alacritty = pkgs.alacritty;

      overlays.default = import ./overlay.nix;
    };
}

overlay.nix

final: prev: {
  alacritty = prev.alacritty-graphics.overrideAttrs (oldAttrs: {
    preInstall = ''
      substituteInPlace extra/linux/Alacritty.desktop \
      --replace 'Exec=alacritty' 'Exec=nixGL alacritty'
    '';
    });
}

I then had to install it using nix profile add .#alacritty, but now it works! Huzzah!

I can finally use alacritty + nvim without getting double keystrokes on enter, tab, and backspace! :joy:

For the record, you could save yourself recompiling all of alactritty by just writing a new .desktop file with e.g. pkgs.writeTextDirectory and combining it with the alacritty package using buildEnv.

Or straight-up manually writing a new .desktop file in ~/.local/share/applications; any .desktop files placed there will take priority over ones further down in $XDG_DATA_DIRS.

2 Likes

Okay. Is there a reason why adding a postInstall script triggers a new compilation? Shouldn’t that be after the compilation phase?

Or does nixpkgs/hydra not cache the build artifacts after each step?

Any changes to any attribute or input of a derivation will result in a full rebuild of the package. That’s nix’s intended design (and the only reason it works).

Hence, overriding a package to add a custom desktop file in generally wouldn’t make sense.

If each step of the derivation is a pure function, why can’t you cache the inputs/outputs of each step and only build what changed?

It’s not, what makes you think that?

But if you think otherwise, make a better nix I guess :slight_smile:

It’s a functional language?
Isn’t that what pure is supposed to mean?

No, it’s bash, which is not a functional language.

The phases are part of stdenv which is nixpkgs-specific, btw.

But if you think otherwise, make a better nix I guess :slight_smile:

I mean, I am working on a Lisp dialect, but I think it’ll be a while until it’s anywhere near ready to even attempt to start using it as a build system. XD

No, it’s bash, which is not a functional language.

The phases are part of stdenv which is nixpkgs-specific, btw.

Ah, I see.

I think my point still stands, regardless. Is there any reason to assume that adding a postInstallation script would at all change the result of the previous compilation steps?

Is there something I’m missing there?

I.e. is there a reason why every build step couldn’t be treated as it’s own mini-derivation that takes the result of the previous steps as input and returns the result of applying the current build step to that input as output?

1 Like

Store paths aren’t modifiable after realization, and the only thing that ends up in the store is under $out*. So if you have a bunch of stuff in the build dir it will get lost between every step and somehow needs preserving. Seems like a lot of unnecessary overhead for little benefit. That’s why you as the developer have to make the call about where the derivation boundaries lie (and that’s why @TLATER suggested creating a new derivation manually).

*Or whatever other outputs you specify.

2 Likes