hyprland: expose cacheable package set

This commit is contained in:
2026-05-29 23:13:40 -07:00
parent 29a0af4bde
commit b8cbf387fa
4 changed files with 450 additions and 26 deletions

View File

@@ -1,15 +1,23 @@
name: Build and Push Cachix (imalison-taffybar)
name: Build and Push Cachix
on:
push:
branches: [master]
paths:
- "dotfiles/config/taffybar/**"
- "dotfiles/config/hypr/**"
- "dotfiles/lib/bin/hypr_*"
- "dotfiles/lib/bin/hypr*"
- "nixos/**"
- ".github/workflows/cachix.yml"
pull_request:
branches: [master]
paths:
- "dotfiles/config/taffybar/**"
- "dotfiles/config/hypr/**"
- "dotfiles/lib/bin/hypr_*"
- "dotfiles/lib/bin/hypr*"
- "nixos/**"
- ".github/workflows/cachix.yml"
workflow_dispatch: {}
@@ -87,3 +95,12 @@ jobs:
--no-link \
--print-build-logs \
./dotfiles/config/taffybar#defaultPackage.x86_64-linux
- name: Build Hyprland stuff
run: |
set -euxo pipefail
nix build \
--no-link \
--print-build-logs \
./nixos#hyprland-stuff \
--override-input railbird-secrets path:./nixos/ci/railbird-secrets-stub

View File

@@ -0,0 +1,408 @@
{
pkgs,
inputs,
lib ? pkgs.lib,
hyprlandConfigDir ? ../../dotfiles/config/hypr,
}: let
system = pkgs.stdenv.hostPlatform.system;
hyprlandInput = inputs.hyprland;
hyprlandInputPkgs = import hyprlandInput.inputs.nixpkgs {inherit system;};
makeHyprlandGlaze = glaze:
(glaze.override {
enableSIMD = false;
}).overrideAttrs (old: {
cmakeFlags =
(old.cmakeFlags or [])
++ [
"-Dglaze_DEVELOPER_MODE=OFF"
"-Dglaze_ENABLE_FUZZING=OFF"
"-DBUILD_TESTING=OFF"
];
});
avoidHyprlandGccIce = glaze: package:
(package.override {
stdenv = pkgs.clangStdenv;
}).overrideAttrs (old: {
buildInputs =
map
(input:
if (input.pname or null) == "glaze"
then makeHyprlandGlaze glaze
else input)
(old.buildInputs or []);
});
avoidOverlayHyprlandGccIce = final: package:
(package.override {
stdenv = final.clangStdenv;
}).overrideAttrs (old: {
buildInputs =
map
(input:
if (input.pname or null) == "glaze"
then makeHyprlandGlaze final.glaze
else input)
(old.buildInputs or []);
});
hyprlandGccIceOverlay = final: prev: {
glaze = makeHyprlandGlaze prev.glaze;
hyprland = avoidOverlayHyprlandGccIce final prev.hyprland;
hyprland-unwrapped = final.hyprland.override {wrapRuntimeDeps = false;};
hyprland-with-tests = final.hyprland.override {withTests = true;};
};
# GCC 15.2 ICEs while compiling Hyprland 0.55 on this pin. Keep the
# Hyprland/plugin pin set intact and build Hyprland itself with Clang.
baseHyprlandPackage = (avoidHyprlandGccIce hyprlandInputPkgs.glaze hyprlandInput.packages.${system}.hyprland).overrideAttrs (_: {
# Clang 21 can segfault in LLVM's Live DEBUG_VALUE analysis while compiling
# ConfigValues.cpp when this build runs in parallel.
enableParallelBuilding = false;
});
hyprlandPluginsForBase = pkgs.callPackage "${pkgs.path}/pkgs/applications/window-managers/hyprwm/hyprland-plugins" {
hyprland = baseHyprlandPackage;
};
cleanupStaleGraphicalSession = pkgs.writeShellScript "cleanup-stale-graphical-session" ''
set -u
# Only clean targets that are plainly stale. If a compositor is still
# running, let the active session own its own shutdown path.
if ${pkgs.procps}/bin/pgrep -u "$(${pkgs.coreutils}/bin/id -u)" -f '(^|/)(Hyprland|\.Hyprland-wrapped|river|kwin_wayland)( |$)' >/dev/null 2>&1; then
exit 0
fi
${pkgs.systemd}/bin/systemctl --user stop \
hyprland-session.target \
river-xmonad-session.target \
graphical-session.target \
graphical-session-pre.target \
tray.target \
2>/dev/null || true
${pkgs.systemd}/bin/systemctl --user unset-environment \
WAYLAND_DISPLAY \
DISPLAY \
XAUTHORITY \
HYPRLAND_INSTANCE_SIGNATURE \
XDG_CURRENT_DESKTOP \
XDG_SESSION_DESKTOP \
XDG_SESSION_TYPE \
IMALISON_SESSION_TYPE \
IMALISON_WINDOW_MANAGER \
2>/dev/null || true
${pkgs.systemd}/bin/systemctl --user reset-failed 2>/dev/null || true
'';
makeHyprlandLuaPackage = package:
(pkgs.symlinkJoin {
name = "${package.name}-lua-config";
inherit (package) version;
paths = [package];
meta =
builtins.removeAttrs (package.meta or {}) ["outputsToInstall"]
// {
mainProgram = package.meta.mainProgram or "Hyprland";
};
passthru =
(package.passthru or {})
// {
providedSessions = package.passthru.providedSessions or ["hyprland"];
};
postBuild = ''
mkdir -p "$out/bin" "$out/share/wayland-sessions"
printf '%s\n' \
'#!${pkgs.runtimeShell}' \
'nvidia_drm_device="/dev/dri/by-path/pci-0000:01:00.0-card"' \
'intel_drm_device="/dev/dri/by-path/pci-0000:00:02.0-card"' \
'if [ -e "$nvidia_drm_device" ] && [ -e "$intel_drm_device" ]; then' \
' export AQ_DRM_DEVICES="$nvidia_drm_device:$intel_drm_device"' \
'fi' \
'config_path="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr/hyprland.lua"' \
'exec "${package}/bin/start-hyprland" --path "${package}/bin/Hyprland" -- --config "$config_path" "$@"' \
> "$out/bin/start-hyprland-lua"
chmod +x "$out/bin/start-hyprland-lua"
printf '%s\n' \
'#!${pkgs.runtimeShell}' \
'${cleanupStaleGraphicalSession}' \
'exec ${pkgs.uwsm}/bin/uwsm start -g -1 -e -D Hyprland hyprland.desktop' \
> "$out/bin/start-hyprland-uwsm-clean"
chmod +x "$out/bin/start-hyprland-uwsm-clean"
rm -f "$out/share/wayland-sessions/hyprland.desktop"
substitute \
"${package}/share/wayland-sessions/hyprland.desktop" \
"$out/share/wayland-sessions/hyprland.desktop" \
--replace-fail \
"Exec=${package}/bin/start-hyprland" \
"Exec=$out/bin/start-hyprland-lua"
rm -f "$out/share/wayland-sessions/hyprland-uwsm.desktop"
substitute \
"${package}/share/wayland-sessions/hyprland-uwsm.desktop" \
"$out/share/wayland-sessions/hyprland-uwsm.desktop" \
--replace-fail \
"Exec=uwsm start -e -D Hyprland hyprland.desktop" \
"Exec=$out/bin/start-hyprland-uwsm-clean"
'';
})
// {
override = {enableXWayland ? true, ...} @ args:
makeHyprlandLuaPackage (package.override args);
overrideAttrs = f: makeHyprlandLuaPackage (package.overrideAttrs f);
};
hyprlandPackage = makeHyprlandLuaPackage baseHyprlandPackage;
enableHyprglass = false;
hyprglass = pkgs.callPackage ../packages/hyprglass {
src = inputs.hyprglass;
hyprland = baseHyprlandPackage;
aquamarine = inputs.aquamarine.packages.${system}.aquamarine;
hyprcursor = inputs.hyprcursor.packages.${system}.hyprcursor;
hyprgraphics = inputs.hyprgraphics.packages.${system}.hyprgraphics;
hyprlang = inputs.hyprlang.packages.${system}.hyprlang;
hyprutils = inputs.hyprutils.packages.${system}.hyprutils;
};
hyprwobbly = (pkgs.callPackage "${inputs.hyprwobbly}/default.nix" {}).overrideAttrs (old: {
patches =
(old.patches or [])
++ [
../packages/hyprwobbly-safe-geometry-and-idle-timer.patch
];
});
hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo;
hyprwinview = hyprlandPluginsForBase.mkHyprlandPlugin {
pluginName = "hyprwinview";
version = "0.1.0";
src = inputs.hyprwinview;
inherit (baseHyprlandPackage) nativeBuildInputs;
buildInputs = [pkgs.librsvg];
meta = {
description = "A window overview plugin for Hyprland";
homepage = "https://github.com/colonelpanic8/hyprwinview";
license = lib.licenses.bsd3;
platforms = lib.platforms.linux;
};
};
hyprWorkspaceHistory = hyprlandPluginsForBase.mkHyprlandPlugin {
pluginName = "hypr-workspace-history";
version = "0.1.0";
src = inputs.hypr-workspace-history;
inherit (baseHyprlandPackage) nativeBuildInputs;
meta = {
description = "Workspace history cycling plugin for Hyprland";
homepage = "https://github.com/colonelpanic8/hypr-workspace-history";
license = lib.licenses.bsd3;
platforms = lib.platforms.linux;
};
};
hyprtasking = pkgs.gcc14Stdenv.mkDerivation {
pname = "hyprtasking";
version = "0.1.0-unstable-${inputs.hyprtasking.shortRev or "dirty"}";
src = inputs.hyprtasking;
strictDeps = true;
nativeBuildInputs =
[
pkgs.pkg-config
pkgs.meson
pkgs.ninja
]
++ baseHyprlandPackage.nativeBuildInputs;
buildInputs = [baseHyprlandPackage] ++ baseHyprlandPackage.buildInputs;
meta = {
description = "Powerful workspace management plugin for Hyprland";
homepage = "https://github.com/raybbian/hyprtasking";
license = lib.licenses.bsd3;
platforms = lib.platforms.linux;
};
};
hyprDynamicCursors = pkgs.gcc14Stdenv.mkDerivation {
pname = "hypr-dynamic-cursors";
version = "0-unstable-${inputs.hypr-dynamic-cursors.shortRev or "dirty"}";
src = inputs.hypr-dynamic-cursors;
strictDeps = true;
nativeBuildInputs =
baseHyprlandPackage.nativeBuildInputs
++ [
baseHyprlandPackage
pkgs.pkg-config
];
buildInputs = [(lib.getDev baseHyprlandPackage)] ++ baseHyprlandPackage.buildInputs;
dontConfigure = true;
dontUseCmakeConfigure = true;
dontUseMesonConfigure = true;
dontUseNinjaBuild = true;
dontUseNinjaInstall = true;
buildPhase = ''
runHook preBuild
make
runHook postBuild
'';
installPhase = ''
runHook preInstall
install -Dm755 out/dynamic-cursors.so "$out/lib/libhypr-dynamic-cursors.so"
runHook postInstall
'';
meta = {
description = "A plugin to make Hyprland cursor movement more realistic";
homepage = "https://github.com/VirtCode/hypr-dynamic-cursors";
license = lib.licenses.bsd3;
platforms = lib.platforms.linux;
};
};
hyprNStack = pkgs.stdenv.mkDerivation {
pname = "hyprNStack";
version = "0-unstable-${inputs.hyprNStack.shortRev or "dirty"}";
src = inputs.hyprNStack;
strictDeps = true;
nativeBuildInputs = [
pkgs.pkg-config
];
buildInputs =
[
baseHyprlandPackage
]
++ baseHyprlandPackage.buildInputs;
dontStrip = true;
installPhase = ''
runHook preInstall
install -Dm755 nstackLayoutPlugin.so "$out/lib/libhyprNStack.so"
runHook postInstall
'';
meta = {
description = "N-stack layout plugin for Hyprland";
homepage = "https://github.com/zakk4223/hyprNStack";
license = lib.licenses.bsd3;
platforms = baseHyprlandPackage.meta.platforms;
};
};
hyprlandPluginPackages =
[
hyprNStack
hyprexpo
hyprwinview
hyprWorkspaceHistory
hyprtasking
hyprDynamicCursors
hyprwobbly
]
++ lib.optionals enableHyprglass [hyprglass];
llvmNmCompat = pkgs.writeShellApplication {
name = "llvm-nm";
runtimeInputs = [pkgs.binutils];
text = ''
exec nm "$@"
'';
};
hyprRofiWindow = pkgs.writeShellApplication {
name = "hypr_rofi_window";
runtimeInputs = [
pkgs.python3
pkgs.rofi
hyprlandPackage
];
text = ''
exec python3 ${../../dotfiles/lib/bin/hypr_rofi_window} "$@"
'';
};
hyprShellUi = pkgs.writeShellApplication {
name = "hypr_shell_ui";
runtimeInputs = [
pkgs.rofi
hyprRofiWindow
];
text = ''
exec ${../../dotfiles/lib/bin/hypr_shell_ui} "$@"
'';
};
hyprRofiLayout = pkgs.writeShellApplication {
name = "hypr_rofi_layout";
runtimeInputs = [
pkgs.coreutils
pkgs.findutils
pkgs.gawk
pkgs.rofi
hyprlandPackage
];
text = ''
exec ${../../dotfiles/lib/bin/hypr_rofi_layout} "$@"
'';
};
hyprRofiAction = pkgs.writeShellApplication {
name = "hypr_rofi_action";
runtimeInputs = [
pkgs.libnotify
pkgs.python3
pkgs.rofi
hyprlandPackage
];
text = ''
exec python3 ${../../dotfiles/lib/bin/hypr_rofi_action} "$@"
'';
};
hyprlandConfigSyntax = import ../checks/hyprland-config-syntax {
inherit pkgs hyprlandConfigDir;
};
hyprlandStuffPaths =
[
hyprlandPackage
llvmNmCompat
hyprRofiLayout
hyprRofiAction
hyprRofiWindow
hyprShellUi
]
++ hyprlandPluginPackages;
hyprlandStuffPathStrings = map builtins.toString (hyprlandStuffPaths ++ [hyprlandConfigSyntax]);
hyprlandStuff = pkgs.symlinkJoin {
name = "imalison-hyprland-stuff";
paths = hyprlandStuffPaths;
postBuild = ''
mkdir -p "$out/nix-support"
printf '%s\n' ${lib.escapeShellArgs hyprlandStuffPathStrings} > "$out/nix-support/hyprland-store-paths"
'';
passthru = {
inherit
baseHyprlandPackage
hyprlandPackage
hyprlandPluginPackages
hyprlandConfigSyntax
;
};
meta = {
description = "Ivan Malison's Hyprland package, plugins, scripts, and Lua config syntax check";
platforms = lib.platforms.linux;
};
};
in {
inherit
baseHyprlandPackage
cleanupStaleGraphicalSession
hyprDynamicCursors
hyprNStack
hyprRofiAction
hyprRofiLayout
hyprRofiWindow
hyprShellUi
hyprWorkspaceHistory
hyprglass
hyprlandConfigSyntax
hyprlandGccIceOverlay
hyprlandPackage
hyprlandPluginPackages
hyprlandStuff
hyprtasking
hyprwinview
hyprwobbly
hyprexpo
llvmNmCompat
;
}

View File

@@ -17,16 +17,9 @@
inherit pkgs system;
inherit inputs;
};
hyprglass = pkgs.callPackage ../packages/hyprglass {
src = inputs.hyprglass;
hyprland = inputs.hyprland.packages.${system}.hyprland;
aquamarine = inputs.aquamarine.packages.${system}.aquamarine;
hyprcursor = inputs.hyprcursor.packages.${system}.hyprcursor;
hyprgraphics = inputs.hyprgraphics.packages.${system}.hyprgraphics;
hyprlang = inputs.hyprlang.packages.${system}.hyprlang;
hyprutils = inputs.hyprutils.packages.${system}.hyprutils;
hyprlandStuffPackages = import ./hyprland-stuff.nix {
inherit pkgs inputs lib;
};
hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo;
tangledConfig = dotfilesOrgApi.org-agenda-custom-config;
# Import container build logic
@@ -42,11 +35,13 @@ in {
kat-org-agenda-api = containerLib.containers.kat;
}
// lib.optionalAttrs pkgs.stdenv.isLinux {
hyprNStack = inputs.hyprNStack.packages.${system}.hyprNStack;
hyprexpo-lua = hyprexpo;
hyprwinview = inputs.hyprwinview.packages.${system}.hyprwinview;
hypr-workspace-history = inputs.hypr-workspace-history.packages.${system}.hypr-workspace-history;
inherit hyprglass;
hyprland-stuff = hyprlandStuffPackages.hyprlandStuff;
hyprland-lua = hyprlandStuffPackages.hyprlandPackage;
hyprNStack = hyprlandStuffPackages.hyprNStack;
hyprexpo-lua = hyprlandStuffPackages.hyprexpo;
hyprwinview = hyprlandStuffPackages.hyprwinview;
hypr-workspace-history = hyprlandStuffPackages.hyprWorkspaceHistory;
hyprglass = hyprlandStuffPackages.hyprglass;
};
checks =
@@ -60,15 +55,13 @@ in {
'';
}
// lib.optionalAttrs pkgs.stdenv.isLinux {
hyprNStack = inputs.hyprNStack.packages.${system}.hyprNStack;
hyprexpo-lua = hyprexpo;
hyprwinview = inputs.hyprwinview.packages.${system}.hyprwinview;
hypr-workspace-history = inputs.hypr-workspace-history.packages.${system}.hypr-workspace-history;
inherit hyprglass;
hyprland-config-syntax = import ../checks/hyprland-config-syntax {
inherit pkgs;
hyprlandConfigDir = ../../dotfiles/config/hypr;
};
hyprNStack = hyprlandStuffPackages.hyprNStack;
hyprexpo-lua = hyprlandStuffPackages.hyprexpo;
hyprwinview = hyprlandStuffPackages.hyprwinview;
hypr-workspace-history = hyprlandStuffPackages.hyprWorkspaceHistory;
hyprglass = hyprlandStuffPackages.hyprglass;
hyprland-config-syntax = hyprlandStuffPackages.hyprlandConfigSyntax;
hyprland-stuff = hyprlandStuffPackages.hyprlandStuff;
# Hyprland 0.54 currently segfaults in --verify-config before it can
# validate even an empty config in this environment. Keep coverage in
# hyprland-config-syntax until the upstream verifier is usable again.

View File

@@ -1,6 +1,12 @@
switch-substituters := "https://cache.nixos.org https://cache.nixos-cuda.org https://cuda-maintainers.cachix.org https://ai.cachix.org https://nix-community.cachix.org https://numtide.cachix.org https://colonelpanic8-dotfiles.cachix.org https://taffybar.cachix.org https://codex-cli.cachix.org https://claude-code.cachix.org"
switch-trusted-public-keys := "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= cache.nixos-cuda.org:74DUi4Ye579gUqzH4ziL9IyiJBlDpMRn9MBN8oNan9M= cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E= ai.cachix.org-1:N9dzRK+alWwoKXQlnn0H6aUx0lU/mspIoz8hMvGvbbc= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= numtide.cachix.org-1:2ps1kLBUWjxIneOy1Ik6cQjb41X0iXVXeHigGmycPPE= colonelpanic8-dotfiles.cachix.org-1:O6GF3nptpeMFapX29okzO92eSWXR36zqW6ZF2C8P0eQ= taffybar.cachix.org-1:beZotJ1nVEsAnJxa3lWn0zwzZM7oeXmGh4ADRpHeeIo= codex-cli.cachix.org-1:1Br3H1hHoRYG22n//cGKJOk3cQXgYobUel6O8DgSing= claude-code.cachix.org-1:YeXf2aNu7UTX8Vwrze0za1WEDS+4DuI2kVeWEE4fsRk="
switch *args:
case "$(systemctl show -P ActiveState nixos-upgrade.service 2>/dev/null)" in active|activating|reloading) /run/wrappers/bin/sudo systemctl stop nixos-upgrade.service;; esac
/run/wrappers/bin/sudo nixos-rebuild switch --flake ".#" --impure {{args}}
/run/wrappers/bin/sudo nixos-rebuild switch --flake ".#" --impure --option substituters '{{switch-substituters}}' --option trusted-public-keys '{{switch-trusted-public-keys}}' {{args}}
populate-cachix cache="colonelpanic8-dotfiles" host=`hostname` *args:
store_path="$(nix build --no-link --print-out-paths ".#nixosConfigurations.{{host}}.config.system.build.toplevel" --impure --option warn-dirty false {{args}})" && cachix push {{cache}} "$store_path
store_path="$(nix build --no-link --print-out-paths ".#nixosConfigurations.{{host}}.config.system.build.toplevel" --impure --option warn-dirty false {{args}})" && cachix push {{cache}} "$store_path"
publish-hyprland-cachix cache="colonelpanic8-dotfiles" *args:
store_paths="$(nix build --no-link --print-out-paths ".#hyprland-stuff" --option warn-dirty false {{args}})" && cachix push {{cache}} $store_paths