Compare commits

...
Author SHA1 Message Date
765b46f831
make walker use system theme 2026-10-20 13:26:02 -04:00
625f3e7358
bump deps 2026-10-20 13:25:26 -04:00
ad5bfb2262
bump deps, mitigate CA leakage 2026-10-20 12:46:57 -04:00
9 changed files with 395 additions and 167 deletions

View file

@ -40,8 +40,15 @@ in
# Take keyboard focus when opened, so you can type into the search straight away
environment.etc."xdg/walker/config.toml".source = (pkgs.formats.toml { }).generate "walker.toml" {
force_keyboard_focus = true;
theme = "system";
};
# The default theme, minus its hardcoded @define-color palette, so the GTK theme's colors show through
environment.etc."xdg/walker/themes/system/style.css".source =
pkgs.runCommand "walker-system-style.css" { } ''
sed '/^@define-color/d' ${pkgs.walker.src}/resources/themes/default/style.css > $out
'';
environment.etc.${filename}.source = (pkgs.formats.toml { }).generate "config.toml" {
autostart = [ session-programs ];
@ -149,7 +156,6 @@ in
patches = (old.patches or [ ]) ++ [
./resize-tiled-windows.patch
./lone-modifier.patch
./scroll-accumulation.patch
];
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ];

View file

@ -1,132 +0,0 @@
--- a/src/state.rs
+++ b/src/state.rs
@@ -719,6 +719,9 @@
pub seat: Seat<State>,
pub keyboard: KeyboardHandle<State>,
pub pointer: PointerHandle<State>,
+ // Accumulated high-resolution scroll (in 1/120ths of a wheel notch), horizontal then vertical,
+ // for scroll bindings, so that they trigger once per notch rather than once per event.
+ pub scroll_binding_accumulator: (f64, f64),
pub clock: Clock<Monotonic>,
pub suppressed_keys: HashMap<u32, (KeyPattern, KeyAction)>,
// We store both the timer and the keysym used to trigger the key action.
@@ -967,6 +970,7 @@
seat_state,
keyboard,
pointer,
+ scroll_binding_accumulator: (0.0, 0.0),
mapped_layer_surfaces: HashMap::new(),
lock_state: LockState::Unlocked,
focused_on_demand_layer_shell: None,
--- a/src/input/mod.rs
+++ b/src/input/mod.rs
@@ -569,56 +569,41 @@
let mut handled = false;
// Check vertical axis bindings using discrete amounts
- if let Some(discrete) = vertical_amount_discrete {
- if discrete > 0.0 {
- let mouse_pattern = fht_compositor_config::MousePattern(
- modifiers,
- fht_compositor_config::MouseInput::Axis(
- fht_compositor_config::MouseAxis::WheelUp,
- ),
- );
- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
- self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial());
- handled = true;
- }
- } else if discrete < 0.0 {
- let mouse_pattern = fht_compositor_config::MousePattern(
- modifiers,
- fht_compositor_config::MouseInput::Axis(
- fht_compositor_config::MouseAxis::WheelDown,
- ),
- );
- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
+ if let Some(discrete) = vertical_amount_discrete.filter(|discrete| *discrete != 0.0) {
+ let mouse_axis = if discrete > 0.0 {
+ fht_compositor_config::MouseAxis::WheelUp
+ } else {
+ fht_compositor_config::MouseAxis::WheelDown
+ };
+ let mouse_pattern = fht_compositor_config::MousePattern(
+ modifiers,
+ fht_compositor_config::MouseInput::Axis(mouse_axis),
+ );
+ if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
+ handled = true;
+ if accumulate_scroll(&mut self.fht.scroll_binding_accumulator.1, discrete) {
self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial());
- handled = true;
}
}
}
// Check horizontal axis bindings using discrete amounts
if !handled {
- if let Some(discrete) = horizontal_amount_discrete {
- if discrete > 0.0 {
- let mouse_pattern = fht_compositor_config::MousePattern(
- modifiers,
- fht_compositor_config::MouseInput::Axis(
- fht_compositor_config::MouseAxis::WheelRight,
- ),
- );
- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
- self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial());
- handled = true;
- }
- } else if discrete < 0.0 {
- let mouse_pattern = fht_compositor_config::MousePattern(
- modifiers,
- fht_compositor_config::MouseInput::Axis(
- fht_compositor_config::MouseAxis::WheelLeft,
- ),
- );
- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
+ if let Some(discrete) = horizontal_amount_discrete.filter(|discrete| *discrete != 0.0)
+ {
+ let mouse_axis = if discrete > 0.0 {
+ fht_compositor_config::MouseAxis::WheelRight
+ } else {
+ fht_compositor_config::MouseAxis::WheelLeft
+ };
+ let mouse_pattern = fht_compositor_config::MousePattern(
+ modifiers,
+ fht_compositor_config::MouseInput::Axis(mouse_axis),
+ );
+ if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
+ handled = true;
+ if accumulate_scroll(&mut self.fht.scroll_binding_accumulator.0, discrete) {
self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial());
- handled = true;
}
}
}
@@ -1079,6 +1064,25 @@
}
}
+/// Accumulate high-resolution scroll for a scroll binding.
+///
+/// High-resolution wheels send several events per notch, each with part of the 120 units of a
+/// notch, so we accumulate them and only trigger the binding once per full notch. Returns whether
+/// the binding should trigger.
+fn accumulate_scroll(accumulated: &mut f64, v120: f64) -> bool {
+ if accumulated.signum() != v120.signum() {
+ // Changed direction, start over
+ *accumulated = 0.0;
+ }
+ *accumulated += v120;
+ if accumulated.abs() >= 120.0 {
+ *accumulated -= 120.0 * accumulated.signum();
+ true
+ } else {
+ false
+ }
+}
+
/// Returns `true` if a VT switch key has been handled.
fn handle_vt_switch(backend: &mut Backend, key_state: KeyState, modified: Keysym) -> bool {
if key_state == KeyState::Released {

View file

@ -5,7 +5,7 @@
...
}:
let
s3Domain = "http://127.0.0.1${config.services.minio.listenAddress}";
s3Domain = "http://127.0.0.1${config.services.minio-vendored.listenAddress}";
cfg = config.services.lasuite-docs;
in
{
@ -76,7 +76,7 @@ in
environmentFile = config.age.secrets."lasuiteSecrets.age".path;
};
minio = {
minio-vendored = {
enable = true;
rootCredentialsFile = config.age.secrets."minioCredentials.age".path;
};
@ -135,5 +135,6 @@ in
nixpkgs.config.permittedInsecurePackages = [
"minio-2025-10-15T17-29-55Z"
"minio-client-2025-08-13T08-35-41Z"
];
}

View file

@ -0,0 +1,317 @@
# MinIO package and module, vendored from nixpkgs 6510408d147d8c5e6d76043e899e9251756f6a75
# (nixos/modules/services/web-servers/minio.nix and pkgs/by-name/mi/minio/package.nix), since
# both were removed upstream because MinIO was abandoned. Only here until lasuite-docs is
# migrated to another S3 server.
#
# Changes from upstream:
# - The option is `services.minio-vendored`, since nixpkgs still reserves `services.minio` to
# show a removal message. The unit, user and paths are unchanged, so existing data keeps working.
# - The package is defined here, as `pkgs.minio` now throws, and without `passthru.tests`, as
# `nixosTests.minio` was removed too.
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.services.minio-vendored;
minio = pkgs.callPackage (
{
lib,
buildGoModule,
fetchFromGitHub,
}:
let
# The web client verifies, that the server version is a valid datetime string:
# https://github.com/minio/minio/blob/3a0e7347cad25c60b2e51ff3194588b34d9e424c/browser/app/js/web.js#L51-L53
#
# Example:
# versionToTimestamp "2021-04-22T15-44-28Z"
# => "2021-04-22T15:44:28Z"
versionToTimestamp =
version:
let
splitTS = builtins.elemAt (builtins.split "(.*)(T.*)" version) 1;
in
builtins.concatStringsSep "" [
(builtins.elemAt splitTS 0)
(builtins.replaceStrings [ "-" ] [ ":" ] (builtins.elemAt splitTS 1))
];
# CopyrightYear will be printed to the CLI UI.
# Example:
# versionToYear "2021-04-22T15-44-28Z"
# => "2021"
versionToYear = version: builtins.elemAt (lib.splitString "-" version) 0;
in
buildGoModule (finalAttrs: {
pname = "minio";
version = "2025-10-15T17-29-55Z";
src = fetchFromGitHub {
owner = "minio";
repo = "minio";
rev = "RELEASE.${finalAttrs.version}";
hash = "sha256-HbjmCJYkWyRRHKriLP6QohaXYLk3QEVfi32Krq3ujjo=";
};
vendorHash = "sha256-BFnTJE9QFWmPsx90hDTG8MusdnwaBPYJxM5bCFk3hew=";
doCheck = false;
subPackages = [ "." ];
env.CGO_ENABLED = 0;
tags = [ "kqueue" ];
ldflags =
let
t = "github.com/minio/minio/cmd";
in
[
"-s"
"-w"
"-X ${t}.Version=${versionToTimestamp finalAttrs.version}"
"-X ${t}.CopyrightYear=${versionToYear finalAttrs.version}"
"-X ${t}.ReleaseTag=RELEASE.${finalAttrs.version}"
"-X ${t}.CommitID=${finalAttrs.src.rev}"
];
meta = {
homepage = "https://www.minio.io/";
description = "S3-compatible object storage server";
changelog = "https://github.com/minio/minio/releases/tag/RELEASE.${finalAttrs.version}";
maintainers = with lib.maintainers; [
bachp
ryan4yin
];
license = lib.licenses.agpl3Plus;
mainProgram = "minio";
knownVulnerabilities = [
"CVE-2026-40344: MinIO has an Unauthenticated Object Write via Missing Signature Verification in Unsigned-Trailer Uploads"
"CVE-2026-41145: Unauthenticated Object Write via Query-String Credential Signature Bypass in Unsigned-Trailer Uploads"
"CVE-2026-33322: JWT Algorithm Confusion in OIDC Authentication"
"CVE-2026-33419: LDAP login brute-force via user enumeration and missing rate limit"
"CVE-2026-34204: SSE Metadata Injection via Replication Headers"
"CVE-2026-39414: DoS via Unbounded Memory Allocation in S3 Select CSV Parsing"
"minio has been abandoned by upstream and security issues won't be fixed. Users should migrate to alternatives such as Garage, SeaweedFS, or Ceph. S3-compatible clients such as rclone can be used to move data."
];
};
})
) { };
legacyCredentials =
cfg:
pkgs.writeText "minio-legacy-credentials" ''
MINIO_ROOT_USER=${cfg.accessKey}
MINIO_ROOT_PASSWORD=${cfg.secretKey}
'';
in
{
options.services.minio-vendored = {
enable = mkEnableOption "Minio Object Storage";
listenAddress = mkOption {
default = ":9000";
type = types.str;
description = "IP address and port of the server.";
};
consoleAddress = mkOption {
default = ":9001";
type = types.str;
description = "IP address and port of the web UI (console).";
};
dataDir = mkOption {
default = [ "/var/lib/minio/data" ];
type = types.listOf (types.either types.path types.str);
description = "The list of data directories or nodes for storing the objects. Use one path for regular operation and the minimum of 4 endpoints for Erasure Code mode.";
};
configDir = mkOption {
default = "/var/lib/minio/config";
type = types.path;
description = "The config directory, for the access keys and other settings.";
};
certificatesDir = mkOption {
default = "/var/lib/minio/certs";
type = types.path;
description = "The directory where TLS certificates are stored.";
};
accessKey = mkOption {
default = "";
type = types.str;
description = ''
Access key of 5 to 20 characters in length that clients use to access the server.
This overrides the access key that is generated by minio on first startup and stored inside the
`configDir` directory.
'';
};
secretKey = mkOption {
default = "";
type = types.str;
description = ''
Specify the Secret key of 8 to 40 characters in length that clients use to access the server.
This overrides the secret key that is generated by minio on first startup and stored inside the
`configDir` directory.
'';
};
rootCredentialsFile = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
File containing the MINIO_ROOT_USER, default is "minioadmin", and
MINIO_ROOT_PASSWORD (length >= 8), default is "minioadmin"; in the format of
an EnvironmentFile=, as described by {manpage}`systemd.exec(5)`.
'';
example = "/etc/nixos/minio-root-credentials";
};
region = mkOption {
default = "us-east-1";
type = types.str;
description = ''
The physical location of the server. By default it is set to us-east-1, which is same as AWS S3's and Minio's default region.
'';
};
browser = mkOption {
default = true;
type = types.bool;
description = "Enable or disable access to web UI.";
};
package = mkOption {
type = types.package;
default = minio;
defaultText = literalMD "MinIO 2025-10-15T17-29-55Z, vendored above";
description = "The MinIO package to use.";
};
};
config = mkIf cfg.enable {
warnings =
optional ((cfg.accessKey != "") || (cfg.secretKey != ""))
"services.minio-vendored.`accessKey` and services.minio-vendored.`secretKey` are deprecated, please use services.minio-vendored.`rootCredentialsFile` instead.";
systemd = lib.mkMerge [
{
tmpfiles.rules = [
"d '${cfg.configDir}' - minio minio - -"
]
++ (map (x: "d '" + x + "' - minio minio - - ") (builtins.filter lib.types.path.check cfg.dataDir));
services.minio = {
description = "Minio Object Storage";
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/minio server --json --address ${cfg.listenAddress} --console-address ${cfg.consoleAddress} --config-dir=${cfg.configDir} --certs-dir=${cfg.certificatesDir} ${toString cfg.dataDir}";
Type = "simple";
User = "minio";
Group = "minio";
LimitNOFILE = 65536;
EnvironmentFile =
if (cfg.rootCredentialsFile != null) then
cfg.rootCredentialsFile
else if ((cfg.accessKey != "") || (cfg.secretKey != "")) then
(legacyCredentials cfg)
else
null;
# hardening
DevicePolicy = "closed";
CapabilityBoundingSet = "";
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_NETLINK"
"AF_UNIX"
];
DeviceAllow = "";
NoNewPrivileges = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
MemoryDenyWriteExecute = true;
LockPersonality = true;
RemoveIPC = true;
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
];
ProtectProc = "invisible";
ProtectHostname = true;
UMask = "0077";
# minio opens /proc/mounts on startup
ProcSubset = "all";
};
environment = {
MINIO_REGION = "${cfg.region}";
MINIO_BROWSER = "${if cfg.browser then "on" else "off"}";
};
};
}
(lib.mkIf (cfg.rootCredentialsFile != null) {
# The service will fail if the credentials file is missing
services.minio.unitConfig.ConditionPathExists = cfg.rootCredentialsFile;
# The service will not restart if the credentials file has
# been changed. This can cause stale root credentials.
paths.minio-root-credentials = {
wantedBy = [ "multi-user.target" ];
pathConfig = {
PathChanged = [ cfg.rootCredentialsFile ];
Unit = "minio-restart.service";
};
};
services.minio-restart = {
description = "Restart MinIO";
script = ''
systemctl restart minio.service
'';
serviceConfig = {
Type = "oneshot";
Restart = "on-failure";
RestartSec = 5;
};
};
})
];
users.users.minio = {
group = "minio";
uid = config.ids.uids.minio;
};
users.groups.minio.gid = config.ids.uids.minio;
};
}

73
flake.lock generated
View file

@ -23,11 +23,11 @@
]
},
"locked": {
"lastModified": 1790734419,
"narHash": "sha256-n7wew722m1OTBT9DOIMxNX/NF4zfsSUABAO5eW3wikE=",
"lastModified": 1792507013,
"narHash": "sha256-8tKjSQajD3mUND1GaAuaWTcuyUpgcGsh5V+l4ibzC7U=",
"owner": "ryantm",
"repo": "agenix",
"rev": "3daa710894355fa2fad8243380af373a2b4046ef",
"rev": "5e5b88a0c8e56f291a108c2fe9934054d9745b2e",
"type": "github"
},
"original": {
@ -163,11 +163,11 @@
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1792171958,
"narHash": "sha256-ZpJe7MK24KnEfpbC4IsKzl1MLusbcDB3PB1SaFd0GSI=",
"lastModified": 1792473472,
"narHash": "sha256-kGZbWSNyp7DWhSo1DmF83LVxp/Gp/4qHXuylJgE7UO4=",
"ref": "refs/heads/main",
"rev": "b0a5caf57606b34baa94afc5f348d0484f5c0f3b",
"revCount": 7962,
"rev": "2f93711a0969bb858fe5faa032c683096c82c333",
"revCount": 7964,
"type": "git",
"url": "https://forgejo.ellis.link/continuwuation/continuwuity"
},
@ -241,11 +241,11 @@
]
},
"locked": {
"lastModified": 1789770686,
"narHash": "sha256-uZkBR7yHdIKUFB5SZdfgh1qkGfI3XmYmI/lTiquxbck=",
"lastModified": 1792505528,
"narHash": "sha256-BsLGrgqKJg2o9IsjU4Xvzo8RZV9Fn1GajEasifBwqsI=",
"owner": "nix-community",
"repo": "disko",
"rev": "725ea35e410ad83be4931d1bff7e090eacaf3563",
"rev": "7fdf779611daf0e250889cb27e4f1f602147a8f2",
"type": "github"
},
"original": {
@ -306,11 +306,11 @@
"rust-overlay": []
},
"locked": {
"lastModified": 1792507568,
"narHash": "sha256-RGXq8SkxpxU0TaMk3oXbJ5SwkRDY90tvN2zIiofAVMQ=",
"lastModified": 1792509123,
"narHash": "sha256-beuuyEmQTfgLd7smvvSeVhsLF5wBgPnUeCeJpd2QD+M=",
"owner": "nferhat",
"repo": "fht-compositor",
"rev": "458dc48d96aa6d8aa0b834a8052f33c09700ffe8",
"rev": "a9b6a8cc2714288b3f5b2752ea7871eee21e927b",
"type": "github"
},
"original": {
@ -322,11 +322,11 @@
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1791905368,
"narHash": "sha256-K8fIXFKovw6zOwWE96wKRyADLB+vIkf+rVGPUqdSd1g=",
"lastModified": 1792416163,
"narHash": "sha256-0M5/QfbfHwI7gP+q6IGdidxl5caGXMaEalNj2E2Rxyg=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "6841588955c23c8fc0f3e067fe1a1009113f7fd2",
"rev": "fdc1af075073f93dc63e43b28a499b2251bcfcc2",
"type": "github"
},
"original": {
@ -724,11 +724,11 @@
]
},
"locked": {
"lastModified": 1792098797,
"narHash": "sha256-u4DIIZgznEGzByxXrxWCXK19VcMtTBmi/M9gZ7Jk9bM=",
"lastModified": 1792495086,
"narHash": "sha256-TyoYH983Nsc++1scw0SoOEKshPSJWJDxK7tTmuZ974M=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "640725978b99076e18e069f6e7d2959124584f8f",
"rev": "ec80131710bffcdf3b8498cf41f3a0579833b023",
"type": "github"
},
"original": {
@ -800,11 +800,11 @@
]
},
"locked": {
"lastModified": 1792268367,
"narHash": "sha256-CsB/G1ut2CossRJ2dWg1G/RI1DA6F2F/qUcYT3ovk6k=",
"lastModified": 1792459113,
"narHash": "sha256-boQ5vhKJyoQJsozBrFVTJGiKXxcApJnc0tPdwT5iBRo=",
"ref": "refs/heads/main",
"rev": "a6fe80fea294588fee8bfeb319bed70d2160bb8b",
"revCount": 1052,
"rev": "a2906746b9273f04833a1bdea36d8ffc87b2c2ec",
"revCount": 1066,
"submodules": true,
"type": "git",
"url": "https://git.federated.nexus/Nexus/nexus"
@ -1043,11 +1043,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1791956154,
"narHash": "sha256-jBYGPi4udQ9uo4KQp9m2J0546nJVQitG15gvZSaVVAs=",
"lastModified": 1792210252,
"narHash": "sha256-Mh0PUaIv4nFY+8wAGonaEh8iBzwsmdNlwjVHmFg1Biw=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "55bfb4d7437bd4e09ab7cba58a43bd68eb310044",
"rev": "09063bd1f2b36fd9fd793c36dfade7bd40a93dfc",
"type": "github"
},
"original": {
@ -1123,6 +1123,7 @@
"sable": "sable",
"sable-next": "sable-next",
"stylix": "stylix",
"v4l2loopback-package": "v4l2loopback-package",
"wrapper-manager": "wrapper-manager"
}
},
@ -1213,11 +1214,11 @@
]
},
"locked": {
"lastModified": 1792276809,
"narHash": "sha256-ocLR3Nn5LaZflG1wZeslUwDt7Roh5kg9ZEQ9FTV13e4=",
"lastModified": 1792505713,
"narHash": "sha256-gYLowB8hLLje3rKZhLhB0VZhUqgOOgDG3HYYaWa+fUU=",
"ref": "refs/heads/main",
"rev": "0cb286a792f23f2506d5c973c074386f79d9a9f7",
"revCount": 6380,
"rev": "ef92a87d1ead6859518b532c5e4cd02e91046d99",
"revCount": 6528,
"type": "git",
"url": "https://git.sable.moe/SableClient/sable-next"
},
@ -1469,6 +1470,18 @@
"type": "github"
}
},
"v4l2loopback-package": {
"flake": false,
"locked": {
"narHash": "sha256-Jel7EbTuktyhriWtL3u9P5+4ADP0FqGjgkcE2uVgPbo=",
"type": "file",
"url": "https://raw.githubusercontent.com/moni-dz/nixpkgs/v4l2loopback-depmod/pkgs/os-specific/linux/v4l2loopback/default.nix"
},
"original": {
"type": "file",
"url": "https://raw.githubusercontent.com/moni-dz/nixpkgs/v4l2loopback-depmod/pkgs/os-specific/linux/v4l2loopback/default.nix"
}
},
"wrapper-manager": {
"locked": {
"lastModified": 1788355120,

View file

@ -88,6 +88,11 @@
url = "file+https://raw.githubusercontent.com/j0hax/nixpkgs/lk-jwt-service-restructure/nixos/modules/services/matrix/lk-jwt-service.nix";
flake = false;
};
# TODO: remove once https://github.com/NixOS/nixpkgs/pull/575861 is merged
v4l2loopback-package = {
url = "file+https://raw.githubusercontent.com/moni-dz/nixpkgs/v4l2loopback-depmod/pkgs/os-specific/linux/v4l2loopback/default.nix";
flake = false;
};
};
outputs =

View file

@ -0,0 +1,11 @@
{
security.pki.caCertificateBlacklist = [
# CVE-2026-111943
"Comodo AAA Services root"
# https://hg-edge.mozilla.org/projects/nss/rev/26d38a0c3fb81e7fb2acedbaf4c42dd21dce0517
"emSign ECC Root CA - G3"
# https://hg-edge.mozilla.org/projects/nss/rev/8159223c48ceeb1273a1915bca95a517294ab0e0
"emSign Root CA - C1"
"emSign ECC Root CA - C3"
];
}

View file

@ -1,8 +1,15 @@
{ pkgs, ... }:
{ pkgs, inputs, ... }:
{
programs.obs-studio = {
enable = true;
plugins = with pkgs.obs-studio-plugins; [ obs-pipewire-audio-capture ];
enableVirtualCamera = true;
};
# TODO: remove once https://github.com/NixOS/nixpkgs/pull/575861 is merged
boot.kernelPackages = pkgs.linuxPackages.extend (
final: _: {
v4l2loopback = final.callPackage inputs.v4l2loopback-package.outPath { };
}
);
}

View file

@ -53,7 +53,7 @@
plugins = [
"github.com/ggicci/caddy-jwt@v1.3.0"
];
hash = "sha256-NagDw+U1aV+NgW+gx5Sr996ZUEHZefuFIfDPu2bsD0Q=";
hash = "sha256-59TJxJMOuVzS5H9jmo3+esDFP1HLI1ov+BGC5ozgDuA=";
};
globalConfig = ''