diff --git a/chataigne/Chataigne-linux-x64-bleedingedge.AppImage b/chataigne/Chataigne-linux-x64-bleedingedge.AppImage new file mode 100755 index 0000000..3ac48d6 Binary files /dev/null and b/chataigne/Chataigne-linux-x64-bleedingedge.AppImage differ diff --git a/chataigne/chataigne.nix b/chataigne/chataigne.nix new file mode 100644 index 0000000..de6b9cf --- /dev/null +++ b/chataigne/chataigne.nix @@ -0,0 +1,125 @@ +{ pkgs, pinnedPkgs, ... }: + +let + # 1. Define the AppImage source. + appImageSrc = ./Chataigne-linux-x64-bleedingedge.AppImage; + + # 2a. Libraries pulled from the modern, current Nixpkgs (for small size). + modernLibs = with pkgs; [ + alsa-lib + freetype + libglvnd + curl + SDL2 + hidapi + xorg.libXrandr + ]; + + # 2b. Libraries pulled from the older, pinned package set (ONLY the ones that failed). + pinnedCurlLibs = with pinnedPkgs; [ + curlWithGnuTls # This is the critical component for the CURL_GNUTLS_3 symbol. + gnutls + ]; + + # 3. Combine the modern runtime dependencies with the pinned compatibility libraries. + appImageDeps = [ + pkgs.steam-run + pkgs.stdenv.cc.cc.lib # Ensures the modern C++ runtime is available + ] ++ modernLibs ++ pinnedCurlLibs; + + chataigneDesktopItem = { + desktopName = "Chataigne"; + name = "chataigne"; + exec = "chataigne"; # The name of the wrapper script in $out/bin + icon = "chataigne"; # The name of the icon file (without extension) + genericName = "Creative Control Software"; + comment = "Control and experiment with creative applications, hardware, and media."; + categories = [ "AudioVideo" "Development" ]; + }; + +in + +# 4. Create the final runnable derivation +pkgs.stdenv.mkDerivation { + pname = "chataigne-runner"; + version = "1.0"; + + # --- Attributes needed for AppImage running (not compiling) --- + src = ./.; + dontUnpack = true; + dontBuild = true; + # -------------------------------------------------- + + # Inject the combined dependencies into the environment + buildInputs = appImageDeps; + + # The install phase creates an executable wrapper script, extracts the AppImage, + # and now handles the desktop file and icon. + installPhase = '' + mkdir -p $out/bin + + # --- STRATEGY: Extract AppImage contents to bypass FUSE, then fix LD_LIBRARY_PATH --- + echo "Extracting AppImage contents to bypass FUSE requirement..." + + # Use the absolute Nix Store path of the AppImage + ${appImageSrc} --appimage-extract + echo "appimage extracted" + + # 2. Check if extraction worked and move the content to $out + if [ ! -d "squashfs-root" ]; then + echo "Extraction failed. The AppImage may not support --appimage-extract." + exit 1 + fi + + # 2. CRITICAL FIX: Manually create and install the .desktop file + mkdir -p $out/share/applications + + # pkgs.lib.makeDesktopItem takes the metadata and creates a small derivation + # We copy the resulting .desktop file from that derivation's output path ($desktop_file_path) + local desktop_file_path="${pkgs.makeDesktopItem chataigneDesktopItem}" + + # The file is typically named $name.desktop inside the share/applications folder of the new derivation + cp $desktop_file_path/share/applications/chataigne.desktop $out/share/applications/ + + # Copy the extracted contents into the output directory + cp -r squashfs-root $out/ + + # --- DESKTOP ENTRY & ICON (NEW) --- + echo "Processing icon and desktop file..." + + # AppImages usually place the icon in squashfs-root/.DirIcon or similar + # We will assume it's in the root of the extracted content. + local icon_source="$out/squashfs-root/.DirIcon" + local icon_target="$out/share/icons/hicolor/128x128/apps/chataigne.png" # Standard location + + # Use the icon if it exists (AppImages often use a .png or .svg) + if [ -f "$icon_source" ]; then + mkdir -p "$(dirname "$icon_target")" + cp "$icon_source" "$icon_target" + else + echo "Warning: Could not find icon at $icon_source. Using default/no icon." + fi + # ---------------------------------- + + # 3. Create the 'chataigne' executable wrapper + cat > $out/bin/chataigne << EOF +#!${pkgs.stdenv.shell} + +# The LD_LIBRARY_PATH is created using all dependencies (excluding the wrapper 'steam-run'). +# This ensures the AppImage finds the pinned CURL library. +export LD_LIBRARY_PATH="${pkgs.lib.makeLibraryPath (pkgs.lib.remove pkgs.steam-run appImageDeps)}:$LD_LIBRARY_PATH" + +# Use steam-run to launch the main execution script inside the extracted folder. +exec ${pkgs.steam-run}/bin/steam-run "$out/squashfs-root/AppRun" "\$@" +EOF + + chmod +x $out/bin/chataigne + ''; + + meta = { + description = "Declarative runner for the Chataigne AppImage, providing necessary dependencies."; + homepage = "https://chataigne.io/"; # Example: Add the actual homepage + license = pkgs.lib.licenses.unfree; # AppImages are often proprietary/unfree + platforms = [ "x86_64-linux" ]; + }; +} diff --git a/chataigne/flake.nix b/chataigne/flake.nix new file mode 100644 index 0000000..459a45b --- /dev/null +++ b/chataigne/flake.nix @@ -0,0 +1,41 @@ +{ + description = "A flake for running the Chataigne AppImage with necessary patched dependencies."; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; # Modern Nixpkgs + + # Pinned Nixpkgs for compatibility (the commit that fixes the CURL_GNUTLS_3 issue) + pinned-nixpkgs = { + url = "github:NixOS/nixpkgs/5171d7b0a9fbaaf216c873622eb5115b6db97957"; + flake = false; # Treat as a tarball input, not a flake + }; + }; + + outputs = { self, nixpkgs, pinned-nixpkgs, ... }: + let + # Supported systems + supportedSystems = [ "x86_64-linux" ]; + + # The main package definition logic is imported as a function + chataigne-appimage-runner = import ./chataigne.nix; + + # Function to generate the package set for each system + forAllSystems = f: nixpkgs.lib.genAttrs supportedSystems (system: f system); + in + { + packages = forAllSystems (system: + let + pkgs = import nixpkgs { inherit system; config.allowUnfree = true; }; + pinnedPkgs = import pinned-nixpkgs { inherit system; }; + in + { + chataigne = chataigne-appimage-runner { + inherit pkgs pinnedPkgs; + }; + + # Also expose the default package for convenience + default = self.packages.${system}.chataigne; + } + ); + }; +} diff --git a/configuration.nix b/configuration.nix index f2d205f..7619e8f 100644 --- a/configuration.nix +++ b/configuration.nix @@ -124,6 +124,7 @@ waybar hyprlock swaynotificationcenter + inputs.chataigne.packages.${pkgs.system}.chataigne wlogout wpaperd kando diff --git a/flake.lock b/flake.lock index e5595b2..91bc470 100644 --- a/flake.lock +++ b/flake.lock @@ -1,8 +1,23 @@ { "nodes": { - "elephant": { + "chataigne": { "inputs": { "nixpkgs": "nixpkgs", + "pinned-nixpkgs": "pinned-nixpkgs" + }, + "locked": { + "path": "./chataigne", + "type": "path" + }, + "original": { + "path": "./chataigne", + "type": "path" + }, + "parent": [] + }, + "elephant": { + "inputs": { + "nixpkgs": "nixpkgs_2", "systems": "systems" }, "locked": { @@ -20,6 +35,22 @@ } }, "nixpkgs": { + "locked": { + "lastModified": 1763421233, + "narHash": "sha256-Stk9ZYRkGrnnpyJ4eqt9eQtdFWRRIvMxpNRf4sIegnw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "89c2b2330e733d6cdb5eae7b899326930c2c0648", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { "locked": { "lastModified": 1760284886, "narHash": "sha256-TK9Kr0BYBQ/1P5kAsnNQhmWWKgmZXwUQr4ZMjCzWf2c=", @@ -35,7 +66,7 @@ "type": "github" } }, - "nixpkgs_2": { + "nixpkgs_3": { "locked": { "lastModified": 1761907660, "narHash": "sha256-kJ8lIZsiPOmbkJypG+B5sReDXSD1KGu2VEPNqhRa/ew=", @@ -51,7 +82,7 @@ "type": "github" } }, - "nixpkgs_3": { + "nixpkgs_4": { "locked": { "lastModified": 1757068644, "narHash": "sha256-NOrUtIhTkIIumj1E/Rsv1J37Yi3xGStISEo8tZm3KW4=", @@ -67,10 +98,28 @@ "type": "github" } }, + "pinned-nixpkgs": { + "flake": false, + "locked": { + "lastModified": 1708756934, + "narHash": "sha256-WqpheJblJ901Svd5NmLJYLmZ3f4fYLkSOyx9i06+un0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5171d7b0a9fbaaf216c873622eb5115b6db97957", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5171d7b0a9fbaaf216c873622eb5115b6db97957", + "type": "github" + } + }, "root": { "inputs": { + "chataigne": "chataigne", "elephant": "elephant", - "nixpkgs": "nixpkgs_2", + "nixpkgs": "nixpkgs_3", "walker": "walker" } }, @@ -109,7 +158,7 @@ "elephant": [ "elephant" ], - "nixpkgs": "nixpkgs_3", + "nixpkgs": "nixpkgs_4", "systems": "systems_2" }, "locked": { diff --git a/flake.nix b/flake.nix index fcd732e..40d491e 100644 --- a/flake.nix +++ b/flake.nix @@ -4,6 +4,7 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; elephant.url = "github:abenz1267/elephant"; + chataigne.url = "./chataigne"; walker = { url = "github:abenz1267/walker"; @@ -11,7 +12,7 @@ }; }; - outputs = { self, nixpkgs, ... }@inputs: let + outputs = { self, chataigne, nixpkgs, ... }@inputs: let stdenv.hostPlatform.system = "x86_64-linux"; # adjust if needed system = stdenv.hostPlatform.system; hardwareConfig = import /etc/nixos/hardware-configuration.nix; @@ -24,6 +25,9 @@ modules = [ ./configuration.nix hardwareConfig + { + nixpkgs.config.allowUnfree = true; + } ]; }; };