feat: add Nix flake with dev shell, package, and NixOS/Home Manager modules
Reproducible development environment for NixOS/Nix contributors: - Dev shell with Node 22, system Electron, Playwright, LD_LIBRARY_PATH for X11/Wayland/audio libs, activated automatically via direnv - buildNpmPackage derivation wrapping system Electron with desktop file and hicolor icons - NixOS module (programs.openscreen.enable) with xdg-desktop-portal - Home Manager module for per-user installation - Overlay for composing with other flakes Tested: nix flake show, nix develop, nix build, nixos-rebuild switch
This commit is contained in:
@@ -34,3 +34,8 @@ playwright-report/
|
|||||||
|
|
||||||
# Vitest browser mode screenshots
|
# Vitest browser mode screenshots
|
||||||
__screenshots__/
|
__screenshots__/
|
||||||
|
|
||||||
|
# Nix
|
||||||
|
result
|
||||||
|
result-*
|
||||||
|
.direnv/
|
||||||
Generated
+27
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1775710090,
|
||||||
|
"narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "4c1018dae018162ec878d42fec712642d214fdfa",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
{
|
||||||
|
description = "OpenScreen — desktop screen recorder with built-in editor";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{ self, nixpkgs }:
|
||||||
|
let
|
||||||
|
systems = [
|
||||||
|
"x86_64-linux"
|
||||||
|
"aarch64-linux"
|
||||||
|
];
|
||||||
|
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# -- Per-system outputs (packages, dev shells) --
|
||||||
|
|
||||||
|
packages = forAllSystems (pkgs: {
|
||||||
|
openscreen = pkgs.callPackage ./nix/package.nix { };
|
||||||
|
default = self.packages.${pkgs.stdenv.hostPlatform.system}.openscreen;
|
||||||
|
});
|
||||||
|
|
||||||
|
devShells = forAllSystems (
|
||||||
|
pkgs:
|
||||||
|
let
|
||||||
|
electron = pkgs.electron;
|
||||||
|
|
||||||
|
# Libraries Electron needs at runtime on Linux
|
||||||
|
runtimeLibs = with pkgs; [
|
||||||
|
# X11
|
||||||
|
libx11
|
||||||
|
libxcomposite
|
||||||
|
libxdamage
|
||||||
|
libxext
|
||||||
|
libxfixes
|
||||||
|
libxrandr
|
||||||
|
libxtst
|
||||||
|
libxcb
|
||||||
|
libxshmfence
|
||||||
|
|
||||||
|
# Wayland
|
||||||
|
wayland
|
||||||
|
|
||||||
|
# GTK / UI toolkit
|
||||||
|
gtk3
|
||||||
|
glib
|
||||||
|
pango
|
||||||
|
cairo
|
||||||
|
gdk-pixbuf
|
||||||
|
atk
|
||||||
|
at-spi2-atk
|
||||||
|
at-spi2-core
|
||||||
|
|
||||||
|
# Graphics
|
||||||
|
mesa
|
||||||
|
libGL
|
||||||
|
libdrm
|
||||||
|
vulkan-loader
|
||||||
|
|
||||||
|
# Networking / crypto (NSS for Chromium)
|
||||||
|
nss
|
||||||
|
nspr
|
||||||
|
|
||||||
|
# Audio
|
||||||
|
alsa-lib
|
||||||
|
pipewire
|
||||||
|
pulseaudio
|
||||||
|
|
||||||
|
# System
|
||||||
|
dbus
|
||||||
|
cups
|
||||||
|
expat
|
||||||
|
libnotify
|
||||||
|
libsecret
|
||||||
|
util-linux # libuuid
|
||||||
|
];
|
||||||
|
in
|
||||||
|
{
|
||||||
|
default = pkgs.mkShell {
|
||||||
|
packages = with pkgs; [
|
||||||
|
nodejs_22
|
||||||
|
electron
|
||||||
|
|
||||||
|
# Native module compilation
|
||||||
|
python3
|
||||||
|
pkg-config
|
||||||
|
gcc
|
||||||
|
|
||||||
|
# Playwright browser tests
|
||||||
|
playwright-driver.browsers
|
||||||
|
];
|
||||||
|
|
||||||
|
# Electron's prebuilt binary needs these at runtime
|
||||||
|
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath runtimeLibs;
|
||||||
|
|
||||||
|
# Tell the npm `electron` package to use the Nix-provided binary
|
||||||
|
# instead of downloading its own. vite-plugin-electron respects this.
|
||||||
|
ELECTRON_OVERRIDE_DIST_PATH = "${electron}/lib/electron";
|
||||||
|
|
||||||
|
# Playwright browser path for test:browser / test:e2e
|
||||||
|
PLAYWRIGHT_BROWSERS_PATH = "${pkgs.playwright-driver.browsers}";
|
||||||
|
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = "1";
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
echo "OpenScreen dev shell — node $(node --version), electron v$(electron --version 2>/dev/null | tr -d 'v')"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
# -- System-wide outputs (modules, overlay) --
|
||||||
|
|
||||||
|
overlays.default = final: _prev: {
|
||||||
|
openscreen = self.packages.${final.stdenv.hostPlatform.system}.openscreen;
|
||||||
|
};
|
||||||
|
|
||||||
|
nixosModules.default = import ./nix/module.nix self;
|
||||||
|
homeManagerModules.default = import ./nix/hm-module.nix self;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# Home Manager module for OpenScreen
|
||||||
|
# Usage in flake-based Home Manager config:
|
||||||
|
#
|
||||||
|
# inputs.openscreen.url = "github:siddharthvaddem/openscreen";
|
||||||
|
#
|
||||||
|
# { inputs, ... }: {
|
||||||
|
# imports = [ inputs.openscreen.homeManagerModules.default ];
|
||||||
|
# programs.openscreen.enable = true;
|
||||||
|
# }
|
||||||
|
self:
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.programs.openscreen;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.programs.openscreen = {
|
||||||
|
enable = lib.mkEnableOption "OpenScreen screen recorder";
|
||||||
|
|
||||||
|
package = lib.mkOption {
|
||||||
|
type = lib.types.package;
|
||||||
|
default = self.packages.${pkgs.stdenv.hostPlatform.system}.openscreen;
|
||||||
|
defaultText = lib.literalExpression "inputs.openscreen.packages.\${pkgs.stdenv.hostPlatform.system}.openscreen";
|
||||||
|
description = "The OpenScreen package to use.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
home.packages = [ cfg.package ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# NixOS module for OpenScreen
|
||||||
|
# Usage in flake-based NixOS config:
|
||||||
|
#
|
||||||
|
# inputs.openscreen.url = "github:siddharthvaddem/openscreen";
|
||||||
|
#
|
||||||
|
# { inputs, ... }: {
|
||||||
|
# imports = [ inputs.openscreen.nixosModules.default ];
|
||||||
|
# programs.openscreen.enable = true;
|
||||||
|
# }
|
||||||
|
self:
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.programs.openscreen;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.programs.openscreen = {
|
||||||
|
enable = lib.mkEnableOption "OpenScreen screen recorder";
|
||||||
|
|
||||||
|
package = lib.mkOption {
|
||||||
|
type = lib.types.package;
|
||||||
|
default = self.packages.${pkgs.stdenv.hostPlatform.system}.openscreen;
|
||||||
|
defaultText = lib.literalExpression "inputs.openscreen.packages.\${pkgs.stdenv.hostPlatform.system}.openscreen";
|
||||||
|
description = "The OpenScreen package to use.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
|
# Screen capture on Wayland requires xdg-desktop-portal.
|
||||||
|
# We enable the base portal; users should also enable a
|
||||||
|
# desktop-specific portal (e.g. xdg-desktop-portal-gtk,
|
||||||
|
# xdg-desktop-portal-hyprland) in their DE config.
|
||||||
|
xdg.portal.enable = lib.mkDefault true;
|
||||||
|
};
|
||||||
|
}
|
||||||
+130
@@ -0,0 +1,130 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
buildNpmPackage,
|
||||||
|
nodejs_22,
|
||||||
|
electron,
|
||||||
|
makeWrapper,
|
||||||
|
makeDesktopItem,
|
||||||
|
copyDesktopItems,
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildNpmPackage {
|
||||||
|
nodejs = nodejs_22;
|
||||||
|
pname = "openscreen";
|
||||||
|
version = "1.3.0";
|
||||||
|
|
||||||
|
src =
|
||||||
|
let
|
||||||
|
fs = lib.fileset;
|
||||||
|
maybe = fs.maybeMissing;
|
||||||
|
in
|
||||||
|
fs.toSource {
|
||||||
|
root = ../.;
|
||||||
|
fileset = fs.difference ../. (
|
||||||
|
fs.unions [
|
||||||
|
../nix
|
||||||
|
../flake.nix
|
||||||
|
../flake.lock
|
||||||
|
(maybe ../release)
|
||||||
|
(maybe ../test-results)
|
||||||
|
(maybe ../playwright-report)
|
||||||
|
(maybe ../.github)
|
||||||
|
(maybe ../.vscode)
|
||||||
|
(maybe ../.idea)
|
||||||
|
(maybe ../.kiro)
|
||||||
|
(maybe ../.envrc)
|
||||||
|
(maybe ../.direnv)
|
||||||
|
(fs.fileFilter (file: file.hasExt "md") ../.)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
npmDepsHash = "sha256-Pd6J9TuggA9vM4s/LjdoK4MoBEivSzAWc/G2+pFOM2U=";
|
||||||
|
|
||||||
|
env.ELECTRON_SKIP_BINARY_DOWNLOAD = "1";
|
||||||
|
|
||||||
|
# electron-builder is not needed — we wrap system electron directly
|
||||||
|
npmFlags = [ "--ignore-scripts" ];
|
||||||
|
makeCacheWritable = true;
|
||||||
|
|
||||||
|
# vite-plugin-electron compiles electron/ sources into dist-electron/
|
||||||
|
# tsconfig has noEmit — tsc is type-check only
|
||||||
|
buildPhase = ''
|
||||||
|
runHook preBuild
|
||||||
|
npx vite build
|
||||||
|
runHook postBuild
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
mkdir -p "$out/lib/openscreen"
|
||||||
|
|
||||||
|
# Renderer build output (index.html, JS chunks, copied public/ assets)
|
||||||
|
cp -r dist "$out/lib/openscreen/"
|
||||||
|
|
||||||
|
# Main process + preload (compiled by vite-plugin-electron)
|
||||||
|
cp -r dist-electron "$out/lib/openscreen/"
|
||||||
|
|
||||||
|
# Package manifest (electron reads "main" field to find entry point)
|
||||||
|
cp package.json "$out/lib/openscreen/"
|
||||||
|
|
||||||
|
# Strip devDependencies (electron, vitest, biome, playwright, etc.)
|
||||||
|
npm prune --omit=dev --no-save
|
||||||
|
cp -r node_modules "$out/lib/openscreen/"
|
||||||
|
|
||||||
|
# Asset resolution: when app.isPackaged is false, the main process resolves
|
||||||
|
# assets at <appPath>/public/assets/. Mirror the electron-builder
|
||||||
|
# extraResources layout so wallpapers load correctly.
|
||||||
|
mkdir -p "$out/lib/openscreen/public/assets"
|
||||||
|
cp -r public/wallpapers "$out/lib/openscreen/public/assets/wallpapers"
|
||||||
|
|
||||||
|
# Wrap system electron with the app directory
|
||||||
|
mkdir -p "$out/bin"
|
||||||
|
makeWrapper "${electron}/bin/electron" "$out/bin/openscreen" \
|
||||||
|
--add-flags "$out/lib/openscreen" \
|
||||||
|
--set ELECTRON_IS_DEV 0
|
||||||
|
|
||||||
|
# Install icons to hicolor theme
|
||||||
|
for size in 16 24 32 48 64 128 256 512 1024; do
|
||||||
|
icon="icons/icons/png/''${size}x''${size}.png"
|
||||||
|
if [ -f "$icon" ]; then
|
||||||
|
install -Dm644 "$icon" \
|
||||||
|
"$out/share/icons/hicolor/''${size}x''${size}/apps/openscreen.png"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
makeWrapper
|
||||||
|
copyDesktopItems
|
||||||
|
];
|
||||||
|
|
||||||
|
desktopItems = [
|
||||||
|
(makeDesktopItem {
|
||||||
|
name = "openscreen";
|
||||||
|
desktopName = "OpenScreen";
|
||||||
|
genericName = "Screen Recorder";
|
||||||
|
exec = "openscreen %U";
|
||||||
|
icon = "openscreen";
|
||||||
|
comment = "Desktop screen recorder with built-in editor";
|
||||||
|
categories = [
|
||||||
|
"AudioVideo"
|
||||||
|
"Video"
|
||||||
|
"Recorder"
|
||||||
|
];
|
||||||
|
startupWMClass = "Openscreen";
|
||||||
|
terminal = false;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Desktop screen recorder with built-in editor";
|
||||||
|
homepage = "https://github.com/siddharthvaddem/openscreen";
|
||||||
|
license = lib.licenses.mit;
|
||||||
|
mainProgram = "openscreen";
|
||||||
|
platforms = lib.platforms.linux;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user