{ description = "hypr-chrome dev shell and package"; # A single nixpkgs input, deliberately not a separate `hyprland` flake # input — Hyprland plugins are ABI-locked to the exact Hyprland build # they're loaded into (hyprctl plugin load checks a build-hash), so both # the dev shell and the packaged plugin below build against `pkgs.hyprland` # from THIS SAME input, guaranteeing they match each other. Pinned to the # exact revision terra's homelab flake currently locks for nixos-26.05 for # this developer's own standalone `nix develop`/`nix build` — consumers # packaging this for their own system should instead set # `inputs.hypr-chrome.inputs.nixpkgs.follows = "nixpkgs"` (their own # system's nixpkgs input) so it builds against whatever Hyprland their # system actually runs, for the same ABI-hash reason. inputs.nixpkgs.url = "github:NixOS/nixpkgs/241313f4e8e508cb9b13278c2b0fa25b9ca27163"; outputs = { self, nixpkgs }: let system = "x86_64-linux"; pkgs = import nixpkgs { inherit system; }; # Read from .env (also read by CMakeLists.txt) rather than a separate # hardcoded string, so .gitea/workflows/version-bump.yml only ever has # to touch that one file for both build systems to stay in sync. pluginVersion = let envLines = pkgs.lib.splitString "\n" (builtins.readFile ./.env); versionLine = pkgs.lib.findFirst (pkgs.lib.hasPrefix "PLUGIN_VERSION=") null envLines; in pkgs.lib.removePrefix "PLUGIN_VERSION=" versionLine; in { # Build with Hyprland's own stdenv (not nixpkgs' default one) so the # compiler/libstdc++ ABI matches what Hyprland itself was built with. packages.${system}.default = pkgs.hyprland.stdenv.mkDerivation { pname = "hypr-chrome"; version = pluginVersion; src = self; nativeBuildInputs = [ pkgs.cmake pkgs.pkg-config ]; # Mirrors nixpkgs' own hyprlandPlugins.mkHyprlandPlugin: relying on # pkgs.hyprland alone isn't enough for pkg-config to resolve its # transitive Requires (aquamarine, hyprutils, cairo, etc.) - its own # buildInputs have to be pulled in explicitly too. buildInputs = [ pkgs.hyprland ] ++ pkgs.hyprland.buildInputs; # CMakeLists.txt installs the plain "hypr-chrome.so" name that # hyprctl/hyprpm/buildAndLoad.sh all expect outside of Nix - rename # to the lib.so convention here, Nix-packaging-only, so # home-manager's `wayland.windowManager.hyprland.plugins` can derive # the plugin path from this package directly instead of a consumer # having to hardcode `${package}/lib/hypr-chrome.so` themselves. postInstall = '' mv "$out/lib/hypr-chrome.so" "$out/lib/libhypr-chrome.so" ''; meta = { description = "Draws a chamfered HUD-style border frame with a title bar around each window."; homepage = "https://git.mgaction.town/darman/hypr-chrome"; platforms = pkgs.lib.platforms.linux; }; }; devShells.${system}.default = pkgs.mkShell { # hyprland.pc pulls in aquamarine/hyprcursor/hyprlang/hyprutils/ # hyprgraphics/hyprland-protocols/libdrm/libinput/systemd(libudev)/ # wayland/libxkbcommon/libglvnd(egl)/cairo/libxcb-wm(xcb-icccm)/ # xcbutilerrors transitively; none of those default to their `dev` # output, so they're listed explicitly. glslang isn't in hyprland.pc's # Requires at all (ShaderLoader.hpp just expects it on the include # path) — Nix's cc-wrapper picks it up automatically from being in # this list, no pkg-config entry needed. All of this was verified by # actually building hypr-chrome.so and `hyprctl plugin load`-ing # it into a live Hyprland session. packages = with pkgs; [ cmake gnumake pkg-config hyprland.dev aquamarine.dev hyprcursor.dev hyprlang.dev hyprutils.dev hyprgraphics.dev hyprland-protocols glslang.dev libdrm.dev libinput.dev systemd.dev pixman wayland.dev libxkbcommon.dev libglvnd.dev cairo.dev libxcb-wm.dev xcbutilerrors.dev ]; }; }; }