From 4f9475cb9ae516e2f0c335c3d96bdb064a29158d Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Wed, 24 Apr 2024 10:12:03 +0000 Subject: [PATCH] init: workarounds.opengl option The option allows packages to be wrapped by nixgl in order to make GUI applications work when installed with home-manager --- modules/lib/maintainers.nix | 6 +++ modules/misc/opengl.nix | 81 +++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 modules/misc/opengl.nix diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index a2c568633711..cae9bb4c6e18 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -201,6 +201,12 @@ github = "MForster"; githubId = 4067975; }; + michaelCTS = { + name = "michaelCTS"; + email = "michael.vogel@cts.co"; + github = "michaelCTS"; + githubId = 132582212; + }; mifom = { name = "mifom"; email = "mifom@users.noreply.github.com"; diff --git a/modules/misc/opengl.nix b/modules/misc/opengl.nix new file mode 100644 index 000000000000..c983a736e7b7 --- /dev/null +++ b/modules/misc/opengl.nix @@ -0,0 +1,81 @@ +{ config, pkgs, lib, ... }: + +let + nixGL = (import (builtins.fetchTarball + "https://github.com/nix-community/nixGL/archive/main.tar.gz") { + inherit pkgs; + }); + + # Higher order function to create a function that wraps a package + createWrapperFunction = wrapperBinPath: + ( + # Expects a PackageConfiguration hashset + { binary, pkg, ... }: + # Adapted from https://nixos.wiki/wiki/Nix_Cookbook + let bin = if binary == null then pkg.pname else binary; + in pkgs.runCommand "nixgl-${pkg.pname}" { + buildInputs = [ pkgs.makeWrapper ]; + } '' + mkdir $out + # Link every top-level folder from pkgs.hello to our new target + ln -s ${pkg}/* $out + # Except the bin folder + rm $out/bin + mkdir $out/bin + # We create the bin folder ourselves and link every binary in it + ln -s ${pkg}/bin/* $out/bin + # Except the target binary + rm $out/bin/${bin} + # Because we create this ourself, by creating a wrapper + makeWrapper ${wrapperBinPath} $out/bin/${bin} \ + --add-flags ${pkg}/bin/${bin} + ''); + PackageConfiguration = with lib; + types.submodule { + options = { + binary = mkOption { + type = types.nullOr types.str; + example = "alacritty"; + default = null; + description = '' + Name of the binary in bin/ of the package. + By default this uses `package.pname`. + ''; + }; + pkg = mkOption { + type = types.package; + example = "pkgs.alacritty"; + description = '' + The package to be wrapped. + It's expected to have a `pname` attribute. + ''; + }; + }; + }; +in { + meta.maintainers = with lib.maintainers; [ michaelCTS ]; + options.workarounds.opengl = { + wrapperBinPath = lib.mkOption { + type = lib.types.str; + example = "$${nixGL.auto.nixGLDefault}/bin/nixGL"; + default = "${nixGL.auto.nixGLDefault}/bin/nixGL"; + }; + packages = lib.mkOption { + type = lib.types.listOf PackageConfiguration; + default = [ ]; + example = "[{ pkg = pkgs.alacritty; }]"; + description = '' + List of packages that will be wrapped with nixGL in order to be able to use opengl. + Without the wrapper, graphical applications cannot access opengl and thus have no + graphical acceleration. + ''; + }; + }; + + config = { + home.packages = (builtins.map + (createWrapperFunction config.workarounds.opengl.wrapperBinPath) + config.workarounds.opengl.packages); + }; +} +