Compare commits

...

276 Commits

Author SHA1 Message Date
b129321af9 s6-rc: fix service run file to have expected format 2024-03-17 06:09:43 +00:00
a5c36d39f4 modules/users: prototype s6 integration: ~/.config/s6/{sources,compiled} 2024-03-17 05:40:31 +00:00
787e6af646 modules/users: remove unused requiredBy service option 2024-03-17 03:28:59 +00:00
4fd2db4e51 modules: users: split services -> fs mapping into own systemd.nix file 2024-03-16 23:48:30 +00:00
ac04dc639f modules/users: make it a directory 2024-03-16 17:21:34 +00:00
4a2eb7ebec fractal: stop persisting old directories 2024-03-16 12:00:53 +00:00
b8bf763c11 gtkcord4: rename to dissent 2024-03-16 11:17:47 +00:00
b82a31a3ac gnome-keyring: ensure the keyring directory is created before entering the sandbox 2024-03-16 09:21:28 +00:00
c8e5edd61a modules/programs: enforce (or rather document) a stricter schema
this should make it easier to switch to a different service manager
2024-03-16 07:35:54 +00:00
1b4a6207e2 modules/users: refactor to remove inherits 2024-03-16 04:58:21 +00:00
3c43fba878 feeds: add NativLang per Ben's rec 2024-03-14 07:53:19 +00:00
7904957544 give self cap_sys_nice 2024-03-14 07:02:57 +00:00
b25df1d997 sane-sandboxed: fix capabilities example 2024-03-14 01:36:46 +00:00
d08f318e4b pmos: move to correct section 2024-03-13 23:51:24 +00:00
f655c31d77 Merge branch 'dev' 2024-03-13 23:48:48 +00:00
288d57e5d5 feeds: subscribe to pmOS blog 2024-03-13 23:20:45 +00:00
f669f2bfe8 procmail: merged into staging-next 2024-03-13 23:12:37 +00:00
5554ad9fe2 nixpkgs: 2024-03-12 -> 2024-03-13
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/2e2cc05898bbe54a8004801ea300525b231d24e2' (2024-03-12)
  → 'github:nixos/nixpkgs/4ee0840ba2ecc50458ab1677d108afcd691f4815' (2024-03-13)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/21adc4f16a8ab151fec83b9d9368cd62d9de86bc' (2024-03-12)
  → 'github:nixos/nixpkgs/2dbc8f62d8af7a1ab962e4b20d12b25ddcb86ced' (2024-03-13)
• Updated input 'nixpkgs-wayland':
    'github:nix-community/nixpkgs-wayland/0f9388d3a9daa597ad87b870de236fb45e24ba63' (2024-03-12)
  → 'github:nix-community/nixpkgs-wayland/771cb198c281db6918829651f194bf4db32e342d' (2024-03-13)
```
2024-03-13 15:37:50 +00:00
6595d177be gimp: fix sandboxing 2024-03-13 11:36:57 +00:00
d194abb4bf swaync: stylize the actual notifications 2024-03-13 11:29:05 +00:00
eaf45e2366 swaync: re-theme (pink/black) 2024-03-13 11:07:17 +00:00
66e04857b6 swaync: fix dimensions to be compatible with pinephone 2024-03-13 08:29:23 +00:00
fa0dcdc5be swaync: splie style.css out to own file 2024-03-13 08:18:34 +00:00
23b87a283a swaync: move to own directory 2024-03-13 08:17:14 +00:00
849ca59f68 swaync: fix styling of toggle buttons 2024-03-13 08:16:47 +00:00
5e1a6062af swaync: ensure it starts *after* pipewire-pulse so that the mpris plugin can function 2024-03-13 07:53:45 +00:00
8dacb93861 fontconfig: remove no-longer-needed cache; disable Font Awesome (emoji seem well-covered by Noto Color Emoji) 2024-03-13 05:28:57 +00:00
eafabe87c4 xdg-desktop-portal: tell systemd the BusName of the service so that it won't consider it started until after said bus name is acquired
this partially fixes an error in sandboxed gtk apps where they would try to connect to org.freedesktop.portal to query settings, and then fall back to bad default fonts when the endpoint errored (because xdp-gtk wasn't ready)
2024-03-13 05:27:43 +00:00
4510352c07 sane-sandboxed: implement --sane-sandbox-no-portal flag 2024-03-13 04:49:48 +00:00
430592632c sane-sandboxed: add a help message 2024-03-13 04:49:48 +00:00
ac22b36d78 dconf: invoke it ourselves instead of letting dbus do it for us 2024-03-13 04:49:48 +00:00
4439491bf0 dconf: fix over-restrictive sandboxing (because previously it was being run unsandboxed...) 2024-03-13 04:49:48 +00:00
56aca78d84 make-sandboxed: also sandbox the .lib output of a package 2024-03-13 04:49:48 +00:00
546482dc80 dconf: disable GIO_EXTRA_MODULES patch 2024-03-13 02:41:39 +00:00
2f07fff084 dconf: migrate to sane.programs 2024-03-13 02:33:02 +00:00
294563c655 dbus: fix to only search /run/current-system/sw/share/dbus-1 for service files 2024-03-13 02:04:02 +00:00
f6c3557b8c nixpkgs: 2024-03-11 -> 2024-03-12
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/ec7a981885b5ede88eabf9bb3516706107de00b2' (2024-03-11)
  → 'github:nixos/nixpkgs/2e2cc05898bbe54a8004801ea300525b231d24e2' (2024-03-12)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/0fbcc4b2e8571f4af39be41752581ea09dd9ab06' (2024-03-11)
  → 'github:nixos/nixpkgs/21adc4f16a8ab151fec83b9d9368cd62d9de86bc' (2024-03-12)
• Updated input 'nixpkgs-wayland':
    'github:nix-community/nixpkgs-wayland/27a56d7435094f141bf5adfe9cfe155932597935' (2024-03-11)
  → 'github:nix-community/nixpkgs-wayland/0f9388d3a9daa597ad87b870de236fb45e24ba63' (2024-03-12)
• Updated input 'nixpkgs-wayland/lib-aggregate':
    'github:nix-community/lib-aggregate/b8a148b163687c9be602b63c6b0b7bc81eecb015' (2024-03-10)
  → 'github:nix-community/lib-aggregate/45b75bf534592c0c1c881a1c447f7fdb37a87eaf' (2024-03-11)
• Updated input 'nixpkgs-wayland/lib-aggregate/flake-utils':
    'github:numtide/flake-utils/d465f4819400de7c8d874d50b982301f28a84605' (2024-02-28)
  → 'github:numtide/flake-utils/b1d9ab70662946ef0850d488da1c9019f3a9752a' (2024-03-11)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/f8d5c8baa83fe620a28c0db633be9db3e34474b4' (2024-03-10)
  → 'github:Mic92/sops-nix/e52d8117b330f690382f1d16d81ae43daeb4b880' (2024-03-11)
```
2024-03-12 12:46:24 +00:00
7513811111 blast: minor cleanups 2024-03-12 12:06:57 +00:00
eabd113262 mpv: blast: shut it down properly even when sandboxed
it only cost everything. also, blast doesnt reliably clean up its pseudo devices
2024-03-12 11:51:15 +00:00
01fa9919fd mpv: route casting through a lua script
this lets me use `subcprocess` instead of `run`, and so the command terminate alongside mpv
2024-03-12 05:01:45 +00:00
56a2c4e49f mpv: split conf files out of main nix code 2024-03-12 03:32:07 +00:00
bf953fbdb5 mpv: move to own dir 2024-03-12 03:27:20 +00:00
4f2d0f2e56 mpv: tune uosc options 2024-03-12 03:05:56 +00:00
500c989e61 nixpkgs: 2024-03-10 -> 2024-03-11
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/85e4390bb2db2543b65a61a6fb601819ba331399' (2024-03-10)
  → 'github:nixos/nixpkgs/ec7a981885b5ede88eabf9bb3516706107de00b2' (2024-03-11)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/c916d4cbac62b2d8b70a3940d3471dbd0c57d2f4' (2024-03-10)
  → 'github:nixos/nixpkgs/0fbcc4b2e8571f4af39be41752581ea09dd9ab06' (2024-03-11)
• Updated input 'nixpkgs-wayland':
    'github:nix-community/nixpkgs-wayland/8af78a7dfb3a2041235c116cc9cc92f5a6d3a20c' (2024-03-11)
  → 'github:nix-community/nixpkgs-wayland/27a56d7435094f141bf5adfe9cfe155932597935' (2024-03-11)
```
2024-03-11 12:23:03 +00:00
08ee0375cc mpv: blast-to-default: remove unnecessary xdg-terminal-exec indirection 2024-03-11 12:07:08 +00:00
afd1a42ec7 mpv: refer to xdg-terminal-exec by name, not full path 2024-03-11 11:56:53 +00:00
21691fc2fd mpv: add a menu option to cast just the audio, via Blast 2024-03-11 11:43:53 +00:00
c1edf96ce0 blast-ugjka: introduce a helper blast-to-default program 2024-03-11 11:43:29 +00:00
21714849cf sway: get Celeste to run in fullscreen again 2024-03-11 08:04:21 +00:00
379f3ef9e0 zsh: deref alias: make the result writable 2024-03-11 08:01:27 +00:00
c07c23a9f8 ibus: remove cross patches (i don't use the package anymore) 2024-03-11 07:55:53 +00:00
f44a4c84ee moby: don't ship fcitx5 (doesn't cross compile) 2024-03-11 07:54:49 +00:00
6822dad9c0 splatmoji: remove from config 2024-03-11 07:53:48 +00:00
9f8e42ef92 fcitx5: enable 2024-03-11 07:44:21 +00:00
bda374db13 sway: ship the nightly version 2024-03-11 05:53:14 +00:00
180a217744 cleanup: remove unnecessary config = { ... } scope 2024-03-11 04:31:11 +00:00
f13ece2212 sway: tune resize more shortcuts; enable natural scrolling 2024-03-11 04:30:28 +00:00
00ab28fcac delfin: 0.4.0 -> 0.4.1 2024-03-11 00:13:13 +00:00
bb18f7355a firefox-extensions: update to latest 2024-03-11 00:00:49 +00:00
0905a658ad rofi: cherry-pick my patches instead of pinning to a fork
wayland upstream released 1.7.5+wayland3, which is compatible with my patches
2024-03-10 23:43:34 +00:00
90b9d00f37 swaync: remove mpris icon patch (upstreamed) 2024-03-10 23:16:33 +00:00
40effc08d6 fractal-nixified: 6 -> 6-unstable-2024-01-31
brings ability to enable/disable read and typing receipts
2024-03-10 23:15:02 +00:00
73a2c9d923 nixpkgs: update ~10hrs to remove now-upstreamed conky patch
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/32f638e62d638c9a0011c0162ed1be4a13d00ea9' (2024-03-10)
  → 'github:nixos/nixpkgs/85e4390bb2db2543b65a61a6fb601819ba331399' (2024-03-10)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/9fc2bd0eef6d2651638656c82fbe0b7a40478c3b' (2024-03-10)
  → 'github:nixos/nixpkgs/c916d4cbac62b2d8b70a3940d3471dbd0c57d2f4' (2024-03-10)
```
2024-03-10 22:31:33 +00:00
d93380938d nixpkgs: 2024-03-09 -> 2024-03-10; sops-nix -> 2024-03-10
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/8baf388f460b92102ea1a8e2ece55f1f1260fbfa' (2024-03-09)
  → 'github:nixos/nixpkgs/32f638e62d638c9a0011c0162ed1be4a13d00ea9' (2024-03-10)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/52d9c7906c26317adc3524d44bdd98b953e20ba1' (2024-03-09)
  → 'github:nixos/nixpkgs/9fc2bd0eef6d2651638656c82fbe0b7a40478c3b' (2024-03-10)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/25dd60fdd08fcacee2567a26ba6b91fe098941dc' (2024-03-06)
  → 'github:Mic92/sops-nix/f8d5c8baa83fe620a28c0db633be9db3e34474b4' (2024-03-10)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/66d65cb00b82ffa04ee03347595aa20e41fe3555' (2024-03-03)
  → 'github:NixOS/nixpkgs/b17375d3bb7c79ffc52f3538028b2ec06eb79ef8' (2024-03-10)
```
2024-03-10 13:36:58 +00:00
573a50fedc doc: pipewire: mention some debug env vars 2024-03-10 04:59:51 +00:00
f8797a77ff blast: ship it!
TODO: integrate into mpv :)
2024-03-10 04:09:34 +00:00
92115709f6 blast-ugjka: init at 0.6.2
it works! at least, with the Sony TV, LG TV is detected but might need some finessing
2024-03-10 02:35:10 +00:00
e6111c9d5e firefox: hide the bookmarks menuabar 2024-03-10 01:59:46 +00:00
975df698a4 pa-dlna: init at 0.7
it detects my TVs and adds them as sinks, but i can't the TVs to actually output anything
2024-03-10 01:55:29 +00:00
ce8c4a4f6f remove dead binfmt code 2024-03-10 01:05:33 +00:00
df33576090 todo.md: remove completed xdg-desktop-portal item 2024-03-10 01:03:23 +00:00
4d6eb705eb mpv: link to some useful extensions 2024-03-10 01:02:54 +00:00
fd70b6acbf rofi: tune maximum height 2024-03-09 23:34:43 +00:00
1d3576b892 sxmo-utils: mark as broken/unmaintained 2024-03-09 21:09:32 +00:00
30d49dc3c3 feeds: update Anish's URL 2024-03-09 20:51:15 +00:00
8e0031e770 feeds: update Byrne Hobart's feed URL 2024-03-09 20:49:01 +00:00
7a50fcf566 feeds: unsubscribe webcurious.co.uk (defunct) 2024-03-09 20:46:08 +00:00
c453dbac8e lwn.net: update feed URL 2024-03-09 20:42:03 +00:00
053b8cf737 nixpkgs: 2024-03-08 -> 2024-03-09
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/f391672e1727b933cf6933154817fe236c6f84c7' (2024-03-08)
  → 'github:nixos/nixpkgs/8baf388f460b92102ea1a8e2ece55f1f1260fbfa' (2024-03-09)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/baf89057836e5f9928696526b85774ea529c749d' (2024-03-08)
  → 'github:nixos/nixpkgs/52d9c7906c26317adc3524d44bdd98b953e20ba1' (2024-03-09)
```
2024-03-09 08:54:18 +00:00
8af962c3a6 mpv: auto-populate internal playlist with other files in the same directory, on launch
so now i can listen to whole albums by opening any file from within them.
and for shows the next episode will automatically launch.
2024-03-09 03:02:09 +00:00
9ea39799a5 zsh: fix c alias 2024-03-09 03:01:37 +00:00
e695459b40 geary-gtk4: init (broken!) 2024-03-09 00:58:44 +00:00
f2e760710d sysvol: tune its position 2024-03-08 23:06:37 +00:00
dc70ed8bd8 pipewire: wait for sockets to appear before considering it active
this fixes race around consumers like sysvol starting too early
2024-03-08 22:44:59 +00:00
b41c249830 disable vlc
i don't use it; it forces a bunch of extra qt builds
2024-03-08 18:53:25 +00:00
8f986e4616 nixpkgs: 2024-03-07 -> 2024-03-08
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/5e0cda94371075bead6d953e8a60a717ec022524' (2024-03-07)
  → 'github:nixos/nixpkgs/f391672e1727b933cf6933154817fe236c6f84c7' (2024-03-08)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/90714b18a06ddad90159cc312814f1871509e10e' (2024-03-07)
  → 'github:nixos/nixpkgs/baf89057836e5f9928696526b85774ea529c749d' (2024-03-08)
```
2024-03-08 13:15:25 +00:00
2b73ebb4c1 sysvol: don't start until after pipewire is ready 2024-03-08 12:55:33 +00:00
bffcaa668e sysvol: wrap with required gtk4 environment variables 2024-03-08 12:54:41 +00:00
ebb037bd48 sysvol: fix cross compilation 2024-03-08 12:25:32 +00:00
df98ef30e0 sysvol: integrate as a service (sane.programs) 2024-03-08 11:53:13 +00:00
e45d4d6ae7 sysvol: init at 0-unstable-2024-02-08 2024-03-08 10:10:50 +00:00
f3568b3ffc sway: port volume controls: pulse -> pipewire 2024-03-08 09:56:15 +00:00
9eaf4d71b2 sway: use simpler assign notation where applicable 2024-03-08 09:53:07 +00:00
3200188a32 sway: factor/generalize the TV workspace/output assignment 2024-03-08 09:50:35 +00:00
a4ab60b836 sway: auto-fullscreen everything on the TV 2024-03-08 09:42:07 +00:00
3282b40e9b doc: sway: consider how to auto-fullscreen mpv on external display 2024-03-08 09:31:08 +00:00
39411164af zsh: add deref function to turn a symlink into a real file 2024-03-08 08:50:28 +00:00
c0a94995a5 docs: note limitations of schlock 2024-03-08 08:16:11 +00:00
f4b5d3a70a sway: position certain apps (mpv, Celeste) on external displays by default 2024-03-08 06:27:16 +00:00
07373b5e6b sway: configure TV output 2024-03-08 06:23:33 +00:00
7281b94e23 deadd-notification-center: add to sane.programs
this is the bare, nearly-default config. i may come back to this,
or explore fixing swaync up into shape. deadd looks possibly a bit more
limited; needs much more effort to style.
2024-03-08 04:06:18 +00:00
0e83742096 sway: allow config reloading 2024-03-08 03:44:33 +00:00
7d8205352c moby: use screen scale of 2.0 in portrait AND landscape 2024-03-08 02:21:47 +00:00
c4994162e1 mpv: fix go2tv sandbox interaction 2024-03-08 02:06:23 +00:00
24a211bd3d sane-input-handler: remove keyboard launch fallback
it'll never work, because of sandboxing
2024-03-08 01:18:39 +00:00
3cf651b212 nixpkgs: 2024-03-06 -> 2024-03-07
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/09c267dae0dae6585ddbc98bd2301bd8153ac177' (2024-03-06)
  → 'github:nixos/nixpkgs/5e0cda94371075bead6d953e8a60a717ec022524' (2024-03-07)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/a85303aef29c6a9000a259ed21c9c14a1aa3859e' (2024-03-06)
  → 'github:nixos/nixpkgs/90714b18a06ddad90159cc312814f1871509e10e' (2024-03-07)
```
2024-03-08 01:12:05 +00:00
cb1c76a0db wvkbd-mk: init 2024-03-08 01:06:13 +00:00
27c12edec0 wvkbd: change default key border 2 -> 1 px
since moby is scaled 2x, it's actually 2 px *in practice*
2024-03-08 00:45:45 +00:00
b41320ffb3 megapixels: fix sandbox-related crash 2024-03-08 00:16:29 +00:00
ac41cfcd42 wvkbd: tune height (by guess) 2024-03-08 00:01:23 +00:00
62cbc65f12 epiphany: fix sandboxing 2024-03-07 23:24:33 +00:00
ccb856faf5 sane-input-handler: power -> vol to rotate display 2024-03-07 23:22:07 +00:00
d7f4438371 nixpatches: update procmail cross hash 2024-03-07 23:21:38 +00:00
f44c3f2e1f moby: auto-screenoff: bump timeout from 150s -> 300s 2024-03-07 23:14:03 +00:00
bb300a4eb5 swayidle: dont enable screenoff action by default 2024-03-07 11:18:34 +00:00
fd4842ab5b swayidle: auto screenoff 2024-03-07 10:59:44 +00:00
1cdc3b8bda moby: enable schlock screen locker 2024-03-07 10:37:18 +00:00
531ea11b3d schlock: fix cross build 2024-03-07 10:36:51 +00:00
041ce0654e schlock: sandbox + auto-launch via .desktop file 2024-03-07 10:32:40 +00:00
526a02bb73 schlock: ship a .desktop file 2024-03-07 10:25:41 +00:00
1d0458ab10 schlock: ship as sane.programs 2024-03-07 10:10:39 +00:00
4358f9471e schlock: init
it works! super jank; doesn't accept keyboard input, fails-open on
crash.
2024-03-07 09:36:53 +00:00
cb3a1fb3fe swaylock-mobile: init (i won't likely use it though) 2024-03-07 01:42:43 +00:00
72d52f9239 sxmo_swaylock: init at unstable-2023-04-26 (but i won't likely use it) 2024-03-07 01:34:53 +00:00
219fe67f34 systemd: reduce shutdown timeout from "20" to "10" sec (40s IRL) 2024-03-07 01:01:06 +00:00
b36d224b85 swaylock-plugin: init (but i likely won't be using it) 2024-03-07 01:00:44 +00:00
90e3c33536 feeds: subscribe to slatecave.net 2024-03-06 22:40:57 +00:00
a9419b7351 swayidle: sandbox 2024-03-06 21:33:11 +00:00
f0d0343b32 sway: lappy: fix output name 2024-03-06 21:18:43 +00:00
bd27f3a015 swayidle: enable; pair with swaylock 2024-03-06 20:55:01 +00:00
6a3e632335 sway: remove config for old external displays i no longer use 2024-03-06 19:03:13 +00:00
a4c4b0575c sway: map touch inputs to their correct display 2024-03-06 19:02:23 +00:00
4730a65008 nixpkgs: 2024-03-05 -> 2024-03-06
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/16bca48d251761297746d5bb7b9e47a3c6564c5a' (2024-03-05)
  → 'github:nixos/nixpkgs/09c267dae0dae6585ddbc98bd2301bd8153ac177' (2024-03-06)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/b3ed737064bc4cc0312081b6937fa2bb48d62afa' (2024-03-05)
  → 'github:nixos/nixpkgs/a85303aef29c6a9000a259ed21c9c14a1aa3859e' (2024-03-06)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/291aad29b59ceda517a06e59809f35cb0bb17c6b' (2024-03-04)
  → 'github:Mic92/sops-nix/25dd60fdd08fcacee2567a26ba6b91fe098941dc' (2024-03-06)
```
2024-03-06 09:54:23 +00:00
63d95edcbe zsh: fix c alias 2024-03-06 09:47:33 +00:00
687e72897b xdg-desktop-portal: don't always prompt the user for how to open every file 2024-03-06 06:25:36 +00:00
0e84744115 todo.md: xdg-desktop-portal improvements 2024-03-06 06:25:14 +00:00
1ee38d3aec todo.md: remove completed items 2024-03-06 05:28:18 +00:00
5f4e421ab9 sane-wipe: fix sandboxing 2024-03-06 05:11:24 +00:00
471339d237 hosts (all): remove sxmo-related polyfills 2024-03-06 05:07:30 +00:00
085232f18c wvkbd: configure layers 2024-03-06 05:07:30 +00:00
18c7fc17fd alacritty: configure font size per-host 2024-03-06 05:07:30 +00:00
a7567dfbe6 ship celeste64 2024-03-06 04:56:39 +00:00
bc0660b623 PDF viewer: evince -> zathura 2024-03-06 04:51:01 +00:00
cf86b4a67c xterm: move to pcGuiApps 2024-03-06 04:38:05 +00:00
d39bed46b5 rofi: allow access to Books 2024-03-06 01:39:48 +00:00
525450e21a fix backlight persistence 2024-03-06 00:58:11 +00:00
a4ee820921 /var/lib/colord: don't persist
files haven't changed in over a year; i assume it's legacy
2024-03-05 23:53:41 +00:00
4b5d6b16e1 alacritty: ignore media keys 2024-03-05 23:25:31 +00:00
41a141dba6 servo: disable navidrome 2024-03-05 18:48:25 +00:00
d5811f142d notifyActive activation script -> apply only to GUI systems
else i get warnings on every servo activation
2024-03-05 18:46:43 +00:00
4d6d79cc81 servo: /var/lib/uninsane/media -> /var/media 2024-03-05 18:44:30 +00:00
53d76920e4 servo: persist more specifically the /var/lib/uninsane/media directory 2024-03-05 18:39:23 +00:00
db892273ac nixpatches: fix imagemagick cross fix hash 2024-03-05 18:37:09 +00:00
65e206afde nixpkgs: 2024-03-04 -> 2024-03-05
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/1a3380fec6e3c2d539e58c4be6a4a094d7d14aea' (2024-03-04)
  → 'github:nixos/nixpkgs/16bca48d251761297746d5bb7b9e47a3c6564c5a' (2024-03-05)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/4c0862ebf8e474315767c5210c3d0a336625f318' (2024-03-04)
  → 'github:nixos/nixpkgs/b3ed737064bc4cc0312081b6937fa2bb48d62afa' (2024-03-05)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/075df9d85ee70cfb53e598058045e1738f05e273' (2024-03-03)
  → 'github:Mic92/sops-nix/291aad29b59ceda517a06e59809f35cb0bb17c6b' (2024-03-04)
```
2024-03-05 10:09:39 +00:00
6765fe8d7d wob: rename sxmo.wobsock -> wob.sock 2024-03-05 10:00:45 +00:00
955119e07b wob-audio: fix, by finishing the port to pipewire
also rewrote it in Python because bash can't do floating point math
2024-03-05 09:32:37 +00:00
daddf9314a gpodder: fix .desktop file(s) 2024-03-05 02:58:21 +00:00
e59123fd62 cozy: fix patch hash 2024-03-05 02:58:14 +00:00
d43cc6c61c alsa-ucm-conf: fold the Pinephone patches into sane.programs.alsa-ucm-conf & distribute to all hosts 2024-03-05 00:28:07 +00:00
a8bc77d40c nixpkgs sourceInfo patching: move to nixpatches/
previously i was using the sourceInfo of the flake, which is kinda wrong: and it would force a _new_ nixpkgs for every time i commit to my own repo -- not just when i bump it
2024-03-05 00:06:08 +00:00
dfc768e2e6 flake: place builds strictly in build/ directory 2024-03-04 23:47:31 +00:00
3544b4b132 nixpkgs: 2024-03-03 -> 2024-03-04
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/6a2985393fcc1dfabc6d36af148ca761a807e002' (2024-03-03)
  → 'github:nixos/nixpkgs/1a3380fec6e3c2d539e58c4be6a4a094d7d14aea' (2024-03-04)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/286977c08ddf540b4c6bebd8cd96fe30070bcb46' (2024-03-03)
  → 'github:nixos/nixpkgs/4c0862ebf8e474315767c5210c3d0a336625f318' (2024-03-04)
```
2024-03-04 09:41:23 +00:00
c86afca795 cozy: patch via sane.programs, not overlay 2024-03-04 09:26:25 +00:00
5f3ef37050 cozy: 1.2.1 -> 1.3.0 2024-03-04 08:57:52 +00:00
3b8252fe43 delfin: doc improvements 2024-03-04 08:28:50 +00:00
1e6e4d2644 cozy: doc improvements 2024-03-04 08:28:35 +00:00
60c447b6c4 signal-desktop: 6.44.0 -> 7.0.0 2024-03-04 08:26:59 +00:00
4fc2ffef56 koreader-from-src: 2024.01 -> 2024.03 2024-03-04 08:19:41 +00:00
9416ef1ff6 firefox-extensions: update 2024-03-04 08:18:48 +00:00
b1dff9bfa8 steam: fix controllers to work in the sandbox 2024-03-03 20:03:20 +00:00
0003acc091 nixpkgs: 2024-03-02 -> 2024-03-03
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/aefac840b87e8e0ab658fa5080539e292ad8a9ba' (2024-03-02)
  → 'github:nixos/nixpkgs/6a2985393fcc1dfabc6d36af148ca761a807e002' (2024-03-03)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/df41961bd4b7e838cb997543ea1297f4cbd7da15' (2024-03-02)
  → 'github:nixos/nixpkgs/286977c08ddf540b4c6bebd8cd96fe30070bcb46' (2024-03-03)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/a1c8de14f60924fafe13aea66b46157f0150f4cf' (2024-02-26)
  → 'github:Mic92/sops-nix/075df9d85ee70cfb53e598058045e1738f05e273' (2024-03-03)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/89a2a12e6c8c6a56c72eb3589982c8e2f89c70ea' (2024-02-25)
  → 'github:NixOS/nixpkgs/66d65cb00b82ffa04ee03347595aa20e41fe3555' (2024-03-03)
```
2024-03-03 10:11:16 +00:00
0630037f86 steam: sandbox
controllers are untested, probably need to be added; graphics and sound work fine
2024-03-03 10:10:14 +00:00
9513680538 sway: enable net access in the sandbox (for Xwayland) 2024-03-03 10:09:29 +00:00
0affeb098a rofi: optimize sizing 2024-03-03 07:36:33 +00:00
979d07d693 wob: port pulseaudio -> pipewire 2024-03-03 07:22:03 +00:00
fd072883dc sane-input-handler: port pulseaudio -> pipewire native 2024-03-03 07:13:23 +00:00
ed87792f9b sed: sandbox 2024-03-03 07:06:00 +00:00
8821b3ca7d procps: sandbox 2024-03-03 06:55:17 +00:00
5e5a1fbaae rofi: allow to use more space on moby when keyboard is active 2024-03-03 04:46:12 +00:00
d2f470dc74 wvkbd: sandbox 2024-03-03 04:44:23 +00:00
7933ef41a2 unl0kr: simplify this code 2024-03-03 04:43:44 +00:00
6b45589e54 wireplumber: ensure ALSA_UCM_CONF2 env var is on PATH
this is critical for pipewire/wireplumber to work on moby
2024-03-03 04:43:11 +00:00
b04357c9de nix.conf: dont ship NIX_PATH for light deploys
it's like 150 MiB
2024-03-03 03:53:13 +00:00
4b04cbc078 mpv: couple app volume to system volume 2024-03-03 03:22:28 +00:00
1498e364b2 doc: mimeo: mention jaro as alternative 2024-03-03 03:16:10 +00:00
0aaa3eaaeb mpv: remove legacy vo=wlshim hack 2024-03-02 23:46:52 +00:00
3ac6b92c18 /etc/nix/registry.json: don't generate for -light builds (it links back to src) 2024-03-02 23:42:58 +00:00
c747855810 bonsai: sandbox 2024-03-02 22:34:38 +00:00
711865018d /etc/nixos: don't link on '*-light' builds 2024-03-02 22:13:04 +00:00
f33fcc2018 nixpatches: update hashes 2024-03-02 21:23:44 +00:00
96ec0106ee sane-input-handler: leverage sane-open-desktop instead of making direct gdbus calls 2024-03-02 21:20:47 +00:00
0c4d7761d3 sane-input-handler: sandbox 2024-03-02 21:20:47 +00:00
fe10640821 wob-pulse: sandbox 2024-03-02 20:57:44 +00:00
1f208083be mpvScripts.uosc: 5.1.1 -> 5.2.0 2024-03-02 20:39:04 +00:00
6ec3126321 moby: fix display driver reload check to run before unl0kr
this should fix the no-graphics-on-boot bug i'm seeing. it was previously fixed for lightdm and greetd: just not unl0kr
2024-03-02 19:50:50 +00:00
8029744c90 modules/programs: don't expose *all* of /run/secrets/home to every program
this was actually causing a lot of bwrap errors because that directory's not user-readable

turns out any program which already uses programs.xyz.secrets gets the /run/secrets mounts for free via symlink following
2024-03-02 18:51:39 +00:00
1fcf0bfcb1 swaync: fix signal-desktop check to be --user 2024-03-02 18:33:35 +00:00
a3ae650273 dialect: fix so it works inside a sandbox 2024-03-02 18:25:13 +00:00
7e0bef549f nixpkgs: 2024-03-01 -> 2024-03-02
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/ee743c92310804de4b4505ff0ac40b4f3f4f49de' (2024-03-01)
  → 'github:nixos/nixpkgs/aefac840b87e8e0ab658fa5080539e292ad8a9ba' (2024-03-02)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/f7fca9d98b0ec282f4b0d63f1fc2e38caf4ea55a' (2024-03-01)
  → 'github:nixos/nixpkgs/df41961bd4b7e838cb997543ea1297f4cbd7da15' (2024-03-02)
```
2024-03-02 07:52:21 +00:00
3b603519ff fuzzel: sandbox (well, i probably dont even have it on my system anymore :P) 2024-03-02 07:43:42 +00:00
f69ca166f4 sway: sandbox 2024-03-02 07:41:51 +00:00
a45e42910d make-sandboxed: generalize runCommand patch to handle any derivation, called with or without callPackage 2024-03-02 07:11:45 +00:00
3dd1d18dcd less: sandbox 2024-03-02 07:11:45 +00:00
28cb705bd4 grim: sandbox 2024-03-02 07:11:45 +00:00
7fa1dbc5d5 slurp: sandbox 2024-03-02 07:11:45 +00:00
8b7575c205 swappy: sandbox 2024-03-02 07:11:45 +00:00
52e9902fa1 sane-screenshot: give it permissions to my screenshots dir (derp) 2024-03-02 06:14:05 +00:00
ab765a81af sway: integrate sane-screenshot as the PrintScreen shortcut 2024-03-02 06:14:05 +00:00
a7bd831ad8 sane-screenshot: port to sane.programs 2024-03-02 06:14:05 +00:00
063d99dd73 todo.md: task to remove /run/wrappers 2024-03-02 05:42:26 +00:00
0d48c462cb sane-screenshot: init 2024-03-02 02:04:48 +00:00
f4ec09f010 rofi: remember the last selected directory 2024-03-02 00:35:29 +00:00
a7ef9fc0b8 todo.md: task for better app integrations 2024-03-02 00:21:56 +00:00
a40cefc8a5 pipewire: speculatively add /dev/video* 2024-03-02 00:14:47 +00:00
f55bb3518f wireplumber: add missing /dev/video2 which is on moby 2024-03-02 00:14:21 +00:00
3d16aa62ea sway: let the pinephone default to it's normal scaling
it's actually pretty nice at 2.0 scaling with my current apps. i'll need to tweak swaync, conky, wvkbd, etc. later.
2024-03-01 23:53:31 +00:00
2548cfeadc xdg-desktop-portal-wlr: fix crashing due to over-restrictive sandbox 2024-03-01 21:17:31 +00:00
90acbf716d Videos/gPodder: allow access from mpv and rofi 2024-03-01 21:02:04 +00:00
4d98593b3f todo.md: sync 2024-03-01 20:48:56 +00:00
db89ac88f0 sane-sandboxed: add new --sane-sandbox-keep-namespace all option 2024-03-01 20:48:56 +00:00
bba149c670 zsh: new c helper to change into a dir and list it 2024-03-01 20:09:20 +00:00
c056984003 zsh: alias exiy -> exit 2024-03-01 19:56:09 +00:00
2324d75165 switch psmisc -> killall
otherwise a really shitty `pstree` makes its way onto my PATH
2024-03-01 18:50:20 +00:00
9296b7731b rofi: add a .desktop file to rofi-snippets 2024-03-01 18:07:52 +00:00
75e9ce509e static-nix-shell: add support for extra nativeBuildInputs 2024-03-01 18:07:07 +00:00
95c95d6f53 splatmoji: actually install the .desktop files 2024-03-01 18:03:45 +00:00
fca23e661a xdg-desktop-portal: disable debug logging 2024-03-01 17:50:49 +00:00
9a7ebbd9d3 rofi: configure window height/location 2024-03-01 17:18:40 +00:00
56b00d998e rofi: theme
i still need to figure out how to make it wider for moby
2024-03-01 16:40:09 +00:00
01ef182073 waybar: theme the indicator style
i don't know if it's perfect, but it is better
2024-03-01 15:32:52 +00:00
b6daeddfa2 waybar: show different modules for moby v.s. others 2024-03-01 15:25:42 +00:00
c6e956f3d2 waybar: fix button.urgent color to match sway's client.urgent 2024-03-01 15:03:14 +00:00
f9510e5d24 nixpkgs: 2024-02-29 -> 2024-03-01
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/e894afb6c101fea0771b47d7827bef022e89ee1e' (2024-02-29)
  → 'github:nixos/nixpkgs/ee743c92310804de4b4505ff0ac40b4f3f4f49de' (2024-03-01)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/d29fabd630000579f744d04639d625828ba412bf' (2024-02-29)
  → 'github:nixos/nixpkgs/f7fca9d98b0ec282f4b0d63f1fc2e38caf4ea55a' (2024-03-01)
```
2024-03-01 07:31:58 +00:00
2e737c2ab1 moby: sxmo -> sway
still several things need to be improved, but the groundwork is there
2024-03-01 07:26:26 +00:00
82368eb45a sway: desko: fix monitor layout
i guess my monitor's name changed... 👀
2024-03-01 07:19:00 +00:00
65fb9e1d57 rofi: allow access to more servo media paths 2024-03-01 07:14:41 +00:00
b02ae7ef74 moby: polyfill an OK sway layout 2024-03-01 05:20:28 +00:00
37ddb2ae17 waybar: fix font size to be more usable on moby 2024-03-01 04:46:06 +00:00
81e02e2885 sway: moby: fix layout/scale preferences 2024-03-01 04:38:26 +00:00
4a3f59468c sway: launch gui apps via sane-open-desktop instead of inline
this will allow for sandboxing, in the future
2024-03-01 04:19:19 +00:00
daab5939e7 rofi: split sane-open-desktop out as a helper 2024-03-01 04:19:19 +00:00
e7430c41f9 refactor: sway-config: for readability 2024-03-01 03:29:52 +00:00
5849e75577 sway-config: remove dead window specializations 2024-03-01 03:21:47 +00:00
296123651c sway: fold sway-config.nix into default.nix 2024-03-01 03:18:37 +00:00
7f0d5e7810 sane-input-handler: explain why i setsid 2024-03-01 03:11:06 +00:00
7af928a6d2 sway: direct inputs to bonsai WITHOUT swallowing them 2024-03-01 03:10:44 +00:00
b73569d675 wvkbd: fix service typo 2024-02-29 22:04:42 +00:00
50ee15ef2b send sway-related cross patches upstream 2024-02-29 21:35:02 +00:00
9764d5f095 sway/waybar: decrease cross-specific patches
cava cross compiles now (yay); sndio is actually required by waybar if cava is enabled, so remove the disable
2024-02-29 18:56:54 +00:00
43386f3ba5 nixpkgs: update; couple cross-compiling patches have merged upstream
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/0852bff4370133e3a62b0cc7d14d193b928a7c59' (2024-02-29)
  → 'github:nixos/nixpkgs/e894afb6c101fea0771b47d7827bef022e89ee1e' (2024-02-29)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/9f21aa90cb8c078969543956d88c19696b646743' (2024-02-29)
  → 'github:nixos/nixpkgs/d29fabd630000579f744d04639d625828ba412bf' (2024-02-29)
```
2024-02-29 18:22:35 +00:00
a3a6278a59 notifyActive: don't depend on sway
it was a little silly to be shipping sway on headless systems
2024-02-29 17:32:19 +00:00
083f743c1f remove nixpkgs less defaults and manage PAGER myself
this lets me avoid the lesspipe cross failures, notably
2024-02-29 15:18:51 +00:00
626ad97005 nixpkgs: 2024-02-27 -> 2024-02-29
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/6daf4de0662e1d895d220a4a4ddb356eb000abe9' (2024-02-27)
  → 'github:nixos/nixpkgs/0852bff4370133e3a62b0cc7d14d193b928a7c59' (2024-02-29)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/5bd8df40204f47a12263f3614c72cd5b6832a9a0' (2024-02-27)
  → 'github:nixos/nixpkgs/9f21aa90cb8c078969543956d88c19696b646743' (2024-02-29)
```
2024-02-29 06:42:18 +00:00
6253d1799a port sxmo_hook_inputhandler.sh -> sane-input-handler
this one can run outside the SXMO environment.
major thing missing at the moment is that rofi doesn't get volume
control inputs because bonsai out-competes it for exclusive control.
2024-02-29 01:26:38 +00:00
d8a8038cae xdg-terminal-exec: define a .desktop file 2024-02-29 00:17:26 +00:00
7fd56b63cb rofi: better patch for the DT_UNKNOWN edgecase 2024-02-28 21:41:59 +00:00
7a65bd36c7 rofi: patch the filebrowser to reliably list entries on remote filesystems
see: <https://github.com/davatorium/rofi/issues/1954>
2024-02-28 21:18:19 +00:00
bd4eeeeb3b nixpatches: imagemagick closure fix: mark as merged upstream 2024-02-28 18:27:15 +00:00
7c22b59b9d sane-which: handle relative symlinks 2024-02-28 18:16:08 +00:00
9e504676bd sane-which: only print the first 30 lines for text files 2024-02-28 18:09:38 +00:00
b515127101 sane-which: follow nix wrappers 2024-02-28 18:09:24 +00:00
40e30cf2f8 programs: make sandbox.wrapperType default to "wrappedDerivation" and remove everywhere i manually set that 2024-02-28 17:39:00 +00:00
812c0c8029 packages: reduce the number of packages which are using inplace sandbox wrapping 2024-02-28 17:35:40 +00:00
7ca5ae84b7 flake: deploy: abort on error 2024-02-28 17:34:45 +00:00
a4248fd5cc make-sandboxed: don't try to wrap directories
whoops. test -x is true for directories
2024-02-28 16:28:25 +00:00
70229e0839 rofi: persist the filebrowsercache 2024-02-28 15:41:52 +00:00
cd303a76bc rofi: disable "run" from combi
they wouldn't work, since i only 'xdg-open' the entries
2024-02-28 15:32:12 +00:00
e43aa3bb8b splatmoji: fix sandboxing so rofi can read its config/cache 2024-02-28 15:19:53 +00:00
6c2d80715c rofi-snippets: fix sandboxing so rofi can read its config/cache 2024-02-28 15:15:02 +00:00
db8456f152 flake: provide a "benchmark" target 2024-02-28 15:10:45 +00:00
d912190db5 sway: split snippets into own program (rofi-snippets) 2024-02-28 14:44:05 +00:00
c380f61bea fix "rescue" host to eval again 2024-02-28 14:19:45 +00:00
ff8cfc9372 flake: fix check.nur target 2024-02-28 13:47:51 +00:00
b302113fc0 modules/programs: require manual definition; don't auto-populate attrset
this greatly decreases nix eval time
2024-02-28 13:35:09 +00:00
9749ff0442 sane.gui.phosh: remove 2024-02-28 13:35:05 +00:00
0d97191f74 sane-wipe-browser: dont call pkill with sudo 2024-02-28 13:35:00 +00:00
206 changed files with 5462 additions and 2189 deletions

View File

@@ -15,8 +15,9 @@ the only hard dependency for my exported pkgs/modules should be [nixpkgs][nixpkg
building [hosts/](./hosts/) will require [sops][sops].
you might specifically be interested in these files (elaborated further in #key-points-of-interest):
- [`sxmo-utils`](./pkgs/additional/sxmo-utils/default.nix)
- [example SXMO deployment](./hosts/modules/gui/sxmo/default.nix)
- ~~[`sxmo-utils`](./pkgs/additional/sxmo-utils/default.nix)~~
- ~~[example SXMO deployment](./hosts/modules/gui/sxmo/default.nix)~~
- these files will remain until my config settles down, but i no longer use or maintain SXMO.
- [my implementation of impermanence](./modules/persist/default.nix)
- my way of deploying dotfiles/configuring programs per-user:
- [modules/fs/](./modules/fs/default.nix)

15
TODO.md
View File

@@ -11,16 +11,15 @@
### sops/secrets
- rework secrets to leverage `sane.fs`
- remove sops activation script as it's covered by my systemd sane.fs impl
- user secrets could just use `gocryptfs`, like with ~/private?
- can gocryptfs support nested filesystems, each with different perms (for desko, moby, etc)?
### roles
- allow any host to take the role of `uninsane.org`
- will make it easier to test new services?
### upstreaming
- split out a sxmo module usable by NUR consumers
- bump nodejs version in lemmy-ui
- add updateScripts to all my packages in nixpkgs
- fix lightdm-mobile-greeter for newer libhandy
- REVIEW/integrate jellyfin dataDir config: <https://github.com/NixOS/nixpkgs/pull/233617>
#### upstreaming to non-nixpkgs repos
@@ -47,6 +46,8 @@
- limit access to `~/knowledge/secrets` through an agent that requires GUI approval, so a firefox exploit can't steal all my logins
- port sane-sandboxed to a compiled language (hare?)
- it adds like 50-70ms launch time _on my laptop_. i'd hate to know how much that is on the pinephone.
- remove /run/wrappers from the sandbox path
- they're mostly useless when using no-new-privs, just an opportunity to forget to specify deps
- make dconf stuff less monolithic
- i.e. per-app dconf profiles for those which need it. possible static config.
- canaries for important services
@@ -54,6 +55,11 @@
- integrate `nix check` into Gitea actions?
### user experience
- xdg-desktop-portal shouldn't kill children on exit
- *maybe* a job for `setsid -f`?
- replace starship prompt with something more efficient
- watch `forkstat`: it does way too much
- cleanup waybar so that it's not invoking playerctl every 2 seconds
- install apps:
- display QR codes for WiFi endpoints: <https://linuxphoneapps.org/apps/noappid.wisperwind.wifi2qr/>
- shopping list (not in nixpkgs): <https://linuxphoneapps.org/apps/ro.hume.cosmin.shoppinglist/>
@@ -76,6 +82,7 @@
#### moby
- fix cpuidle (gets better power consumption): <https://xnux.eu/log/077.html>
- moby: tune keyboard layout
- SwayNC:
- don't show MPRIS if no players detected
- this is a problem of playerctld, i guess
@@ -97,6 +104,7 @@
- RSS: integrate a paywall bypass
- e.g. self-hosted [ladder](https://github.com/everywall/ladder) (like 12ft.io)
- neovim: set up language server (lsp; rnix-lsp; nvim-lspconfig)
- neovim: integrate LLMs
- Helix: make copy-to-system clipboard be the default
- firefox/librewolf: persist history
- just not cookies or tabs
@@ -114,7 +122,6 @@
### perf
- debug nixos-rebuild times
- i bet sane.programs adds a LOT of time, with how it automatically creates an attrs for EVERY package in nixpkgs.
- add `pkgs.impure-cached.<foo>` package set to build things with ccache enabled
- every package here can be auto-generated, and marked with some env var so that it doesn't pollute the pure package set
- would be super handy for package prototyping!

233
flake.lock generated
View File

@@ -1,5 +1,79 @@
{
"nodes": {
"flake-compat": {
"locked": {
"lastModified": 1688025799,
"narHash": "sha256-ktpB4dRtnksm9F5WawoIkEneh1nrEvuxb5lJFt1iOyw=",
"owner": "nix-community",
"repo": "flake-compat",
"rev": "8bf105319d44f6b9f0d764efa4fdef9f1cc9ba1c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs-wayland",
"nix-eval-jobs",
"nixpkgs"
]
},
"locked": {
"lastModified": 1701473968,
"narHash": "sha256-YcVE5emp1qQ8ieHUnxt1wCZCC3ZfAS+SRRWZ2TMda7E=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "34fed993f1674c8d06d58b37ce1e0fe5eebcb9f5",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"lib-aggregate": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1710184940,
"narHash": "sha256-FzYm4td3FJfzOAuEkCXt3KdUgZuA072OAQXqIq+IAMo=",
"owner": "nix-community",
"repo": "lib-aggregate",
"rev": "45b75bf534592c0c1c881a1c447f7fdb37a87eaf",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "lib-aggregate",
"type": "github"
}
},
"mobile-nixos": {
"flake": false,
"locked": {
@@ -17,13 +91,87 @@
"type": "github"
}
},
"nix-eval-jobs": {
"inputs": {
"flake-parts": "flake-parts",
"nix-github-actions": "nix-github-actions",
"nixpkgs": "nixpkgs",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1705242886,
"narHash": "sha256-TLj334vRwFtSym3m+NnKcNCnKKPNoTC/TDZL40vmOso=",
"owner": "nix-community",
"repo": "nix-eval-jobs",
"rev": "6b03a93296faf174b97546fd573c8b379f523a8d",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-eval-jobs",
"type": "github"
}
},
"nix-github-actions": {
"inputs": {
"nixpkgs": [
"nixpkgs-wayland",
"nix-eval-jobs",
"nixpkgs"
]
},
"locked": {
"lastModified": 1701208414,
"narHash": "sha256-xrQ0FyhwTZK6BwKhahIkUVZhMNk21IEI1nUcWSONtpo=",
"owner": "nix-community",
"repo": "nix-github-actions",
"rev": "93e39cc1a087d65bcf7a132e75a650c44dd2b734",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-github-actions",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1703134684,
"narHash": "sha256-SQmng1EnBFLzS7WSRyPM9HgmZP2kLJcPAz+Ug/nug6o=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d6863cbcbbb80e71cecfc03356db1cda38919523",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1710031547,
"narHash": "sha256-pkUg3hOKuGWMGF9WEMPPN/G4pqqdbNGJQ54yhyQYDVY=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "630ebdc047ca96d8126e16bb664c7730dc52f6e6",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs-next-unpatched": {
"locked": {
"lastModified": 1708992120,
"narHash": "sha256-t/8QV+lEroW5fK44w5oEUalIM0eYYVGs833AHDCIl4s=",
"lastModified": 1710337169,
"narHash": "sha256-u2/74bhQuWykUZDWUIhHd6IpZiaQ0hSpTBbx0y9opkE=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "6daf4de0662e1d895d220a4a4ddb356eb000abe9",
"rev": "4ee0840ba2ecc50458ab1677d108afcd691f4815",
"type": "github"
},
"original": {
@@ -35,11 +183,11 @@
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1708819810,
"narHash": "sha256-1KosU+ZFXf31GPeCBNxobZWMgHsSOJcrSFA6F2jhzdE=",
"lastModified": 1710033658,
"narHash": "sha256-yiZiVKP5Ya813iYLho2+CcFuuHpaqKc/CoxOlANKcqM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "89a2a12e6c8c6a56c72eb3589982c8e2f89c70ea",
"rev": "b17375d3bb7c79ffc52f3538028b2ec06eb79ef8",
"type": "github"
},
"original": {
@@ -51,11 +199,11 @@
},
"nixpkgs-unpatched": {
"locked": {
"lastModified": 1708995544,
"narHash": "sha256-YJgLopKOKVTggnKzjX4OiAS22hx/vNv397DcsAyTZgY=",
"lastModified": 1710339354,
"narHash": "sha256-+P5ccUPiLouHexb8aJrUOVOIja9qm+fG57pgAu7uIRs=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "5bd8df40204f47a12263f3614c72cd5b6832a9a0",
"rev": "2dbc8f62d8af7a1ab962e4b20d12b25ddcb86ced",
"type": "github"
},
"original": {
@@ -65,11 +213,35 @@
"type": "github"
}
},
"nixpkgs-wayland": {
"inputs": {
"flake-compat": "flake-compat",
"lib-aggregate": "lib-aggregate",
"nix-eval-jobs": "nix-eval-jobs",
"nixpkgs": [
"nixpkgs-unpatched"
]
},
"locked": {
"lastModified": 1710317949,
"narHash": "sha256-bwReMiWPA2wYBvKEMhO8pJcu+o+7ocy5hGkSoawTHu0=",
"owner": "nix-community",
"repo": "nixpkgs-wayland",
"rev": "771cb198c281db6918829651f194bf4db32e342d",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs-wayland",
"type": "github"
}
},
"root": {
"inputs": {
"mobile-nixos": "mobile-nixos",
"nixpkgs-next-unpatched": "nixpkgs-next-unpatched",
"nixpkgs-unpatched": "nixpkgs-unpatched",
"nixpkgs-wayland": "nixpkgs-wayland",
"sops-nix": "sops-nix",
"uninsane-dot-org": "uninsane-dot-org"
}
@@ -82,11 +254,11 @@
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1708987867,
"narHash": "sha256-k2lDaDWNTU5sBVHanYzjDKVDmk29RHIgdbbXu5sdzBA=",
"lastModified": 1710195194,
"narHash": "sha256-KFxCJp0T6TJOz1IOKlpRdpsCr9xsvlVuWY/VCiAFnTE=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "a1c8de14f60924fafe13aea66b46157f0150f4cf",
"rev": "e52d8117b330f690382f1d16d81ae43daeb4b880",
"type": "github"
},
"original": {
@@ -95,6 +267,43 @@
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs-wayland",
"nix-eval-jobs",
"nixpkgs"
]
},
"locked": {
"lastModified": 1702979157,
"narHash": "sha256-RnFBbLbpqtn4AoJGXKevQMCGhra4h6G2MPcuTSZZQ+g=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "2961375283668d867e64129c22af532de8e77734",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"uninsane-dot-org": {
"inputs": {
"nixpkgs": [

View File

@@ -48,6 +48,11 @@
# nixpkgs-unpatched.url = "github:nixos/nixpkgs?ref=nixos-staging-next";
nixpkgs-next-unpatched.url = "github:nixos/nixpkgs?ref=staging-next";
nixpkgs-wayland = {
url = "github:nix-community/nixpkgs-wayland";
inputs.nixpkgs.follows = "nixpkgs-unpatched";
};
mobile-nixos = {
# <https://github.com/nixos/mobile-nixos>
# only used for building disk images, not relevant after deployment
@@ -76,6 +81,7 @@
self,
nixpkgs-unpatched,
nixpkgs-next-unpatched ? nixpkgs-unpatched,
nixpkgs-wayland,
mobile-nixos,
sops-nix,
uninsane-dot-org,
@@ -97,30 +103,7 @@
patchNixpkgs = variant: nixpkgs: (import ./nixpatches/flake.nix).outputs {
inherit variant nixpkgs;
self = patchNixpkgs variant nixpkgs;
} // {
# sourceInfo includes fields (square brackets for the ones which are not always present):
# - [dirtyRev]
# - [dirtyShortRev]
# - lastModified
# - lastModifiedDate
# - narHash
# - outPath
# - [rev]
# - [revCount]
# - [shortRev]
# - submodules
#
# these values are used within nixpkgs:
# - to give a friendly name to the nixos system (`readlink /run/current-system` -> `...nixos-system-desko-24.05.20240227.dirty`)
# - to alias `import <nixpkgs>` so that nix uses the system's nixpkgs when called externally (supposedly).
#
# these values seem to exist both within the `sourceInfo` attrset and at the top-level.
# for a list of all implicit flake outputs (which is what these seem to be):
# $ nix-repl
# > lf .
# > <tab>
inherit (self) sourceInfo;
} // self.sourceInfo;
};
nixpkgs' = patchNixpkgs "master" nixpkgs-unpatched;
nixpkgsCompiledBy = system: nixpkgs'.legacyPackages."${system}";
@@ -207,9 +190,18 @@
let
mobile = (import "${mobile-nixos}/overlay/overlay.nix");
uninsane = uninsane-dot-org.overlays.default;
wayland = final: prev: {
# default is to dump the packages into `waylandPkgs` *and* the toplevel.
# but i just want the `waylandPkgs` set
inherit (nixpkgs-wayland.overlays.default final prev)
waylandPkgs
new-wayland-protocols #< 2024/03/10: nixpkgs-wayland assumes this will be in the toplevel
;
};
in
(mobile final prev)
// (uninsane final prev)
// (wayland final prev)
;
};
@@ -265,6 +257,8 @@
pkgs = self.legacyPackages."x86_64-linux";
sanePkgs = import ./pkgs { inherit pkgs; };
deployScript = host: addr: action: pkgs.writeShellScript "deploy-${host}" ''
set -e
host="${host}"
addr="${addr}"
action="${if action != null then action else ""}"
@@ -278,8 +272,8 @@
fi
}
nix build ".#nixosConfigurations.$host.config.system.build.toplevel" --out-link "./result-$host" "$@"
storePath="$(readlink ./result-$host)"
nix build ".#nixosConfigurations.$host.config.system.build.toplevel" --out-link "./build/result-$host" "$@"
storePath="$(readlink ./build/result-$host)"
# mimic `nixos-rebuild --target-host`, in effect:
# - nix-copy-closure ...
@@ -382,6 +376,8 @@
- or `nix run '.#preDeploy'` to target all hosts
- `nix run '.#check'`
- make sure all systems build; NUR evaluates
- `nix run '.#bench'`
- benchmark the eval time of common targets this flake provides
specific build targets of interest:
- `nix build '.#imgs.rescue'`
@@ -525,6 +521,7 @@
--option allow-import-from-derivation true \
--drv-path --show-trace \
-I nixpkgs=${nixpkgs-unpatched} \
-I nixpkgs-overlays=${./.}/hosts/common/nix/overlay \
-I ../../ \
| tee # tee to prevent interactive mode
'');
@@ -536,7 +533,7 @@
checkHost = host: let
shellHost = pkgs.lib.replaceStrings [ "-" ] [ "_" ] host;
in ''
nix build -v '.#nixosConfigurations.${host}.config.system.build.toplevel' --out-link ./result-${host} -j2 "$@"
nix build -v '.#nixosConfigurations.${host}.config.system.build.toplevel' --out-link ./build/result-${host} -j2 "$@"
RC_${shellHost}=$?
'';
in builtins.toString (pkgs.writeShellScript
@@ -585,7 +582,31 @@
check.rescue = {
type = "app";
program = builtins.toString (pkgs.writeShellScript "check-rescue" ''
nix build -v '.#imgs.rescue' --out-link ./result-rescue-img -j2
nix build -v '.#imgs.rescue' --out-link ./build/result-rescue-img -j2
'');
};
bench = {
type = "app";
program = builtins.toString (pkgs.writeShellScript "bench" ''
doBench() {
attrPath="$1"
shift
echo -n "benchmarking eval of '$attrPath'... "
/run/current-system/sw/bin/time -f "%e sec" -o /dev/stdout \
nix eval --no-eval-cache --quiet --raw ".#$attrPath" --apply 'result: if result != null then "" else "unexpected null"' $@ 2> /dev/null
}
if [ -n "$1" ]; then
doBench "$@"
else
doBench hostConfigs
doBench hostConfigs.lappy
doBench hostConfigs.lappy.sane.programs
doBench hostConfigs.lappy.sane.users.colin
doBench hostConfigs.lappy.sane.fs
doBench hostConfigs.lappy.environment.systemPackages
fi
'');
};
};

View File

@@ -2,7 +2,6 @@
{
imports = [
./fs.nix
./polyfill.nix
];
sane.roles.client = true;

View File

@@ -1,41 +0,0 @@
# doesn't actually *enable* anything,
# but sets up any modules such that if they *were* enabled, they'll act as expected.
{ pkgs, ... }:
{
sane.gui.sxmo = {
noidle = true; #< power button requires 1s hold, which makes it impractical to be dealing with.
settings = {
# XXX: make sure the user is part of the `input` group!
SXMO_LISGD_INPUT_DEVICE = "/dev/input/by-id/usb-Wacom_Co._Ltd._Pen_and_multitouch_sensor-event-if00";
# these identifiers are from `swaymsg -t get_inputs`
SXMO_VOLUME_BUTTON = "1:1:AT_Translated_Set_2_keyboard";
# SXMO_VOLUME_BUTTON = "none";
# N.B.: thinkpad's power button requires a full second press to do anything
SXMO_POWER_BUTTON = "0:1:Power_Button";
# SXMO_POWER_BUTTON = "none";
SXMO_DISABLE_LEDS = "1";
SXMO_UNLOCK_IDLE_TIME = "120"; # default
# sxmo tries to determine device type from /proc/device-tree/compatible,
# but that doesn't seem to exist on NixOS? (or maybe it just doesn't exist
# on non-aarch64 builds).
# the device type informs (at least):
# - SXMO_WIFI_MODULE
# - SXMO_RTW_SCAN_INTERVAL
# - SXMO_TOUCHSCREEN_ID
# - SXMO_MONITOR
# - SXMO_ALSA_CONTROL_NAME
# - SXMO_SWAY_SCALE
# see <repo:mil/sxmo-utils:scripts/deviceprofiles>
# SXMO_DEVICE_NAME = "pine64,pinephone-1.2";
# if sxmo doesn't know the device, it can't decide whether to use one_button or three_button mode
# and so it just wouldn't handle any button inputs (sxmo_hook_inputhandler.sh not on path)
SXMO_DEVICE_NAME = "three_button_touchscreen";
};
package = (pkgs.sxmo-utils.override { preferSystemd = true; }).overrideAttrs (base: {
postPatch = (base.postPatch or "") + ''
# after volume-button navigation mode, restore full keyboard functionality
cp ${./xkb_mobile_normal_buttons} ./configs/xkb/xkb_mobile_normal_buttons
'';
});
};
}

View File

@@ -36,10 +36,15 @@
sops.secrets.colin-passwd.neededForUsers = true;
sane.gui.sxmo.enable = true;
# sane.programs.consoleUtils.enableFor.user.colin = false;
# sane.programs.guiApps.enableFor.user.colin = false;
# sane.gui.sxmo.enable = true;
sane.programs.sway.enableFor.user.colin = true;
sane.programs.swaylock.enableFor.user.colin = false; #< not usable on touch
sane.programs.schlock.enableFor.user.colin = true;
sane.programs.swayidle.config.actions.screenoff.delay = 300;
sane.programs.swayidle.config.actions.screenoff.enable = true;
sane.programs.sane-input-handler.enableFor.user.colin = true;
sane.programs.blueberry.enableFor.user.colin = false; # bluetooth manager: doesn't cross compile!
sane.programs.fcitx5.enableFor.user.colin = false; # does not cross compile
sane.programs.mercurial.enableFor.user.colin = false; # does not cross compile
sane.programs.nvme-cli.enableFor.system = false; # does not cross compile (libhugetlbfs)
@@ -52,7 +57,6 @@
# sane.programs.signal-desktop.config.autostart = true; # TODO: enable once electron stops derping.
# sane.programs."gnome.geary".config.autostart = true;
# sane.programs.calls.config.autostart = true;
sane.programs.mpv.config.vo = "wlshm"; #< see hosts/common/programs/mpv.nix for details
sane.programs.firefox.mime.priority = 300; # prefer other browsers when possible
# HACK/TODO: make `programs.P.env.VAR` behave according to `mime.priority`
@@ -124,42 +128,12 @@
# enable rotation sensor
hardware.sensor.iio.enable = true;
# inject specialized alsa configs via the environment.
# specifically, this gets the pinephone headphones & internal earpiece working.
# see pkgs/patched/alsa-ucm-conf for more info.
environment.variables.ALSA_CONFIG_UCM2 = "/run/current-system/sw/share/alsa/ucm2";
environment.pathsToLink = [ "/share/alsa/ucm2" ];
environment.systemPackages = [
(pkgs.alsa-ucm-conf-sane.override {
# internal speaker has a tendency to break :(
preferEarpiece = true;
})
];
systemd = let
ucm-env = config.environment.variables.ALSA_CONFIG_UCM2;
in {
# cribbed from <repo:nixos/mobile-nixos:modules/quirks/audio.nix>
# pipewire
user.services.pipewire.environment.ALSA_CONFIG_UCM2 = ucm-env;
user.services.pipewire-pulse.environment.ALSA_CONFIG_UCM2 = ucm-env;
user.services.wireplumber.environment.ALSA_CONFIG_UCM2 = ucm-env;
services.pipewire.environment.ALSA_CONFIG_UCM2 = ucm-env;
services.pipewire-pulse.environment.ALSA_CONFIG_UCM2 = ucm-env;
services.wireplumber.environment.ALSA_CONFIG_UCM2 = ucm-env;
# pulseaudio
# user.services.pulseaudio.environment.ALSA_CONFIG_UCM2 = ucm-env;
# services.pulseaudio.environment.ALSA_CONFIG_UCM2 = ucm-env;
# TODO: move elsewhere...
services.ModemManager.serviceConfig = {
# N.B.: the extra "" in ExecStart serves to force upstream ExecStart to be ignored
ExecStart = [ "" "${pkgs.modemmanager}/bin/ModemManager --debug" ];
# --debug sets DEBUG level logging: so reset
ExecStartPost = [ "${pkgs.modemmanager}/bin/mmcli --set-logging=INFO" ];
};
# TODO: move elsewhere...
systemd.services.ModemManager.serviceConfig = {
# N.B.: the extra "" in ExecStart serves to force upstream ExecStart to be ignored
ExecStart = [ "" "${pkgs.modemmanager}/bin/ModemManager --debug" ];
# --debug sets DEBUG level logging: so reset
ExecStartPost = [ "${pkgs.modemmanager}/bin/mmcli --set-logging=INFO" ];
};
services.udev.extraRules = let

View File

@@ -85,6 +85,7 @@ in
"lima.sched_timeout_ms=2000"
];
services.xserver.displayManager.job.preStart = ensureHWReady;
systemd.services.greetd.preStart = ensureHWReady;
# services.xserver.displayManager.job.preStart = ensureHWReady;
# systemd.services.greetd.preStart = ensureHWReady;
systemd.services.unl0kr.preStart = ensureHWReady;
}

View File

@@ -24,73 +24,22 @@
backlight = "backlight"; # /sys/class/backlight/*backlight*/brightness
};
sane.gui.sxmo = {
nogesture = true;
settings = {
### hardware: touch screen
SXMO_LISGD_INPUT_DEVICE = "/dev/input/by-path/platform-1c2ac00.i2c-event";
# vol and power are detected correctly by upstream
sane.programs.alacritty.config.fontSize = 9;
### preferences
DEFAULT_COUNTRY = "US";
sane.programs.sway.config = {
font = "pango:monospace 10";
mod = "Mod1"; # prefer Alt
workspace_layout = "tabbed";
};
SXMO_AUTOROTATE = "1"; # enable auto-rotation at launch. has no meaning in stock/upstream sxmo-utils
# BEMENU lines (wayland DMENU):
# - camera is 9th entry
# - flashlight is 10th entry
# - config is 14th entry. inside that:
# - autorotate is 11th entry
# - system menu is 19th entry
# - close is 20th entry
# - power is 15th entry
# - close is 16th entry
SXMO_BEMENU_LANDSCAPE_LINES = "11"; # default 8
SXMO_BEMENU_PORTRAIT_LINES = "16"; # default 16
SXMO_LOCK_IDLE_TIME = "15"; # how long between screenoff -> lock -> back to screenoff (default: 8)
# gravity: how far to tilt the device before the screen rotates
# for a given setting, normal <-> invert requires more movement then left <-> right
# i.e. the settingd doesn't feel completely symmetric
# SXMO_ROTATION_GRAVITY default is 16374
# SXMO_ROTATION_GRAVITY = "12800"; # uncomfortably high
# SXMO_ROTATION_GRAVITY = "12500"; # kinda uncomfortable when walking
SXMO_ROTATION_GRAVITY = "12000";
SXMO_SCREENSHOT_DIR = "/home/colin/Pictures"; # default: "$HOME"
# sway/wayland scaling:
# - conflicting info out there on how scaling actually works
# at the least, for things where it matters (mpv), it seems like scale settings have 0 effect on perf
# ways to enforce scaling:
# - <https://wiki.archlinux.org/title/HiDPI>
# - `swaymsg -- output DSI-1 scale 2.0` (scales everything)
# - `dconf write /org/gnome/desktop/interface/text-scaling-factor 2.0` (scales ONLY TEXT)
# - `GDK_DPI_SCALE=2.0` (scales ONLY TEXT)
#
# application notes:
# - cozy: in landscape, playback position is not visible unless scale <= 1.7
# - if in a tab, then scale 1.6 is the max
# SXMO_SWAY_SCALE = "1.5"; # hard to press gPodder icons
SXMO_SWAY_SCALE = "1.6";
# SXMO_SWAY_SCALE = "1.8";
# SXMO_SWAY_SCALE = "2";
SXMO_WORKSPACE_WRAPPING = "5"; # how many workspaces. default: 4
# wvkbd layers:
# - full
# - landscape
# - special (e.g. coding symbols like ~)
# - emoji
# - nav
# - simple (like landscape, but no parens/tab/etc; even fewer chars)
# - simplegrid (simple, but grid layout)
# - dialer (digits)
# - cyrillic
# - arabic
# - persian
# - greek
# - georgian
WVKBD_LANDSCAPE_LAYERS = "landscape,special,emoji";
WVKBD_LAYERS = "full,special,emoji";
};
sane.programs.waybar.config = {
fontSize = 14;
height = 26;
persistWorkspaces = [ "1" "2" "3" "4" "5" ];
modules.media = false;
modules.network = false;
modules.perf = false;
modules.windowTitle = false;
# TODO: show modem state
};
}

View File

@@ -6,7 +6,7 @@
boot.loader.efi.canTouchEfiVariables = false;
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
sane.persist.enable = false;
sane.persist.enable = false; # what we mean here is that the image is immutable; `/` is still tmpfs.
sane.nixcache.enable = false; # don't want to be calling out to dead machines that we're *trying* to rescue
# auto-login at shell

View File

@@ -82,34 +82,34 @@
};
sane.fs."/mnt/usb-hdd".mount = {};
sane.persist.sys.byStore.plaintext = [
# TODO: this is overly broad; only need media and share directories to be persisted
{ user = "colin"; group = "users"; path = "/var/lib/uninsane"; method = "bind"; }
];
# force some problematic directories to always get correct permissions:
sane.fs."/var/lib/uninsane/media".dir.acl = {
user = "colin"; group = "media"; mode = "0775";
};
sane.fs."/var/lib/uninsane/media/archive".dir = {};
sane.persist.sys.byStore.plaintext = [{
path = "/var/media";
method = "bind"; #< this HAS to be `bind` if we're going to persist the whole thing but create subdirs, as below.
user = "colin";
group = "media";
mode = "0755";
}];
sane.fs."/var/media/archive".dir = {};
# this is file.text instead of symlink.text so that it may be read over a remote mount (where consumers might not have any /nix/store/.../README.md path)
sane.fs."/var/lib/uninsane/media/archive/README.md".file.text = ''
sane.fs."/var/media/archive/README.md".file.text = ''
this directory is for media i wish to remove from my library,
but keep for a short time in case i reverse my decision.
treat it like a system trash can.
'';
sane.fs."/var/lib/uninsane/media/Books".dir = {};
sane.fs."/var/lib/uninsane/media/Books/Audiobooks".dir = {};
sane.fs."/var/lib/uninsane/media/Books/Books".dir = {};
sane.fs."/var/lib/uninsane/media/Books/Visual".dir = {};
sane.fs."/var/lib/uninsane/media/collections".dir = {};
sane.fs."/var/lib/uninsane/media/datasets".dir = {};
sane.fs."/var/lib/uninsane/media/freeleech".dir = {};
sane.fs."/var/lib/uninsane/media/Music".dir = {};
sane.fs."/var/lib/uninsane/media/Pictures".dir = {};
sane.fs."/var/lib/uninsane/media/Videos".dir = {};
sane.fs."/var/lib/uninsane/media/Videos/Film".dir = {};
sane.fs."/var/lib/uninsane/media/Videos/Shows".dir = {};
sane.fs."/var/lib/uninsane/media/Videos/Talks".dir = {};
sane.fs."/var/media/Books".dir = {};
sane.fs."/var/media/Books/Audiobooks".dir = {};
sane.fs."/var/media/Books/Books".dir = {};
sane.fs."/var/media/Books/Visual".dir = {};
sane.fs."/var/media/collections".dir = {};
sane.fs."/var/media/datasets".dir = {};
sane.fs."/var/media/freeleech".dir = {};
sane.fs."/var/media/Music".dir = {};
sane.fs."/var/media/Pictures".dir = {};
sane.fs."/var/media/Videos".dir = {};
sane.fs."/var/media/Videos/Film".dir = {};
sane.fs."/var/media/Videos/Shows".dir = {};
sane.fs."/var/media/Videos/Talks".dir = {};
# this is file.text instead of symlink.text so that it may be read over a remote mount (where consumers might not have any /nix/store/.../README.md path)
sane.fs."/var/lib/uninsane/datasets/README.md".file.text = ''
this directory may seem redundant with ../media/datasets. it isn't.
@@ -122,19 +122,19 @@
user = "colin";
group = "users";
mode = "0777";
path = "/var/lib/uninsane/media/Videos";
path = "/var/media/Videos";
}
{
user = "colin";
group = "users";
mode = "0777";
path = "/var/lib/uninsane/media/freeleech";
path = "/var/media/freeleech";
}
{
user = "colin";
group = "users";
mode = "0777";
path = "/var/lib/uninsane/media/datasets";
mode = "0775";
path = "/var/lib/uninsane/datasets";
}
];

View File

@@ -9,7 +9,7 @@
fileSystems."/var/export/media" = {
# everything in here could be considered publicly readable (based on the viewer's legal jurisdiction)
device = "/var/lib/uninsane/media";
device = "/var/media";
options = [ "rbind" ];
};
# fileSystems."/var/export/playground" = {

View File

@@ -1,5 +1,6 @@
{ lib, ... }:
lib.mkIf false #< i don't actively use navidrome
{
sane.persist.sys.byStore.plaintext = [
{ user = "navidrome"; group = "navidrome"; path = "/var/lib/navidrome"; method = "bind"; }
@@ -9,7 +10,7 @@
# docs: https://www.navidrome.org/docs/usage/configuration-options/
Address = "127.0.0.1";
Port = 4533;
MusicFolder = "/var/lib/uninsane/media/Music";
MusicFolder = "/var/media/Music";
CovertArtPriority = "*.jpg, *.JPG, *.png, *.PNG, embedded";
AutoImportPlaylists = false;
ScanSchedule = "@every 1h";

View File

@@ -55,8 +55,8 @@ in
# web blog/personal site
# alternative way to link stuff into the share:
# sane.fs."/var/lib/uninsane/share/Ubunchu".mount.bind = "/var/lib/uninsane/media/Books/Visual/HiroshiSeo/Ubunchu";
# sane.fs."/var/lib/uninsane/media/Books/Visual/HiroshiSeo/Ubunchu".dir = {};
# sane.fs."/var/www/sites/uninsane.org/share/Ubunchu".mount.bind = "/var/media/Books/Visual/HiroshiSeo/Ubunchu";
# sane.fs."/var/media/Books/Visual/HiroshiSeo/Ubunchu".dir = {};
services.nginx.virtualHosts."uninsane.org" = publog {
# a lot of places hardcode https://uninsane.org,
# and then when we mix http + non-https, we get CORS violations

View File

@@ -44,13 +44,13 @@
# [Alias]/path/on/disk
# NOTE: Music library is quick to scan; videos take a solid 10min to scan.
# TODO: re-enable the other libraries
# "[Audioooks]/var/lib/uninsane/media/Books/Audiobooks"
# "[Books]/var/lib/uninsane/media/Books/Books"
# "[Manga]/var/lib/uninsane/media/Books/Visual"
# "[games]/var/lib/uninsane/media/games"
"[Music]/var/lib/uninsane/media/Music"
# "[Film]/var/lib/uninsane/media/Videos/Film"
# "[Shows]/var/lib/uninsane/media/Videos/Shows"
# "[Audioooks]/var/media/Books/Audiobooks"
# "[Books]/var/media/Books/Books"
# "[Manga]/var/media/Books/Visual"
# "[games]/var/media/games"
"[Music]/var/media/Music"
# "[Film]/var/media/Videos/Film"
# "[Shows]/var/media/Videos/Shows"
];
# directories.downloads = "..." # TODO
# directories.incomplete = "..." # TODO

View File

@@ -72,8 +72,8 @@ in
# see: https://git.zknt.org/mirror/transmission/commit/cfce6e2e3a9b9d31a9dafedd0bdc8bf2cdb6e876?lang=bg-BG
anti-brute-force-enabled = false;
download-dir = "/var/lib/uninsane/media";
incomplete-dir = "/var/lib/uninsane/media/incomplete";
download-dir = "/var/media";
incomplete-dir = "/var/media/incomplete";
# transmission regularly fails to move stuff from the incomplete dir to the main one, so disable:
# TODO: uncomment this line!
incomplete-dir-enabled = false;

View File

@@ -43,17 +43,6 @@
fi
'';
};
system.activationScripts.notifyActive = {
text = ''
# send a notification to any sway users logged in, that the system has been activated/upgraded.
# this probably doesn't work if more than one sway session exists on the system.
_notifyActiveSwaySock="$(echo /run/user/*/sway-ipc*.sock)"
if [ -e "$_notifyActiveSwaySock" ]; then
SWAYSOCK="$_notifyActiveSwaySock" ${config.sane.programs.sway.packageUnwrapped}/bin/swaymsg -- exec \
"${pkgs.libnotify}/bin/notify-send 'nixos activated' 'version: $(cat $systemConfig/nixos-version)'"
fi
'';
};
# link debug symbols into /run/current-system/sw/lib/debug
# hopefully picked up by gdb automatically?

View File

@@ -121,6 +121,7 @@ let
texts = [
(fromDb "acoup.blog/feed") # history, states. author: <https://historians.social/@bretdevereaux/following>
(fromDb "amosbbatto.wordpress.com" // tech)
(fromDb "anish.lakhwara.com" // tech)
(fromDb "applieddivinitystudies.com" // rat)
(fromDb "artemis.sh" // tech)
(fromDb "ascii.textfiles.com" // tech) # Jason Scott
@@ -161,6 +162,7 @@ let
(fromDb "palladiummag.com" // uncat)
(fromDb "philosopher.coach" // rat) # Peter Saint-Andre -- side project of stpeter.im
(fromDb "pomeroyb.com" // tech)
(fromDb "postmarketos.org/blog" // tech)
(fromDb "preposterousuniverse.com" // rat) # Sean Carroll
(fromDb "profectusmag.com" // uncat)
(fromDb "project-insanity.org" // tech) # shared blog by a few NixOS devs, notably onny
@@ -172,9 +174,11 @@ let
(fromDb "sagacioussuricata.com" // tech) # ian (Sanctuary)
(fromDb "semiaccurate.com" // tech)
(fromDb "sideways-view.com" // rat) # Paul Christiano
(fromDb "slatecave.net" // tech)
(fromDb "slimemoldtimemold.com" // rat)
(fromDb "spectrum.ieee.org" // tech)
(fromDb "stpeter.im/atom.xml" // pol)
(fromDb "thediff.co" // pol) # Byrne Hobart
# (fromDb "theregister.com" // tech)
(fromDb "thisweek.gnome.org" // tech)
(fromDb "tuxphones.com" // tech)
@@ -182,17 +186,15 @@ let
(fromDb "unintendedconsequenc.es" // rat)
# (fromDb "vitalik.ca" // tech) # moved to vitalik.eth.limo
(fromDb "vitalik.eth.limo" // tech) # Vitalik Buterin
(fromDb "webcurious.co.uk" // uncat)
# (fromDb "webcurious.co.uk" // uncat) # link aggregator; defunct?
(fromDb "xn--gckvb8fzb.com" // tech)
(mkSubstack "astralcodexten" // rat // daily) # Scott Alexander
(mkSubstack "byrnehobart" // pol // infrequent)
# (mkSubstack "doomberg" // tech // weekly) # articles are all pay-walled
(mkSubstack "eliqian" // rat // weekly)
(mkSubstack "oversharing" // pol // daily)
(mkSubstack "samkriss" // humor // infrequent)
(mkText "http://benjaminrosshoffman.com/feed" // pol // weekly)
(mkText "http://boginjr.com/feed" // tech // infrequent)
(mkText "https://anish.lakhwara.com/home.html" // tech // weekly)
(mkText "https://forum.merveilles.town/rss.xml" // pol // infrequent) #quality RSS list here: <https://forum.merveilles.town/thread/57/share-your-rss-feeds%21-6/>
# (mkText "https://github.com/Kaiteki-Fedi/Kaiteki/commits/master.atom" // tech // infrequent)
(mkText "https://jvns.ca/atom.xml" // tech // weekly) # Julia Evans
@@ -211,6 +213,7 @@ let
(fromDb "youtube.com/@Exurb1a")
(fromDb "youtube.com/@hbomberguy")
(fromDb "youtube.com/@JackStauber")
(fromDb "youtube.com/@NativLang")
(fromDb "youtube.com/@PolyMatter")
# (fromDb "youtube.com/@rossmanngroup" // pol // tech) # Louis Rossmann
(fromDb "youtube.com/@TechnologyConnections" // tech)

View File

@@ -79,11 +79,6 @@
HandleLidSwitch=lock
'';
# some packages build only if binfmt *isn't* present
nix.settings.system-features = lib.mkIf (config.boot.binfmt.emulatedSystems == []) [
"no-binfmt"
];
# services.snapper.configs = {
# root = {
# subvolume = "/";

View File

@@ -1,4 +1,4 @@
{ config, ... }:
{ config, lib, ... }:
{
sane.user.persist.byStore.plaintext = [
"archive"
@@ -29,14 +29,17 @@
];
# convenience
sane.user.fs.".persist/private".symlink.target = config.sane.persist.stores.private.origin;
sane.user.fs.".persist/plaintext".symlink.target = config.sane.persist.stores.plaintext.origin;
sane.user.fs.".persist/ephemeral".symlink.target = config.sane.persist.stores.cryptClearOnBoot.origin;
sane.user.fs = let
persistEnabled = config.sane.persist.enable;
in {
".persist/private" = lib.mkIf persistEnabled { symlink.target = config.sane.persist.stores.private.origin; };
".persist/plaintext" = lib.mkIf persistEnabled { symlink.target = config.sane.persist.stores.plaintext.origin; };
".persist/ephemeral" = lib.mkIf persistEnabled { symlink.target = config.sane.persist.stores.cryptClearOnBoot.origin; };
sane.user.fs."nixos".symlink.target = "dev/nixos";
"nixos".symlink.target = "dev/nixos";
sane.user.fs."Books/servo".symlink.target = "/mnt/servo/media/Books";
sane.user.fs."Videos/servo".symlink.target = "/mnt/servo/media/Videos";
# sane.user.fs."Music/servo".symlink.target = "/mnt/servo/media/Music";
sane.user.fs."Pictures/servo-macros".symlink.target = "/mnt/servo/media/Pictures/macros";
"Books/servo".symlink.target = "/mnt/servo/media/Books";
"Videos/servo".symlink.target = "/mnt/servo/media/Videos";
"Pictures/servo-macros".symlink.target = "/mnt/servo/media/Pictures/macros";
};
}

View File

@@ -53,8 +53,9 @@
# allow `nix-shell` (and probably nix-index?) to locate our patched and custom packages.
# this is actually a no-op, and the real action happens in assigning `nix.settings.nix-path`.
nix.nixPath = [
nix.nixPath = (lib.optionals config.sane.enableSlowPrograms [
"nixpkgs=${pkgs.path}"
]) ++ [
# note the import starts at repo root: this allows `./overlay/default.nix` to access the stuff at the root
# "nixpkgs-overlays=${../../..}/hosts/common/nix-path/overlay"
# as long as my system itself doesn't rely on NIXPKGS at runtime, we can point the overlays to git
@@ -63,7 +64,13 @@
];
# ensure new deployments have a source of this repo with which they can bootstrap.
environment.etc."nixos".source = ../../..;
# this however changes on every commit and can be slow to copy for e.g. `moby`.
environment.etc."nixos" = lib.mkIf config.sane.enableSlowPrograms {
source = ../../..;
};
environment.etc."nix/registry.json" = lib.mkIf (!config.sane.enableSlowPrograms) {
enable = false;
};
systemd.services.nix-daemon.serviceConfig = {
# the nix-daemon manages nix builders

View File

@@ -13,7 +13,7 @@
"/run/current-system/sw"
];
# NIXPKGS_CONFIG defaults to "/etc/nix/nixpkgs-config.nix", for idfk why.
# NIXPKGS_CONFIG defaults to "/etc/nix/nixpkgs-config.nix" in <nixos/modules/programs/environment.nix>.
# that's never existed on my system and everything does fine without it set empty (no nixpkgs API to forcibly *unset* it).
environment.variables.NIXPKGS_CONFIG = lib.mkForce "";
# XDG_CONFIG_DIRS defaults to "/etc/xdg", which doesn't exist.
@@ -42,4 +42,26 @@
# so as to inform when trying to run a non-nixos binary?
# IMO that's confusing: i thought /lib/ld-linux.so was some file actually required by nix.
environment.stub-ld.enable = false;
# `less.enable` sets LESSKEYIN_SYSTEM, LESSOPEN, LESSCLOSE env vars, which does confusing "lesspipe" things, so disable that.
# it's enabled by default from `<nixos/modules/programs/environment.nix>`, who also sets `PAGER="less"` and `EDITOR="nano"` (keep).
programs.less.enable = lib.mkForce false;
environment.variables.PAGER = lib.mkOverride 900 ""; # mkDefault sets 1000. non-override is 100. 900 will beat the nixpkgs `mkDefault` but not anyone else.
environment.variables.EDITOR = lib.mkOverride 900 "";
# several packages (dconf, modemmanager, networkmanager, gvfs, polkit, udisks, bluez/blueman, feedbackd, etc)
# will add themselves to the dbus search path.
# i prefer dbus to only search XDG paths (/share/dbus-1) for service files, as that's more introspectable.
# see: <repo:nixos/nixpkgs:nixos/modules/services/system/dbus.nix>
# TODO: sandbox dbus? i pretty explicitly don't want to use it as a launcher.
services.dbus.packages = lib.mkForce [
"/run/current-system/sw"
# config.system.path
# pkgs.dbus
# pkgs.polkit.out
# pkgs.modemmanager
# pkgs.networkmanager
# pkgs.udisks
# pkgs.wpa_supplicant
];
}

View File

@@ -4,7 +4,7 @@
{
sane.programs.aerc = {
sandbox.method = "bwrap";
sandbox.wrapperType = "inplace";
sandbox.wrapperType = "inplace"; #< /share/aerc/aerc.conf refers to other /share files by absolute path
sandbox.net = "clearnet";
secrets.".config/aerc/accounts.conf" = ../../../secrets/common/aerc_accounts.conf.bin;
mime.associations."x-scheme-handler/mailto" = "aerc.desktop";

View File

@@ -3,14 +3,28 @@
# - `man 5 alacritty`
# - defaults: <https://github.com/alacritty/alacritty/releases> -> alacritty.yml
# - irc: #alacritty on libera.chat
{ lib, ... }:
{ config, lib, ... }:
let
cfg = config.sane.programs.alacritty;
in
{
sane.programs.alacritty = {
configOption = with lib; mkOption {
default = {};
type = types.submodule {
options.fontSize = mkOption {
type = types.int;
default = 14;
};
};
};
sandbox.enable = false;
env.TERMINAL = lib.mkDefault "alacritty";
fs.".config/alacritty/alacritty.toml".symlink.text = ''
[font]
size = 14
size = ${builtins.toString cfg.config.fontSize}
[[keyboard.bindings]]
mods = "Control"
@@ -36,6 +50,21 @@
mods = "Control|Shift"
key = "PageDown"
action = "ScrollPageDown"
# disable OS shortcuts which leak through...
# see sway config or sane-input-handler for more info on why these leak through
[[keyboard.bindings]]
key = "AudioVolumeUp"
action = "None"
[[keyboard.bindings]]
key = "AudioVolumeDown"
action = "None"
[[keyboard.bindings]]
key = "Power"
action = "None"
[[keyboard.bindings]]
key = "PowerOff"
action = "None"
'';
};
}

View File

@@ -0,0 +1,65 @@
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.alsa-ucm-conf;
in
{
sane.programs.alsa-ucm-conf = {
configOption = with lib; mkOption {
default = {};
type = types.submodule {
options.preferEarpiece = mkOption {
type = types.bool;
default = true;
};
};
};
# upstream alsa ships with PinePhone audio configs, but they don't actually produce sound.
# see: <https://github.com/alsa-project/alsa-ucm-conf/pull/134>
# these audio files come from some revision of:
# - <https://gitlab.manjaro.org/manjaro-arm/packages/community/phosh/alsa-ucm-pinephone>
#
# alternative to patching is to plumb `ALSA_CONFIG_UCM2 = "${./ucm2}"` environment variable into the relevant places
# e.g. `systemd.services.pulseaudio.environment`.
# that leaves more opportunity for gaps (i.e. missing a service),
# on the other hand this method causes about 500 packages to be rebuilt (including qt5 and webkitgtk).
#
# note that with these files, the following audio device support:
# - headphones work.
# - "internal earpiece" works.
# - "internal speaker" doesn't work (but that's probably because i broke the ribbon cable)
# - "analog output" doesn't work.
packageUnwrapped = pkgs.alsa-ucm-conf.overrideAttrs (upstream: {
postPatch = (upstream.postPatch or "") + ''
cp ${./ucm2/PinePhone}/* ucm2/Allwinner/A64/PinePhone/
# fix the self-contained ucm files i source from to have correct path within the alsa-ucm-conf source tree
substituteInPlace ucm2/Allwinner/A64/PinePhone/PinePhone.conf \
--replace 'HiFi.conf' '/Allwinner/A64/PinePhone/HiFi.conf'
substituteInPlace ucm2/Allwinner/A64/PinePhone/PinePhone.conf \
--replace 'VoiceCall.conf' '/Allwinner/A64/PinePhone/VoiceCall.conf'
'' + lib.optionalString cfg.config.preferEarpiece ''
# decrease the priority of the internal speaker so that sounds are routed
# to the earpiece by default.
# this is just personal preference.
substituteInPlace ucm2/Allwinner/A64/PinePhone/* \
--replace 'PlaybackPriority 300' 'PlaybackPriority 100'
'';
});
sandbox.enable = false; #< only provides #out/share/alsa
# alsa-lib package only looks in its $out/share/alsa to find runtime config data, by default.
# but ALSA_CONFIG_UCM2 is an env var that can override that.
# this is particularly needed by wireplumber;
# also *maybe* pipewire and pipewire-pulse.
# taken from <repo:nixos/mobile-nixos:modules/quirks/audio.nix>
env.ALSA_CONFIG_UCM2 = "/run/current-system/sw/share/alsa/ucm2";
enableFor.system = lib.mkIf (builtins.any (en: en) (builtins.attrValues cfg.enableFor.user)) true;
};
environment.pathsToLink = lib.mkIf cfg.enabled [
"/share/alsa/ucm2"
];
}

View File

@@ -31,7 +31,6 @@
};
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistWayland = true;
persist.byStore.plaintext = [

View File

@@ -62,6 +62,7 @@ in
# "iw"
"jq"
"killall"
"less"
# "libcap_ng" # for `netcap`
"lsof"
# "miniupnpc"
@@ -165,6 +166,7 @@ in
];
consoleMediaUtils = declPackageSet [
"blast-ugjka" # cast audio to UPNP/DLNA devices (via pulseaudio sink)
# "catt" # cast videos to chromecast
"ffmpeg"
"go2tv" # cast videos to UPNP/DLNA device (i.e. tv).
@@ -203,17 +205,17 @@ in
# INDIVIDUAL PACKAGE DEFINITIONS
alsaUtils.sandbox.method = "landlock";
alsaUtils.sandbox.wrapperType = "wrappedDerivation";
alsaUtils.sandbox.whitelistAudio = true; #< not strictly necessary?
backblaze-b2 = {};
blanket.sandbox.method = "bwrap";
blanket.sandbox.wrapperType = "wrappedDerivation";
blanket.sandbox.whitelistAudio = true;
# blanket.sandbox.whitelistDbus = [ "user" ]; # TODO: untested
blanket.sandbox.whitelistWayland = true;
blueberry.sandbox.method = "bwrap";
blueberry.sandbox.wrapperType = "inplace"; # /etc/xdg/autostart hardcodes paths
blueberry.sandbox.wrapperType = "inplace"; #< various /lib scripts refer to the bins by full path
blueberry.sandbox.whitelistWayland = true;
blueberry.sandbox.extraPaths = [
"/dev/rfkill"
@@ -223,11 +225,9 @@ in
];
bridge-utils.sandbox.method = "bwrap"; #< bwrap, landlock: both work
bridge-utils.sandbox.wrapperType = "wrappedDerivation";
bridge-utils.sandbox.net = "all";
brightnessctl.sandbox.method = "landlock"; # also bwrap, but landlock is more responsive
brightnessctl.sandbox.wrapperType = "wrappedDerivation";
brightnessctl.sandbox.extraPaths = [
"/sys/class/backlight"
"/sys/class/leds"
@@ -236,16 +236,16 @@ in
brightnessctl.sandbox.whitelistDbus = [ "system" ];
btrfs-progs.sandbox.method = "bwrap"; #< bwrap, landlock: both work
btrfs-progs.sandbox.wrapperType = "wrappedDerivation";
btrfs-progs.sandbox.autodetectCliPaths = "existing"; # e.g. `btrfs filesystem df /my/fs`
"cacert.unbundled".sandbox.enable = false;
cargo.persist.byStore.plaintext = [ ".cargo" ];
clang = {};
# cryptsetup: typical use is `cryptsetup open /dev/loopxyz mappedName`, and creates `/dev/mapper/mappedName`
cryptsetup.sandbox.method = "landlock";
cryptsetup.sandbox.wrapperType = "wrappedDerivation";
cryptsetup.sandbox.extraPaths = [
"/dev/mapper"
"/dev/random"
@@ -259,12 +259,10 @@ in
cryptsetup.sandbox.autodetectCliPaths = "existing";
ddrescue.sandbox.method = "landlock"; # TODO:sandbox: untested
ddrescue.sandbox.wrapperType = "wrappedDerivation";
ddrescue.sandbox.autodetectCliPaths = "existingOrParent";
# auth token, preferences
delfin.sandbox.method = "bwrap";
delfin.sandbox.wrapperType = "wrappedDerivation";
delfin.sandbox.whitelistAudio = true;
delfin.sandbox.whitelistDbus = [ "user" ]; # else `mpris` plugin crashes the player
delfin.sandbox.whitelistDri = true;
@@ -273,7 +271,6 @@ in
delfin.persist.byStore.private = [ ".config/delfin" ];
dig.sandbox.method = "bwrap";
dig.sandbox.wrapperType = "wrappedDerivation";
dig.sandbox.net = "all";
# creds, but also 200 MB of node modules, etc
@@ -289,29 +286,28 @@ in
dtc.sandbox.autodetectCliPaths = true; # TODO:sandbox: untested
dtrx.sandbox.method = "bwrap";
dtrx.sandbox.wrapperType = "wrappedDerivation";
dtrx.sandbox.whitelistPwd = true;
dtrx.sandbox.autodetectCliPaths = "existing"; #< for the archive
duplicity = {};
e2fsprogs.sandbox.method = "landlock";
e2fsprogs.sandbox.wrapperType = "wrappedDerivation";
e2fsprogs.sandbox.autodetectCliPaths = "existing";
efibootmgr.sandbox.method = "landlock";
efibootmgr.sandbox.wrapperType = "wrappedDerivation";
efibootmgr.sandbox.extraPaths = [
"/sys/firmware/efi"
];
eg25-control = {};
electrum.sandbox.method = "bwrap"; # TODO:sandbox: untested
electrum.sandbox.wrapperType = "wrappedDerivation";
electrum.sandbox.net = "all"; # TODO: probably want to make this run behind a VPN, always
electrum.sandbox.whitelistWayland = true;
electrum.persist.byStore.cryptClearOnBoot = [ ".electrum" ]; #< TODO: use XDG dirs!
endless-sky.persist.byStore.plaintext = [ ".local/share/endless-sky" ];
endless-sky.sandbox.method = "bwrap";
endless-sky.sandbox.wrapperType = "wrappedDerivation";
endless-sky.sandbox.whitelistAudio = true;
endless-sky.sandbox.whitelistDri = true;
endless-sky.sandbox.whitelistWayland = true;
@@ -322,14 +318,12 @@ in
emote.persist.byStore.plaintext = [ ".local/share/Emote" ];
ethtool.sandbox.method = "landlock";
ethtool.sandbox.wrapperType = "wrappedDerivation";
ethtool.sandbox.capabilities = [ "net_admin" ];
# eza `ls` replacement
# landlock is OK, only `whitelistPwd` doesn't make the intermediate symlinks traversable, so it breaks on e.g. ~/Videos/servo/Shows/foo
# eza.sandbox.method = "landlock";
eza.sandbox.method = "bwrap";
eza.sandbox.wrapperType = "wrappedDerivation"; # slow to build
eza.sandbox.autodetectCliPaths = true;
eza.sandbox.whitelistPwd = true;
eza.sandbox.extraHomePaths = [
@@ -339,11 +333,9 @@ in
];
fatresize.sandbox.method = "landlock";
fatresize.sandbox.wrapperType = "wrappedDerivation";
fatresize.sandbox.autodetectCliPaths = "parent"; # /dev/sda1 -> needs /dev/sda
fd.sandbox.method = "landlock";
fd.sandbox.wrapperType = "wrappedDerivation"; # slow to build
fd.sandbox.autodetectCliPaths = true;
fd.sandbox.whitelistPwd = true;
fd.sandbox.extraHomePaths = [
@@ -353,15 +345,12 @@ in
];
ffmpeg.sandbox.method = "bwrap";
ffmpeg.sandbox.wrapperType = "wrappedDerivation"; # slow to build
ffmpeg.sandbox.autodetectCliPaths = "existingFileOrParent"; # it outputs uncreated files -> parent dir needs mounting
file.sandbox.method = "bwrap";
file.sandbox.wrapperType = "wrappedDerivation";
file.sandbox.autodetectCliPaths = true;
findutils.sandbox.method = "bwrap";
findutils.sandbox.wrapperType = "wrappedDerivation";
findutils.sandbox.autodetectCliPaths = true;
findutils.sandbox.whitelistPwd = true;
findutils.sandbox.extraHomePaths = [
@@ -373,14 +362,12 @@ in
fluffychat-moby.persist.byStore.plaintext = [ ".local/share/chat.fluffy.fluffychat" ];
font-manager.sandbox.method = "bwrap";
font-manager.sandbox.wrapperType = "inplace"; # .desktop and dbus .service file refer to /libexec
font-manager.packageUnwrapped = pkgs.font-manager.override {
font-manager.packageUnwrapped = pkgs.rmDbusServicesInPlace (pkgs.font-manager.override {
# build without the "Google Fonts" integration feature, to save closure / avoid webkitgtk_4_0
withWebkit = false;
};
});
forkstat.sandbox.method = "landlock"; #< doesn't seem to support bwrap
forkstat.sandbox.wrapperType = "wrappedDerivation";
forkstat.sandbox.extraConfig = [
"--sane-sandbox-keep-namespace" "pid"
];
@@ -388,12 +375,7 @@ in
"/proc"
];
# fuzzel: TODO: re-enable sandbox. i use fuzzel both as an entry system (snippets) AND an app-launcher.
# as an app-launcher, it cannot be sandboxed without over-restricting the app it launches.
# should probably make it not be an app-launcher
fuzzel.sandbox.enable = false;
fuzzel.sandbox.method = "bwrap"; #< landlock nearly works, but unable to open ~/.cache
fuzzel.sandbox.wrapperType = "wrappedDerivation";
fuzzel.sandbox.whitelistWayland = true;
fuzzel.persist.byStore.private = [
# this is a file of recent selections
@@ -401,20 +383,21 @@ in
];
gawk.sandbox.method = "bwrap"; # TODO:sandbox: untested
gawk.sandbox.wrapperType = "inplace"; # share/gawk libraries refer to /libexec
gawk.sandbox.wrapperType = "inplace"; # /share/gawk libraries refer to /libexec
gawk.sandbox.autodetectCliPaths = true;
gdb.sandbox.enable = false; # gdb doesn't sandbox well. i don't know how you could.
# gdb.sandbox.method = "landlock"; # permission denied when trying to attach, even as root
gdb.sandbox.wrapperType = "wrappedDerivation";
gdb.sandbox.autodetectCliPaths = true;
geoclue2-with-demo-agent = {};
# MS GitHub stores auth token in .config
# TODO: we can populate gh's stuff statically; it even lets us use the same oauth across machines
gh.persist.byStore.private = [ ".config/gh" ];
gimp.sandbox.method = "bwrap";
gimp.sandbox.wrapperType = "wrappedDerivation";
gimp.sandbox.net = "clearnet"; #< for Xwayland
gimp.sandbox.whitelistWayland = true;
gimp.sandbox.extraHomePaths = [
"Pictures/albums"
@@ -433,39 +416,32 @@ in
];
"gnome.gnome-calculator".sandbox.method = "bwrap";
"gnome.gnome-calculator".sandbox.wrapperType = "inplace"; # /libexec/gnome-calculator-search-provider
"gnome.gnome-calculator".sandbox.whitelistWayland = true;
# gnome-calendar surely has data to persist, but i use it strictly to do date math, not track events.
"gnome.gnome-calendar".sandbox.method = "bwrap";
"gnome.gnome-calendar".sandbox.wrapperType = "wrappedDerivation";
"gnome.gnome-calendar".sandbox.whitelistWayland = true;
"gnome.gnome-clocks".sandbox.method = "bwrap";
"gnome.gnome-clocks".sandbox.wrapperType = "wrappedDerivation";
"gnome.gnome-clocks".sandbox.whitelistWayland = true;
"gnome.gnome-clocks".suggestedPrograms = [ "dconf" ];
# gnome-disks
"gnome.gnome-disk-utility".sandbox.method = "bwrap";
"gnome.gnome-disk-utility".sandbox.wrapperType = "inplace"; # /etc/xdg/autostart
"gnome.gnome-disk-utility".sandbox.whitelistDbus = [ "system" ];
"gnome.gnome-disk-utility".sandbox.whitelistWayland = true;
# seahorse: dump gnome-keyring secrets.
# N.B.: it can also manage ~/.ssh keys, but i explicitly don't add those to the sandbox for now.
"gnome.seahorse".sandbox.method = "bwrap";
"gnome.seahorse".sandbox.wrapperType = "wrappedDerivation";
"gnome.seahorse".sandbox.whitelistDbus = [ "user" ];
"gnome.seahorse".sandbox.whitelistWayland = true;
gnome-2048.sandbox.method = "bwrap";
gnome-2048.sandbox.wrapperType = "wrappedDerivation";
gnome-2048.sandbox.whitelistWayland = true;
gnome-2048.persist.byStore.plaintext = [ ".local/share/gnome-2048/scores" ];
gnome-frog.sandbox.method = "bwrap";
gnome-frog.sandbox.wrapperType = "wrappedDerivation";
gnome-frog.sandbox.whitelistWayland = true;
gnome-frog.sandbox.whitelistDbus = [ "user" ];
gnome-frog.sandbox.extraPaths = [
@@ -492,11 +468,9 @@ in
# 2. no two shaded tiles can be direct N/S/E/W neighbors
# - win once (1) and (2) are satisfied
"gnome.hitori".sandbox.method = "bwrap";
"gnome.hitori".sandbox.wrapperType = "wrappedDerivation";
"gnome.hitori".sandbox.whitelistWayland = true;
gnugrep.sandbox.method = "bwrap";
gnugrep.sandbox.wrapperType = "wrappedDerivation";
gnugrep.sandbox.autodetectCliPaths = true;
gnugrep.sandbox.whitelistPwd = true;
gnugrep.sandbox.extraHomePaths = [
@@ -505,15 +479,24 @@ in
".persist/plaintext"
];
# sed: there is an edgecase of `--file=<foo>`, wherein `foo` won't be whitelisted.
gnused.sandbox.method = "bwrap";
gnused.sandbox.autodetectCliPaths = "existingFile";
gnused.sandbox.whitelistPwd = true; #< `-i` flag creates a temporary file in pwd (?) and then moves it.
gpsd = {};
gptfdisk.sandbox.method = "landlock";
gptfdisk.sandbox.wrapperType = "wrappedDerivation";
gptfdisk.sandbox.extraPaths = [
"/dev"
];
gptfdisk.sandbox.autodetectCliPaths = "existing"; #< sometimes you'll use gdisk on a device file.
grim.sandbox.method = "bwrap";
grim.sandbox.autodetectCliPaths = "existingOrParent";
grim.sandbox.whitelistWayland = true;
hase.sandbox.method = "bwrap";
hase.sandbox.wrapperType = "wrappedDerivation";
hase.sandbox.net = "clearnet";
hase.sandbox.whitelistAudio = true;
hase.sandbox.whitelistDri = true;
@@ -521,15 +504,12 @@ in
# hdparm: has to be run as sudo. e.g. `sudo hdparm -i /dev/sda`
hdparm.sandbox.method = "bwrap";
hdparm.sandbox.wrapperType = "wrappedDerivation";
hdparm.sandbox.autodetectCliPaths = true;
host.sandbox.method = "landlock";
host.sandbox.wrapperType = "wrappedDerivation";
host.sandbox.net = "all"; #< technically, only needs to contact localhost's DNS server
htop.sandbox.method = "landlock";
htop.sandbox.wrapperType = "wrappedDerivation";
htop.sandbox.extraPaths = [
"/proc"
"/sys/devices"
@@ -540,16 +520,13 @@ in
];
iftop.sandbox.method = "landlock";
iftop.sandbox.wrapperType = "wrappedDerivation";
iftop.sandbox.capabilities = [ "net_raw" ];
# inetutils: ping, ifconfig, hostname, traceroute, whois, ....
# N.B.: inetutils' `ping` is shadowed by iputils' ping (by nixos, intentionally).
inetutils.sandbox.method = "landlock"; # want to keep the same netns, at least.
inetutils.sandbox.wrapperType = "wrappedDerivation";
inkscape.sandbox.method = "bwrap";
inkscape.sandbox.wrapperType = "wrappedDerivation";
inkscape.sandbox.whitelistWayland = true;
inkscape.sandbox.extraHomePaths = [
"Pictures/albums"
@@ -565,7 +542,6 @@ in
inkscape.sandbox.autodetectCliPaths = true;
iotop.sandbox.method = "landlock";
iotop.sandbox.wrapperType = "wrappedDerivation";
iotop.sandbox.extraPaths = [
"/proc"
];
@@ -573,38 +549,31 @@ in
# provides `ip`, `routel`, others
iproute2.sandbox.method = "landlock";
iproute2.sandbox.wrapperType = "wrappedDerivation";
iproute2.sandbox.net = "all";
iproute2.sandbox.capabilities = [ "net_admin" ];
iptables.sandbox.method = "landlock";
iptables.sandbox.wrapperType = "wrappedDerivation";
iptables.sandbox.net = "all";
iptables.sandbox.capabilities = [ "net_admin" ];
# iputils provides `ping` (and arping, clockdiff, tracepath)
iputils.sandbox.method = "landlock";
iputils.sandbox.wrapperType = "wrappedDerivation";
iputils.sandbox.net = "all";
iputils.sandbox.capabilities = [ "net_raw" ];
iw.sandbox.method = "landlock";
iw.sandbox.wrapperType = "wrappedDerivation";
iw.sandbox.net = "all";
iw.sandbox.capabilities = [ "net_admin" ];
jq.sandbox.method = "bwrap";
jq.sandbox.wrapperType = "wrappedDerivation";
jq.sandbox.autodetectCliPaths = "existingFile";
killall.sandbox.method = "landlock";
killall.sandbox.wrapperType = "wrappedDerivation";
killall.sandbox.extraPaths = [
"/proc"
];
krita.sandbox.method = "bwrap";
krita.sandbox.wrapperType = "wrappedDerivation";
krita.sandbox.whitelistWayland = true;
krita.sandbox.autodetectCliPaths = "existing";
krita.sandbox.extraHomePaths = [
@@ -622,11 +591,9 @@ in
libcap_ng.sandbox.enable = false; # there's something about /proc/$pid/fd which breaks `readlink`/stat with every sandbox technique (except capsh-only)
libnotify.sandbox.method = "bwrap";
libnotify.sandbox.wrapperType = "wrappedDerivation";
libnotify.sandbox.whitelistDbus = [ "user" ]; # notify-send
losslesscut-bin.sandbox.method = "bwrap";
losslesscut-bin.sandbox.wrapperType = "wrappedDerivation";
losslesscut-bin.sandbox.extraHomePaths = [
"Music"
"Pictures/from" # videos from e.g. mobile phone
@@ -641,10 +608,11 @@ in
losslesscut-bin.sandbox.whitelistX = true;
lsof.sandbox.method = "capshonly"; # lsof doesn't sandbox under bwrap or even landlock w/ full access to /
lsof.sandbox.wrapperType = "wrappedDerivation";
lua = {};
"mate.engrampa".packageUnwrapped = pkgs.rmDbusServices pkgs.mate.engrampa;
"mate.engrampa".sandbox.method = "bwrap"; # TODO:sandbox: untested
"mate.engrampa".sandbox.wrapperType = "inplace";
"mate.engrampa".sandbox.whitelistWayland = true;
"mate.engrampa".sandbox.autodetectCliPaths = "existingOrParent";
"mate.engrampa".sandbox.extraHomePaths = [
@@ -657,7 +625,6 @@ in
];
mercurial.sandbox.method = "bwrap"; # TODO:sandbox: untested
mercurial.sandbox.wrapperType = "wrappedDerivation";
mercurial.sandbox.net = "clearnet";
mercurial.sandbox.whitelistPwd = true;
@@ -665,7 +632,6 @@ in
# XXX: is it really safe to persist this? it doesn't have info that could de-anonymize if captured?
monero-gui.persist.byStore.plaintext = [ ".bitmonero" ];
monero-gui.sandbox.method = "bwrap";
monero-gui.sandbox.wrapperType = "wrappedDerivation";
monero-gui.sandbox.net = "all";
monero-gui.sandbox.extraHomePaths = [
"records/finance/cryptocurrencies/monero"
@@ -674,20 +640,16 @@ in
mumble.persist.byStore.private = [ ".local/share/Mumble" ];
nano.sandbox.method = "bwrap";
nano.sandbox.wrapperType = "wrappedDerivation";
nano.sandbox.autodetectCliPaths = "existingFileOrParent";
netcat.sandbox.method = "landlock";
netcat.sandbox.wrapperType = "wrappedDerivation";
netcat.sandbox.net = "all";
nethogs.sandbox.method = "capshonly"; # *partially* works under landlock w/ full access to /
nethogs.sandbox.wrapperType = "wrappedDerivation";
nethogs.sandbox.capabilities = [ "net_admin" "net_raw" ];
# provides `arp`, `hostname`, `route`, `ifconfig`
nettools.sandbox.method = "landlock";
nettools.sandbox.wrapperType = "wrappedDerivation";
nettools.sandbox.net = "all";
nettools.sandbox.capabilities = [ "net_admin" "net_raw" ];
nettools.sandbox.extraPaths = [
@@ -695,7 +657,6 @@ in
];
networkmanagerapplet.sandbox.method = "bwrap";
networkmanagerapplet.sandbox.wrapperType = "wrappedDerivation";
networkmanagerapplet.sandbox.whitelistWayland = true;
networkmanagerapplet.sandbox.whitelistDbus = [ "system" ];
@@ -708,18 +669,17 @@ in
];
nmap.sandbox.method = "bwrap";
nmap.sandbox.wrapperType = "wrappedDerivation";
nmap.sandbox.net = "all"; # clearnet and lan
nmon.sandbox.method = "landlock";
nmon.sandbox.wrapperType = "wrappedDerivation";
nmon.sandbox.extraPaths = [
"/proc"
];
nodejs = {};
# `nvme list` only shows results when run as root.
nvme-cli.sandbox.method = "landlock";
nvme-cli.sandbox.wrapperType = "wrappedDerivation";
nvme-cli.sandbox.extraPaths = [
"/sys/devices"
"/sys/class/nvme"
@@ -731,25 +691,23 @@ in
# contains only `oathtool`, which i only use for evaluating TOTP codes from CLI/stdin
oath-toolkit.sandbox.method = "bwrap";
oath-toolkit.sandbox.wrapperType = "wrappedDerivation";
# settings (electron app)
obsidian.persist.byStore.plaintext = [ ".config/obsidian" ];
parted.sandbox.method = "landlock";
parted.sandbox.wrapperType = "wrappedDerivation";
parted.sandbox.extraPaths = [
"/dev"
];
parted.sandbox.autodetectCliPaths = "existing"; #< sometimes you'll use parted on a device file.
patchelf = {};
pavucontrol.sandbox.method = "bwrap";
pavucontrol.sandbox.wrapperType = "wrappedDerivation";
pavucontrol.sandbox.whitelistAudio = true;
pavucontrol.sandbox.whitelistWayland = true;
pciutils.sandbox.method = "landlock";
pciutils.sandbox.wrapperType = "wrappedDerivation";
pciutils.sandbox.extraPaths = [
"/sys/bus/pci"
"/sys/devices"
@@ -758,7 +716,6 @@ in
"perlPackages.FileMimeInfo".sandbox.enable = false; #< TODO: sandbox `mimetype` but not `mimeopen`.
powertop.sandbox.method = "landlock";
powertop.sandbox.wrapperType = "wrappedDerivation";
powertop.sandbox.capabilities = [ "ipc_lock" "sys_admin" ];
powertop.sandbox.extraPaths = [
"/proc"
@@ -767,18 +724,23 @@ in
"/sys/kernel"
];
# procps: free, pgrep, pidof, pkill, ps, pwait, top, uptime, couple others
procps.sandbox.method = "bwrap";
procps.sandbox.extraConfig = [
"--sane-sandbox-keep-namespace" "pid"
];
pstree.sandbox.method = "landlock";
pstree.sandbox.wrapperType = "wrappedDerivation";
pstree.sandbox.extraPaths = [
"/proc"
];
pulseaudio = {};
pulsemixer.sandbox.method = "landlock";
pulsemixer.sandbox.wrapperType = "wrappedDerivation";
pulsemixer.sandbox.whitelistAudio = true;
pwvucontrol.sandbox.method = "bwrap";
pwvucontrol.sandbox.wrapperType = "wrappedDerivation";
pwvucontrol.sandbox.whitelistAudio = true;
pwvucontrol.sandbox.whitelistWayland = true;
@@ -786,7 +748,6 @@ in
requests
]);
python3-repl.sandbox.method = "bwrap";
python3-repl.sandbox.wrapperType = "wrappedDerivation";
python3-repl.sandbox.net = "clearnet";
python3-repl.sandbox.extraHomePaths = [
"/"
@@ -797,20 +758,24 @@ in
qemu.slowToBuild = true;
rsync.sandbox.method = "bwrap";
rsync.sandbox.wrapperType = "wrappedDerivation";
rsync.sandbox.net = "clearnet";
rsync.sandbox.autodetectCliPaths = "existingOrParent";
rustc = {};
sane-open-desktop.sandbox.enable = false; #< trivial script, and all our deps are sandboxed
sane-open-desktop.suggestedPrograms = [
"gdbus"
];
screen.sandbox.enable = false; #< tty; needs to run anything
sequoia.sandbox.method = "bwrap"; # TODO:sandbox: untested
sequoia.sandbox.wrapperType = "wrappedDerivation"; # slow to build
sequoia.sandbox.whitelistPwd = true;
sequoia.sandbox.autodetectCliPaths = true;
shattered-pixel-dungeon.persist.byStore.plaintext = [ ".local/share/.shatteredpixel/shattered-pixel-dungeon" ];
shattered-pixel-dungeon.sandbox.method = "bwrap";
shattered-pixel-dungeon.sandbox.wrapperType = "wrappedDerivation";
shattered-pixel-dungeon.sandbox.whitelistAudio = true;
shattered-pixel-dungeon.sandbox.whitelistDri = true;
shattered-pixel-dungeon.sandbox.whitelistWayland = true;
@@ -818,6 +783,9 @@ in
# printer/filament settings
slic3r.persist.byStore.plaintext = [ ".Slic3r" ];
slurp.sandbox.method = "bwrap";
slurp.sandbox.whitelistWayland = true;
# use like `sudo smartctl /dev/sda -a`
smartmontools.sandbox.method = "landlock";
smartmontools.sandbox.wrapperType = "inplace"; # ships a script in /etc that calls into its bin
@@ -825,7 +793,6 @@ in
smartmontools.sandbox.capabilities = [ "sys_rawio" ];
sops.sandbox.method = "bwrap"; # TODO:sandbox: untested
sops.sandbox.wrapperType = "wrappedDerivation";
sops.sandbox.extraHomePaths = [
".config/sops"
"dev/nixos"
@@ -835,7 +802,6 @@ in
];
soundconverter.sandbox.method = "bwrap";
soundconverter.sandbox.wrapperType = "wrappedDerivation";
soundconverter.sandbox.whitelistWayland = true;
soundconverter.sandbox.extraHomePaths = [
"Music"
@@ -849,25 +815,23 @@ in
soundconverter.sandbox.autodetectCliPaths = "existingOrParent";
sox.sandbox.method = "bwrap";
sox.sandbox.wrapperType = "wrappedDerivation";
sox.sandbox.autodetectCliPaths = "existingFileOrParent";
sox.sandbox.whitelistAudio = true;
space-cadet-pinball.persist.byStore.plaintext = [ ".local/share/SpaceCadetPinball" ];
space-cadet-pinball.sandbox.method = "bwrap";
space-cadet-pinball.sandbox.wrapperType = "wrappedDerivation";
space-cadet-pinball.sandbox.whitelistAudio = true;
space-cadet-pinball.sandbox.whitelistDri = true;
space-cadet-pinball.sandbox.whitelistWayland = true;
speedtest-cli.sandbox.method = "bwrap";
speedtest-cli.sandbox.wrapperType = "wrappedDerivation";
speedtest-cli.sandbox.net = "all";
sqlite = {};
strace.sandbox.enable = false; #< needs to `exec` its args, and therefore support *anything*
subversion.sandbox.method = "bwrap";
subversion.sandbox.wrapperType = "wrappedDerivation";
subversion.sandbox.net = "clearnet";
subversion.sandbox.whitelistPwd = true;
sudo.sandbox.enable = false;
@@ -879,8 +843,11 @@ in
superTux.sandbox.whitelistWayland = true;
superTux.persist.byStore.plaintext = [ ".local/share/supertux2" ];
swappy.sandbox.method = "bwrap";
swappy.sandbox.autodetectCliPaths = "existingFileOrParent";
swappy.sandbox.whitelistWayland = true;
tcpdump.sandbox.method = "landlock";
tcpdump.sandbox.wrapperType = "wrappedDerivation";
tcpdump.sandbox.net = "all";
tcpdump.sandbox.autodetectCliPaths = "existingFileOrParent";
tcpdump.sandbox.capabilities = [ "net_admin" "net_raw" ];
@@ -890,12 +857,10 @@ in
tokodon.persist.byStore.private = [ ".cache/KDE/tokodon" ];
tree.sandbox.method = "landlock";
tree.sandbox.wrapperType = "wrappedDerivation";
tree.sandbox.autodetectCliPaths = true;
tree.sandbox.whitelistPwd = true;
tumiki-fighters.sandbox.method = "bwrap";
tumiki-fighters.sandbox.wrapperType = "wrappedDerivation";
tumiki-fighters.sandbox.whitelistAudio = true;
tumiki-fighters.sandbox.whitelistDri = true; #< not strictly necessary, but triples CPU perf
tumiki-fighters.sandbox.whitelistWayland = true;
@@ -904,34 +869,28 @@ in
util-linux.sandbox.enable = false; #< TODO: possible to sandbox if i specific a different profile for each of its ~50 binaries
unzip.sandbox.method = "bwrap";
unzip.sandbox.wrapperType = "wrappedDerivation";
unzip.sandbox.autodetectCliPaths = "existingOrParent";
unzip.sandbox.whitelistPwd = true;
usbutils.sandbox.method = "bwrap"; # breaks `usbhid-dump`, but `lsusb`, `usb-devices` work
usbutils.sandbox.wrapperType = "wrappedDerivation";
usbutils.sandbox.extraPaths = [
"/sys/devices"
"/sys/bus/usb"
];
visidata.sandbox.method = "bwrap"; # TODO:sandbox: untested
visidata.sandbox.wrapperType = "wrappedDerivation";
visidata.sandbox.autodetectCliPaths = true;
# `vulkaninfo`, `vkcube`
vulkan-tools.sandbox.method = "landlock";
vulkan-tools.sandbox.wrapperType = "wrappedDerivation";
vvvvvv.sandbox.method = "bwrap";
vvvvvv.sandbox.wrapperType = "wrappedDerivation";
vvvvvv.sandbox.whitelistAudio = true;
vvvvvv.sandbox.whitelistDri = true; #< playable without, but burns noticably more CPU
vvvvvv.sandbox.whitelistWayland = true;
vvvvvv.persist.byStore.plaintext = [ ".local/share/VVVVVV" ];
w3m.sandbox.method = "bwrap";
w3m.sandbox.wrapperType = "wrappedDerivation";
w3m.sandbox.net = "all";
w3m.sandbox.extraHomePaths = [
# little-used feature, but you can save web pages :)
@@ -939,11 +898,9 @@ in
];
wdisplays.sandbox.method = "bwrap";
wdisplays.sandbox.wrapperType = "wrappedDerivation";
wdisplays.sandbox.whitelistWayland = true;
wget.sandbox.method = "bwrap";
wget.sandbox.wrapperType = "wrappedDerivation";
wget.sandbox.net = "all";
wget.sandbox.whitelistPwd = true; # saves to pwd by default
@@ -951,40 +908,35 @@ in
# `wg`, `wg-quick`
wireguard-tools.sandbox.method = "landlock";
wireguard-tools.sandbox.wrapperType = "wrappedDerivation";
wireguard-tools.sandbox.capabilities = [ "net_admin" ];
# provides `iwconfig`, `iwlist`, `iwpriv`, ...
wirelesstools.sandbox.method = "landlock";
wirelesstools.sandbox.wrapperType = "wrappedDerivation";
wirelesstools.sandbox.capabilities = [ "net_admin" ];
wl-clipboard.sandbox.method = "bwrap";
wl-clipboard.sandbox.wrapperType = "wrappedDerivation";
wl-clipboard.sandbox.whitelistWayland = true;
wtype = {};
xwayland.sandbox.method = "bwrap";
xwayland.sandbox.wrapperType = "inplace"; #< consumers use it as a library (e.g. wlroots)
xwayland.sandbox.whitelistWayland = true; #< just assuming this is needed
xwayland.sandbox.net = "clearnet"; #< just assuming this is needed (X11 traffic)
xwayland.sandbox.whitelistDri = true; #< would assume this gives better gfx perf
xdg-terminal-exec.sandbox.enable = false; # xdg-terminal-exec is a launcher for $TERM
xterm.sandbox.enable = false; # need to be able to do everything
yarn.persist.byStore.plaintext = [ ".cache/yarn" ];
yt-dlp.sandbox.method = "bwrap"; # TODO:sandbox: untested
yt-dlp.sandbox.wrapperType = "wrappedDerivation";
yt-dlp.sandbox.net = "all";
yt-dlp.sandbox.whitelistPwd = true; # saves to pwd by default
zfs = {};
};
programs.feedbackd = lib.mkIf config.sane.programs.feedbackd.enabled {
enable = true;
};
programs.firejail = lib.mkIf config.sane.programs.firejail.enabled {
enable = true; #< install the suid binary
};
}

View File

@@ -10,7 +10,6 @@
};
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistAudio = true;
sandbox.whitelistWayland = true;
sandbox.autodetectCliPaths = true;

View File

@@ -88,7 +88,6 @@ in
{
sane.programs.bemenu = {
sandbox.method = "bwrap"; # landlock works, but requires *all* of /run/user/$ID to be granted.
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistWayland = true;
sandbox.extraHomePaths = [
".cache/fontconfig" #< else it complains, and is *way* slower

View File

@@ -0,0 +1,216 @@
#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p "python3.withPackages (ps: [ ])" -p blast-ugjka
# vim: set filetype=python :
import ctypes
import logging
import os
import signal
import socket
import subprocess
from enum import Enum
logger = logging.getLogger(__name__)
# map from known devices -> required flags
DEVICE_MAP = {
"Theater TV": [],
"[LG] webOS TV OLED55C9PUA": [ "-usewav" ],
}
def set_pdeathsig(sig=signal.SIGTERM):
"""
helper function to ensure once parent process exits, its children processes will automatically die.
see: <https://stackoverflow.com/a/43152455>
see: <https://www.man7.org/linux/man-pages/man2/prctl.2.html>
"""
libc = ctypes.CDLL("libc.so.6")
return libc.prctl(1, sig)
MY_PID = None
def reap_children(sig=None, frame=None):
global MY_PID
# reset SIGTERM handler to avoid recursing
signal.signal(signal.SIGTERM, signal.Handlers.SIG_DFL)
logger.info("killing all children (of pid %d)", MY_PID)
os.killpg(MY_PID, signal.SIGTERM)
def reap_on_exit():
"""
catch when the parent exits, and map that to SIGTERM for this process.
when this process receives SIGTERM, also terminate all descendent processes.
this is done because:
1. mpv invokes this, but (potentially) via the sandbox wrapper.
2. when mpv exits, it `SIGKILL`s that sandbox wrapper.
3. bwrap does not pass SIGKILL or SIGTERM to its child.
4. hence, we neither receive that signal NOR can we pass it on simply by killing our immediate children
(since any bwrap'd children wouldn't pass that signal on...)
really, the proper fix would be on mpv's side:
- mpv should create a new process group when it launches a command, and kill that process group on exit.
or fix this in the sandbox wrapper:
- why *doesn't* bwrap forward the signals?
- there's --die-with-parent, but i can't apply that *system wide* and expect reasonably behavior
<https://github.com/containers/bubblewrap/issues/529>
"""
global MY_PID
MY_PID = os.getpid()
# create a new process group, pgid = gid
os.setpgid(MY_PID, MY_PID)
set_pdeathsig(signal.SIGTERM)
signal.signal(signal.SIGTERM, reap_children)
def get_ranked_ip_addrs():
"""
return the IP addresses most likely to be LAN addresses
based on: <https://stackoverflow.com/a/1267524>
"""
_name, _aliases, static_addrs = socket.gethostbyname_ex(socket.gethostname())
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("1", 53))
con_addr, _port = s.getsockname()
return sorted(set(static_addrs + [ con_addr ]), key=lambda a: (a.startswith("127"), a))
class ParserState(Enum):
Break = "break"
Receiver = "receiver"
Ips = "ip"
class Status(Enum):
Continue = "continue"
Error = "error"
RedoWithFlags = "redo_with_flags"
Launched = "launched"
class BlastDriver:
parsing: ParserState | None = None
last_write: str | None = None
def __init__(self, blast_flags: list[str] = []):
self.ranked_ips = get_ranked_ip_addrs()
self.blast = subprocess.Popen(
["blast", "-source", "blast.monitor"] + blast_flags,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
# this pdeathsig isn't necessary; seems it might result in leaked pulse outputs
# preexec_fn=set_pdeathsig
)
self.blast_flags = list(blast_flags)
self.receiver_names = []
self.ips = []
def writeline(self, line: str) -> None:
logger.debug("[send] %s", line)
self.blast.stdin.write(f"{line}\n".encode())
self.blast.stdin.flush()
self.last_write = line
def readline(self) -> str:
line = self.blast.stdout.readline().decode('utf-8').strip()
line = line.replace('\x1b[1A\x1b[K', '') #< escape codes
logger.debug("[recv] %r", line)
return line
def set_state(self, state: ParserState):
logger.debug("[pars] %s", state)
self.parsing = state
def feedline(self, line: str) -> (Status, str|None):
"""
apply a line from blast's stdout to modify parser state.
returns a status code (e.g. Status.Continue), and optionally a reply to send back to blast.
"""
if line == "Loading...":
return Status.Continue, None
elif line == "----------":
self.set_state(ParserState.Break)
return Status.Continue, None
elif line == "DLNA receivers":
self.set_state(ParserState.Receiver)
return Status.Continue, None
elif line == "Your LAN ip addresses":
self.set_state(ParserState.Ips)
return Status.Continue, None
elif line == "Select the DLNA device:":
assert len(self.receiver_names) == 1, self.receiver_names
name = self.receiver_names[0]
if name in DEVICE_MAP and DEVICE_MAP[name] != self.blast_flags:
return Status.RedoWithFlags, None
return Status.Continue, "0"
elif line == "Select the lan IP address for the stream:":
for r in self.ranked_ips:
if r in self.ips:
return Status.Launched, str(self.ips.index(r))
# fallback: just guess the best IP
return Status.Launched, "0"
elif self.parsing == ParserState.Receiver:
id_, name = line.split(": ")
assert id_ == str(len(self.receiver_names)), (id_, self.receiver_names)
self.receiver_names.append(name)
return Status.Continue, None
elif self.parsing == ParserState.Ips:
id_, ip = line.split(": ")
assert id_ == str(len(self.ips)), (id_, self.ips)
self.ips.append(ip)
return Status.Continue, None
elif line == f"[{self.last_write}]":
# it's echoing to us what we wrote
return Status.Continue, None
# elif line == "":
# return Status.Continue, None
else:
logger.info("unrecognized output (state=%s): %r", self.parsing, line)
return Status.Error, None
def step(self) -> Status:
"""
advance the interaction between us and blast.
reads a line from blast, modifies internal state, maybe sends a reply.
could block indefinitely.
"""
line = self.readline()
status, reply = self.feedline(line)
if reply is not None:
self.writeline(reply)
return status
def try_blast(*args, **kwargs) -> BlastDriver | None:
blast = BlastDriver(*args, **kwargs)
status = Status.Continue
while status == Status.Continue:
status = blast.step()
if status == Status.RedoWithFlags:
dev = blast.receiver_names[0]
blast_flags = DEVICE_MAP[dev]
logger.info("re-exec blast for %s with flags: %r", dev, blast_flags)
blast.blast.terminate()
return try_blast(blast_flags=blast_flags)
elif status == Status.Error:
logger.info("blast error => terminating")
blast.blast.terminate()
else:
# successfully launched
return blast
def main():
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
reap_on_exit()
blast = try_blast()
if blast is not None:
logger.info("waiting until blast exits")
blast.blast.wait()
reap_children()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,51 @@
# blast: tunnel audio from a pulseaudio sink to a UPnP/DLNA device (like a TV).
# - expect 7s of latency
# - can cast the default sink, or create a new one "blast.monitor"
# and either assign that to default or assign apps to it.
# compatibility:
# - there is no single invocation which will be compatible with all known devices.
# - sony tv:
# - `blast` (default): WORKS
# - `-usewav`: FAILS
# - LG TV:
# - `-usewav`: WORKS!
# - `-useaac`: FAILS
# - `-useflac`: FAILS
# - `-uselpcm`: FAILS
# - `-uselpcmle`: FAILS
# - `-format aac`: FAILS
# - `-bitrate 128`: FAILS
# - `-nochunked`: FAILS
# - `-format "ogg" -mime 'audio/x-opus+ogg'`: FAILS
# - `-mime audio/ac3 -format ac3`: FAILS
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.blast-ugjka;
in
{
sane.programs.blast-ugjka = {
sandbox.method = "bwrap";
sandbox.whitelistAudio = true;
sandbox.net = "clearnet";
};
sane.programs.blast-to-default = {
# helper to deal with blast's interactive CLI
packageUnwrapped = pkgs.static-nix-shell.mkPython3Bin {
pname = "blast-to-default";
pkgs = [ "blast-ugjka" ];
srcRoot = ./.;
};
sandbox.method = "bwrap";
sandbox.whitelistAudio = true;
sandbox.net = "clearnet";
sandbox.extraConfig = [
# else it fails to reap its children (or, maybe, it fails to hook its parent's death signal?)
# might be possible to remove this, but kinda hard to see a clean way.
"--sane-sandbox-keep-namespace" "pid"
];
suggestedPrograms = [ "blast-ugjka" ];
};
networking.firewall.allowedTCPPorts = lib.mkIf cfg.enabled [ 9000 ];
}

View File

@@ -111,6 +111,11 @@ in
};
};
sandbox.method = "bwrap";
sandbox.extraRuntimePaths = [
"/" #< just needs "bonsai", but needs to create it first...
];
services.bonsaid = {
description = "bonsai: programmable input dispatcher";
after = [ "graphical-session.target" ];

View File

@@ -0,0 +1,17 @@
{ ... }:
{
sane.programs.celeste64 = {
sandbox.method = "bwrap";
sandbox.whitelistAudio = true;
sandbox.whitelistDri = true;
sandbox.whitelistWayland = true;
sandbox.extraPaths = [
"/dev/input" #< for controllers
];
persist.byStore.plaintext = [
# save data, controls map
".local/share/Celeste64"
];
};
}

View File

@@ -1,9 +1,19 @@
{ ... }:
{ pkgs, ... }:
{
sane.programs.cozy = {
packageUnwrapped = pkgs.cozy.overrideAttrs (upstream: {
postPatch = (upstream.postPatch or "") + ''
# disable all reporting.
# this can be done via the settings, but that's troublesome and easy to forget.
# specifically, i don't want moby to be making these network requests several times per hour
# while it might be roaming or trying to put the RF to sleep.
substituteInPlace cozy/application_settings.py \
--replace-fail 'self._settings.get_int("report-level")' '0'
'';
});
sandbox.method = "bwrap"; # landlock gives: _multiprocessing.SemLock: Permission Denied
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistAudio = true;
sandbox.whitelistDbus = [ "user" ]; # mpris
sandbox.whitelistWayland = true;

View File

@@ -9,17 +9,47 @@ let
in
{
sane.programs.dconf = {
configOption = with lib; mkOption {
type = types.submodule {
options = {
site = mkOption {
type = types.listOf types.package;
default = [];
description = ''
extra packages to link into /etc/dconf
'';
};
};
};
default = {};
};
packageUnwrapped = pkgs.rmDbusServicesInPlace pkgs.dconf;
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.wrapperType = "inplace"; #< dbus/systemd services live in `.out` but point to `.lib` data.
sandbox.whitelistDbus = [ "user" ];
persist.byStore.private = [
".config/dconf"
];
};
programs.dconf = lib.mkIf cfg.enabled {
# note that `programs.dconf` doesn't allow specifying the dconf package.
enable = true;
packages = [
services.dconf = {
description = "dconf configuration database/server";
after = [ "graphical-session.target" ];
wantedBy = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${lib.getLib cfg.package}/libexec/dconf-service";
Type = "simple";
Restart = "always";
RestartSec = "5s";
};
};
# supposedly necessary for packages which haven't been wrapped (i.e. wrapGtkApp?),
# but in practice seems unnecessary.
# env.GIO_EXTRA_MODULES = "${pkgs.dconf.lib}/lib/gio/modules";
config.site = [
(pkgs.writeTextFile {
name = "dconf-user-profile";
destination = "/etc/dconf/profile/user";
@@ -30,4 +60,18 @@ in
})
];
};
# TODO: get dconf to read these from ~/.config/dconf ?
environment.etc.dconf = lib.mkIf cfg.enabled {
source = pkgs.symlinkJoin {
name = "dconf-system-config";
paths = map (x: "${x}/etc/dconf") cfg.config.site;
nativeBuildInputs = [ (lib.getBin pkgs.dconf) ];
postBuild = ''
if test -d $out/db; then
dconf update $out/db
fi
'';
};
};
}

View File

@@ -0,0 +1,139 @@
/* Notification center */
.blurredBG, #main_window, .blurredBG.low, .blurredBG.normal {
background: rgba(255, 255, 255, 1.0);
}
.noti-center.time {
font-size: 32px;
}
/* Notifications */
.notification.content {
margin-left: 15px;
margin-right: 15px;
}
.title {
font-weight: bold;
font-size: 16px;
}
.appname {
font-size: 12px;
}
.time {
font-size: 12px;
}
.blurredBG.notification {
background: rgba(255, 255, 255, 0.4);
}
.blurredBG.notification.critical {
background: rgba(255, 0, 0, 0.5);
}
.notificationInCenter.critical {
background: rgba(155, 0, 20, 0.5);
}
/* Labels */
label {
color: #322;
}
label.notification {
color: #322;
}
label.critical {
color: #000;
}
.notificationInCenter label.critical {
color: #000;
}
/* Buttons */
button {
background: transparent;
color: #322;
border-radius: 3px;
border-width: 0px;
background-position: 0px 0px;
text-shadow: none;
}
button:hover {
border-radius: 3px;
background: rgba(0, 20, 20, 0.2);
border-width: 0px;
border-top: transparent;
border-color: #f00;
color: #fee;
}
/* Custom Buttons */
.userbutton {
background: rgba(20,0,0, 0.15);
}
.userbuttonlabel {
color: #222;
font-size: 12px;
}
.userbutton:hover {
background: rgba(20, 0, 0, 0.2);
}
.userbuttonlabel:hover {
color: #111;
}
button.buttonState1 {
background: rgba(20,0,0,0.5);
}
.userbuttonlabel.buttonState1 {
color: #fff;
}
button.buttonState1:hover {
background: rgba(20,0,0, 0.4);
}
.userbuttonlabel.buttonState1:hover {
color: #111;
}
button.buttonState2 {
background: rgba(255,255,255,0.3);
}
.userbuttonlabel.buttonState2 {
color: #111;
}
button.buttonState2:hover {
background: rgba(20,0,0, 0.3);
}
.userbuttonlabel.buttonState2:hover {
color: #000;
}
/* Images */
image.deadd-noti-center.notification.image {
margin-left: 20px;
}

View File

@@ -0,0 +1,263 @@
### Margins for notification-center/notifications
margin-top: 0
margin-right: 0
### Margins for notification-center
margin-bottom: 0
### Width of the notification center/notifications in pixels.
width: 360
### Command to run at startup. This can be used to setup
### button states.
# startup-command: deadd-notification-center-startup
### Monitor on which the notification center/notifications will be
### printed. If "follow-mouse" is set true, this does nothing.
monitor: 0
### If true, the notification center/notifications will open on the
### screen, on which the mouse is. Overrides the "monitor" setting.
follow-mouse: false
notification-center:
### Margin at the top/right/bottom of the notification center in
### pixels. This can be used to avoid overlap between the notification
### center and bars such as polybar or i3blocks.
margin-top: 40
# margin-right: 0
# margin-bottom: 0
### Width of the notification center in pixels.
# width: 500
### Monitor on which the notification center will be printed. If
### "follow-mouse" is set true, this does nothing.
# monitor: 0
### If true, the notification center will open on the screen, on which
### the mouse is. Overrides the "monitor" setting.
# follow-mouse: false
### Notification center closes when the mouse leaves it
hide-on-mouse-leave: true
### If newFirst is set to true, newest notifications appear on the top
### of the notification center. Else, notifications stack, from top to
### bottom.
new-first: true
### If true, the transient field in notifications will be ignored,
### thus the notification will be persisted in the notification
### center anyways
ignore-transient: false
### Custom buttons in notification center
buttons:
### Numbers of buttons that can be drawn on a row of the notification
### center.
# buttons-per-row: 5
### Height of buttons in the notification center (in pixels).
# buttons-height: 60
### Horizontal and vertical margin between each button in the
### notification center (in pixels).
# buttons-margin: 2
### Button actions and labels. For each button you must specify a
### label and a command.
actions:
# - label: VPN
# command: "sudo vpnToggle"
# - label: Bluetooth
# command: bluetoothToggle
# - label: Wifi
# command: wifiToggle
# - label: Screensaver
# command: screensaverToggle
# - label: Keyboard
# command: keyboardToggle
notification:
### If true, markup (<u>, <i>, <b>, <a>) will be displayed properly
use-markup: true
### If true, html entities (&#38; for &, &#37; for %, etc) will be
### parsed properly. This is useful for chromium-based apps, which
### tend to send these in notifications.
parse-html-entities: true
dbus:
### If noti-closed messages are enabled, the sending application
### will know that a notification was closed/timed out. This can
### be an issue for certain applications, that overwrite
### notifications on status updates (e.g. Spotify on each
### song). When one of these applications thinks, the notification
### has been closed/timed out, they will not overwrite existing
### notifications but send new ones. This can lead to redundant
### notifications in the notification center, as the close-message
### is send regardless of the notification being persisted.
send-noti-closed: false
app-icon:
### If set to true: If no icon is passed by the app_icon parameter
### and no application "desktop-entry"-hint is present, deadd will
### try to guess the icon from the application name (if present).
guess-icon-from-name: true
### The display size of the application icons in the notification
### pop-ups and in the notification center
icon-size: 20
image:
### The maximal display size of images that are part of
### notifications for notification pop-ups and in the notification
### center
size: 100
### The margin around the top, bottom, left, and right of
### notification images.
margin-top: 15
margin-bottom: 15
margin-left: 15
margin-right: 0
### Apply modifications to certain notifications:
### Each modification rule needs a "match" and either a "modify" or
### a "script" entry.
modifications:
### Match:
### Matches the notifications against these rules. If all of the
### values (of one modification rule) match, the "modify"/"script"
### part is applied.
# - match:
### Possible match criteria:
# title: "Notification title"
# body: "Notification body"
# time: "12:44"
# app-name: "App name"
# urgency: "low" # "low", "normal" or "critical"
# modify:
### Possible modifications
# title: "abc"
# body: "abc"
# app-name: "abc"
# app-icon: "file:///abc.png"
### The timeout has three special values:
### timeout: 0 -> don't time out at all
### timeout: -1 -> use default timeout
### timeout: 1 -> don't show as pop-up
### timeout: >1 -> milliseconds until timeout
# timeout: 1
# margin-right: 10
# margin-top: 10
# image: "file:///abc.png"
# image-size: 10
# transient: true
# send-noti-closed: false
### Remove action buttons from notifications
# remove-actions: true
### Set the action-icons hint to true, action labels will then
### be intergreted as GTK icon names
# action-icons: true
### List of actions, where the even elements (0, 2, ...) are the
### action name and the odd elements are the label
# actions:
# - previous
# - media-skip-backward
# - play
# - media-playback-start
# - next
# - media-skip-forward
### Action commands, where the keys (e.g. "play") is the action
### name and the value is a program call that should be executed
### on action. Prevents sending of the action to the application.
# action-commands:
# play: playerctl play-pause
# previous: playerctl previous
# next: playerctl next
### Add a class-name to the notification container, that can be
### used for specific styling of notifications using the
### deadd.css file
# class-name: "abc"
# - match:
# app-name: "Chromium"
### Instead of modifying a notification directly, a script can be
### run, which will receive the notification as JSON on STDIN. It
### is expected to return JSON/YAML configuration that defines the
### modifications that should be applied. Minimum complete return
### value must be '{"modify": {}, "match": {}}'. Always leave the "match"
### object empty (technical reasons, i.e. I am lazy).
# script: "linux-notification-center-parse-chromium"
- match:
app-name: "Spotify"
modify:
image-size: 80
timeout: 1
send-noti-closed: true
class-name: "Spotify"
action-icons: true
actions:
- previous
- media-skip-backward
- play
- media-playback-start
- next
- media-skip-forward
action-commands:
play: playerctl play-pause
previous: playerctl previous
next: playerctl next
# - match:
# title: Bildschirmhelligkeit
# modify:
# image-size: 60
popup:
### Default timeout used for notifications in milli-seconds. This can
### be overwritten with the "-t" option (or "--expire-time") of the
### notify-send command.
default-timeout: 10000
### Margin above/right/between notifications (in pixels). This can
### be used to avoid overlap between notifications and a bar such as
### polybar or i3blocks.
margin-top: 50
margin-right: 50
margin-between: 20
### Defines after how many lines of text the body will be truncated.
### Use 0 if you want to disable truncation.
max-lines-in-body: 3
### Determines whether the GTK widget that displays the notification body
### in the notification popup will be hidden when empty. This is especially
### useful for transient notifications that display a progress bar.
# hide-body-if-empty: false
### Monitor on which the notifications will be
### printed. If "follow-mouse" is set true, this does nothing.
# monitor: 0
### If true, the notifications will open on the
### screen, on which the mouse is. Overrides the "monitor" setting.
# follow-mouse: false
click-behavior:
### The mouse button for dismissing a popup. Must be either "mouse1",
### "mouse2", "mouse3", "mouse4", or "mouse5"
dismiss: mouse1
### The mouse button for opening a popup with the default action.
### Must be either "mouse1", "mouse2", "mouse3", "mouse4", or "mouse5"
default-action: mouse3

View File

@@ -0,0 +1,17 @@
# docs are via README only:
# - <https://github.com/phuhl/linux_notification_center>
# reload config:
# - `notify-send a --hint=boolean:deadd-notification-center:true --hint=string:type:reloadStyle`
# toggle visibility:
# - `kill -s USR1 $(pidof deadd-notification-center)`
# clear notifications:
# - `notify-send a --hint=boolean:deadd-notification-center:true --hint=string:type:clearInCenter`
# set state of user button 0 to "highlighted" (true)
# - `notify-send a --hint=boolean:deadd-notification-center:true --hint=int:id:0 --hint=boolean:state:true --hint=type:string:buttons`
{ ... }:
{
sane.programs.deadd-notification-center = {
fs.".config/deadd/deadd.css".symlink.target = ./deadd.css;
fs.".config/deadd/deadd.yml".symlink.target = ./deadd.yml;
};
}

View File

@@ -5,27 +5,34 @@
./abaddon.nix
./aerc.nix
./alacritty.nix
./alsa-ucm-conf
./animatch.nix
./assorted.nix
./audacity.nix
./bemenu.nix
./blast-ugjka
./bonsai.nix
./brave.nix
./bubblewrap.nix
./calls.nix
./cantata.nix
./catt.nix
./celeste64.nix
./chatty.nix
./conky
./cozy.nix
./dconf.nix
./deadd-notification-center
./dialect.nix
./dino.nix
./dissent.nix
./element-desktop.nix
./epiphany.nix
./evince.nix
./fcitx5.nix
./feedbackd.nix
./firefox.nix
./firejail.nix
./flare-signal.nix
./fontconfig.nix
./fractal.nix
@@ -44,7 +51,6 @@
./gpodder.nix
./grimshot.nix
./gthumb.nix
./gtkcord4.nix
./handbrake.nix
./helix.nix
./imagemagick.nix
@@ -52,6 +58,7 @@
./kdenlive.nix
./komikku.nix
./koreader
./less.nix
./libreoffice.nix
./lemoa.nix
./loupe.nix
@@ -60,7 +67,7 @@
./mepo.nix
./mimeo
./mopidy.nix
./mpv.nix
./mpv
./msmtp.nix
./nautilus.nix
./neovim.nix
@@ -80,7 +87,10 @@
./rhythmbox.nix
./ripgrep.nix
./rofi
./sane-input-handler
./sane-screenshot.nix
./sane-scripts.nix
./schlock.nix
./sfeed.nix
./signal-desktop.nix
./splatmoji.nix
@@ -93,8 +103,10 @@
./supertuxkart.nix
./sway
./sway-autoscaler
./swayidle.nix
./swaylock.nix
./swaynotificationcenter.nix
./swaynotificationcenter
./sysvol.nix
./tangram.nix
./tor-browser.nix
./tuba.nix
@@ -107,19 +119,19 @@
./wireplumber.nix
./wireshark.nix
./wob
./wvkbd.nix
./xarchiver.nix
./xdg-desktop-portal.nix
./xdg-desktop-portal-gtk.nix
./xdg-desktop-portal-wlr.nix
./xdg-terminal-exec.nix
./xdg-utils.nix
./zathura.nix
./zeal.nix
./zecwallet-lite.nix
./zsh
];
config = {
# XXX: this might not be necessary. try removing this and cacert.unbundled (servo)?
environment.etc."ssl/certs".source = "${pkgs.cacert.unbundled}/etc/ssl/certs/*";
};
# XXX: this might not be necessary. try removing this and cacert.unbundled (servo)?
environment.etc."ssl/certs".source = "${pkgs.cacert.unbundled}/etc/ssl/certs/*";
}

View File

@@ -5,6 +5,9 @@
sandbox.wrapperType = "inplace"; # share/search_providers/ calls back into the binary, weird wrap semantics
sandbox.whitelistWayland = true;
sandbox.net = "clearnet";
sandbox.extraHomePaths = [
".config/dconf" # won't start without it
];
suggestedPrograms = [ "dconf" ]; #< to persist settings
packageUnwrapped = pkgs.dialect.overrideAttrs (upstream: {

View File

@@ -46,7 +46,6 @@ in
};
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "clearnet";
sandbox.whitelistAudio = true;
sandbox.whitelistDbus = [ "user" ]; # notifications

View File

@@ -3,10 +3,10 @@
# - notification sounds can be handled by swaync
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.gtkcord4;
cfg = config.sane.programs.dissent;
in
{
sane.programs.gtkcord4 = {
sane.programs.dissent = {
configOption = with lib; mkOption {
default = {};
type = types.submodule {
@@ -17,22 +17,21 @@ in
};
};
packageUnwrapped = pkgs.gtkcord4.overrideAttrs (upstream: {
packageUnwrapped = pkgs.dissent.overrideAttrs (upstream: {
postConfigure = (upstream.postConfigure or "") + ''
# gtkcord4 uses go-keyring to interface with the org.freedesktop.secrets provider (i.e. gnome-keyring).
# dissent uses go-keyring to interface with the org.freedesktop.secrets provider (i.e. gnome-keyring).
# go-keyring hardcodes `login.keyring` as the keyring to store secrets in, instead of reading `~/.local/share/keyring/default`.
# `login.keyring` seems to be a special keyring preconfigured (by gnome-keyring) to encrypt everything to the user's password.
# that's redundant with my fs-level encryption and makes the keyring less inspectable,
# so patch gtkcord4 to use Default_keyring instead.
# so patch dissent to use Default_keyring instead.
# see:
# - <https://github.com/diamondburned/gtkcord4/issues/139>
# - <https://github.com/diamondburned/dissent/issues/139>
# - <https://github.com/zalando/go-keyring/issues/46>
substituteInPlace vendor/github.com/zalando/go-keyring/secret_service/secret_service.go \
--replace '"login"' '"Default_keyring"'
'';
});
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "clearnet";
sandbox.whitelistAudio = true;
sandbox.whitelistDbus = [ "user" ]; # notifications
@@ -52,18 +51,17 @@ in
];
persist.byStore.private = [
".cache/gtkcord4"
".config/gtkcord4" # empty?
".cache/dissent"
".config/dissent" # empty?
];
services.gtkcord4 = {
description = "gtkcord4 Discord client";
services.dissent = {
description = "dissent Discord client";
after = [ "graphical-session.target" ];
# partOf = [ "graphical-session.target" ];
wantedBy = lib.mkIf cfg.config.autostart [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/gtkcord4";
ExecStart = "${cfg.package}/bin/dissent";
Type = "simple";
Restart = "always";
RestartSec = "20s";

View File

@@ -17,7 +17,6 @@
];
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "clearnet";
sandbox.whitelistAudio = true;
sandbox.whitelistDbus = [ "user" ]; # notifications

View File

@@ -12,11 +12,13 @@
sandbox.wrapperType = "inplace"; # /share/epiphany/default-bookmarks.rdf refers back to /share; dbus files to /libexec
sandbox.net = "clearnet";
sandbox.whitelistAudio = true;
sandbox.whitelistDbus = [ "user" ]; #< silently fails to start without it.
# default sandboxing breaks rendering in weird ways. sites are super zoomed in / not scaled.
# enabling DRI/DRM (as below) seems to fix that.
sandbox.whitelistDri = true;
sandbox.whitelistWayland = true;
sandbox.extraHomePaths = [
".config/dconf" # else will always prompt "make default browser?"
".config/epiphany" #< else it gets angry at launch
"tmp"
];

View File

@@ -0,0 +1,123 @@
# fcitx5 is an "input method", to e.g. allow typing CJK on qwerty.
# but i also misuse it to allow typing emoji on qwerty:
# - press `Super+backtick`
# - type something like "effort"
# - it should be underlined, at the least
# - if well supported (e.g. Firefox; also gtk4, alacritty on sway 1.10+), a drop-down fuzzy matcher will appear
# - press space
# - "effort" should be replaced by `(ง •̀_•́)ง`
#
## debugging
# - `fcitx5-diagnose`
#
## config/docs:
# - `fcitx5-configtool`, then check ~/.config/fcitx5 files
# - <https://fcitx-im.org/wiki/Fcitx_5>
# - <https://wiki.archlinux.org/title/Fcitx5>
# - theming: <https://wiki.archlinux.org/title/Fcitx5#Themes_and_appearance>
# - <https://en.wikipedia.org/wiki/Fcitx>
# - wayland specifics: <https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland>
# - quickphrase (emoji): <https://fcitx-im.org/wiki/QuickPhrase>
# - override phrases via `~/.config/fcitx/data/QuickPhrase.mb`
# - customize bindings via `fcitx5-configtool` > addons > QuickPhrase
# - theming:
# - nixpkgs has a few themes: `fcitx5-{material-color,nord,rose-pine}`
# - NUR has a few themes
# - <https://github.com/catppuccin/fcitx5>
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.fcitx5;
in
{
sane.programs.fcitx5 = {
packageUnwrapped = pkgs.fcitx5-with-addons.override {
addons = with pkgs; [
# fcitx5-mozc # japanese input: <https://github.com/fcitx/mozc>
fcitx5-gtk # <https://github.com/fcitx/fcitx5-gtk>
];
};
sandbox.method = "bwrap";
sandbox.whitelistDbus = [ "user" ];
sandbox.whitelistWayland = true; # for `fcitx5-configtool, if nothing else`
sandbox.extraHomePaths = [
# ".config/fcitx"
".config/fcitx5"
".local/share/fcitx5"
];
fs.".config/fcitx5/conf/quickphrase.conf".symlink.text = ''
# Choose key modifier
Choose Modifier=None
# Enable Spell check
Spell=True
FallbackSpellLanguage=en
[TriggerKey]
# defaults: Super+grave, Super+semicolon
# gtk apps use ctrl+period, so super+period is a nice complement
0=Super+grave
1=Super+semicolon
2=Super+period
'';
fs.".config/fcitx5/conf/classicui.conf".symlink.text = ''
Theme=sane
Font="Sans 20"
Vertical Candidate List=True
'';
fs.".local/share/fcitx5/themes/sane/theme.conf".symlink.text = ''
# i omit several keys, especially the ones which don't seem to do much.
# for a theme which uses many more options, see:
# - <https://github.com/catppuccin/fcitx5/blob/main/src/catppuccin-mocha/theme.conf>
[Metadata]
Name=sane
ScaleWithDPI=True
[InputPanel]
NormalColor=#d8d8d8
HighlightCandidateColor=#FFFFFF
HighlightColor=#FFFFFF
HighlightBackgroundColor=#1f5e54
[InputPanel/Background]
Color=#1f5e54
[InputPanel/Highlight]
Color=#418379
[InputPanel/Highlight/Margin]
Left=20
Right=20
Top=7
Bottom=7
[InputPanel/TextMargin]
Left=20
Right=20
Top=6
Bottom=6
'';
services.fcitx5 = {
description = "fcitx5: input method (IME) for emoji/internationalization";
after = [ "graphical-session.target" ];
wantedBy = [ "graphical-session.target" ];
serviceConfig = {
ExecStart="${cfg.package}/bin/fcitx5";
Type = "simple";
Restart = "always";
RestartSec = "10s";
};
};
env.XMODIFIERS = "@im=fcitx";
# setting IM_MODULE is generally not required on wayland, but can be used to override the toolkit's own dialogs with our own.
# env.GTK_IM_MODULE = "fcitx";
# enable if you want them:
# env.QT_IM_MODULE = "fcitx";
# env.QT_PLUGIN_PATH = [ "${cfg.package}/${pkgs.qt6.qtbase.qtPluginPrefix}" ];
# env.SDL_IM_MODULE = "fcitx";
# env.GLFW_IM_MODULE = "ibus"; # for KiTTY, as per <https://wiki.archlinux.org/title/Fcitx5#Integration>
};
}

View File

@@ -25,7 +25,6 @@ in
};
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistDbus = [ "user" ];
sandbox.whitelistAudio = true;

View File

@@ -234,7 +234,7 @@ in
sane.programs.firefox = {
inherit packageUnwrapped;
sandbox.method = "bwrap"; # landlock works, but requires all of /proc to be linked
sandbox.wrapperType = "inplace"; # probably wrappedDerivation could work too.
sandbox.wrapperType = "inplace"; # trivial package; cheap enough to wrap inplace
sandbox.net = "all";
sandbox.whitelistAudio = true;
sandbox.whitelistDbus = [ "user" ]; # mpris
@@ -322,6 +322,8 @@ in
defaultPref("widget.use-xdg-desktop-portal.mime-handler", 1);
defaultPref("widget.use-xdg-desktop-portal.open-uri", 1);
defaultPref("browser.toolbars.bookmarks.visibility", "never");
// auto-open mpv:// URIs without prompting.
// can do this with other protocols too (e.g. matrix?). see about:config for common handlers.
defaultPref("network.protocol-handler.external.mpv", true);

View File

@@ -0,0 +1,8 @@
{ lib, config, ... }:
{
sane.programs.firejail = {};
programs.firejail = lib.mkIf config.sane.programs.firejail.enabled {
enable = true; #< install the suid binary
};
}

View File

@@ -1,6 +1,10 @@
# to preview fonts:
# - `font-manager` (gui)
# - useful to determine official name; codepoint support
# docs:
# - <https://slatecave.net/notebook/fontconfig/>
# debugging:
# - `fc-conflist` -> show all config files loaded
{ config, lib, pkgs, ... }:
let
# nerdfonts takes popular open fonts and patches them to support a wider range of glyphs, notably emoji.
@@ -30,13 +34,12 @@ in
{
sane.programs.fontconfig = {
sandbox.method = "bwrap"; # TODO:sandbox: untested
sandbox.wrapperType = "wrappedDerivation";
sandbox.autodetectCliPaths = "existingOrParent"; #< this might be overkill; or, how many programs reference fontconfig internally?
persist.byStore.plaintext = [
# < 10 MiB
".cache/fontconfig"
];
# persist.byStore.plaintext = [
# # < 10 MiB. however, nixos generates its own fontconfig cache at build time now.
# ".cache/fontconfig"
# ];
};
fonts = lib.mkIf config.sane.programs.fontconfig.enabled {
@@ -44,8 +47,8 @@ in
fontconfig.defaultFonts = {
emoji = [
"Noto Color Emoji"
"Font Awesome 6 Free"
"Font Awesome 6 Brands"
# "Font Awesome 6 Free"
# "Font Awesome 6 Brands"
];
monospace = [
"Hack Nerd Font Propo"
@@ -67,7 +70,7 @@ in
# TODO: reduce this font set.
# - probably need only one of dejavu/freefont/liberation
dejavu_fonts # 10 MiB; DejaVu {Sans,Serif,Sans Mono,Math TeX Gyre}; also available as a NerdFonts (Sans Mono only)
font-awesome # 2 MiB; Font Awesome 6 {Free,Brands}
# font-awesome # 2 MiB; Font Awesome 6 {Free,Brands}
freefont_ttf # 11 MiB; Free{Mono,Sans,Serif}
gyre-fonts # 4 MiB; Tex Gyre *; ttf substitutes for standard PostScript fonts
# hack-font # 1 MiB; Hack; also available as a NerdFonts

View File

@@ -28,7 +28,6 @@ in
# packageUnwrapped = pkgs.fractal-next;
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "clearnet";
sandbox.whitelistAudio = true;
sandbox.whitelistDbus = [ "user" ]; # notifications
@@ -60,9 +59,9 @@ in
persist.byStore.private = [
# XXX by default fractal stores its state in ~/.local/share/<build-profile>/<UUID>.
".local/share/hack" # for debug-like builds
".local/share/stable" # for normal releases
".local/share/fractal" # for version 5+, i think?
# ".local/share/hack" # for debug-like builds
# ".local/share/stable" # for normal releases
".local/share/fractal" # for version 5+
];
suggestedPrograms = [ "gnome-keyring" ];

View File

@@ -3,7 +3,6 @@
{
sane.programs.frozen-bubble = {
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "clearnet"; # net play
sandbox.whitelistAudio = true;
sandbox.whitelistWayland = true;

View File

@@ -1,5 +1,6 @@
{ config, lib, ... }:
{
sane.programs.fwupd = {};
services.fwupd = lib.mkIf config.sane.programs.fwupd.enabled {
# enables the dbus service, which i think the frontend speaks to.
enable = true;

View File

@@ -9,7 +9,6 @@
{
sane.programs.g4music = {
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistAudio = true;
sandbox.whitelistDbus = [ "user" ]; # mpris
sandbox.whitelistWayland = true;

View File

@@ -4,7 +4,6 @@
packageUnwrapped = pkgs.linkIntoOwnPackage pkgs.glib "bin/gdbus";
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistDbus = [ "user" ]; #< XXX: maybe future users will also want system access
};
}

View File

@@ -20,7 +20,6 @@ in
};
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "clearnet";
sandbox.whitelistDbus = [ "user" ]; # notifications
sandbox.whitelistWayland = true;

View File

@@ -19,7 +19,6 @@ in
'';
});
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "clearnet";
sandbox.whitelistPwd = true;
sandbox.autodetectCliPaths = true; # necessary for git-upload-pack

View File

@@ -6,10 +6,10 @@ in
sane.programs.gnome-keyring = {
packageUnwrapped = pkgs.rmDbusServices pkgs.gnome.gnome-keyring;
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistDbus = [ "user" ];
sandbox.extraRuntimePaths = [
"keyring/control"
"keyring" #< only needs keyring/control, but has to *create* that.
# "keyring/control"
];
sandbox.capabilities = [
# ipc_lock: used to `mlock` the secrets so they don't get swapped out.
@@ -28,7 +28,7 @@ in
fs.".local/share/keyrings/default" = {
file.text = "Default_keyring.keyring"; #< no trailing newline
wantedBy = [ config.sane.fs."${config.sane.persist.stores.private.origin}".unit ];
# wantedBy = [ config.sane.fs."${config.sane.persist.stores.private.origin}".unit ];
wantedBeforeBy = [ #< don't create this as part of `multi-user.target`
"gnome-keyring.service" # TODO: sane.programs should declare this dependency for us
];
@@ -43,7 +43,7 @@ in
lock-on-idle=false
lock-after=false
'';
wantedBy = [ config.sane.fs."${config.sane.persist.stores.private.origin}".unit ];
# wantedBy = [ config.sane.fs."${config.sane.persist.stores.private.origin}".unit ];
wantedBeforeBy = [ #< don't create this as part of `multi-user.target`
"gnome-keyring.service"
];
@@ -55,6 +55,7 @@ in
wantedBy = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/gnome-keyring-daemon --start --foreground --components=secrets";
ExecStartPre = "${pkgs.coreutils}/bin/mkdir -m 0700 -p %t/keyring";
Type = "simple";
Restart = "always";
RestartSec = "20s";

View File

@@ -1,8 +1,8 @@
{ ... }:
{ pkgs, ... }:
{
sane.programs."gnome.gnome-maps" = {
packageUnwrapped = pkgs.rmDbusServices pkgs.gnome.gnome-maps;
sandbox.method = "bwrap";
sandbox.wrapperType = "inplace"; #< dbus files
sandbox.whitelistDri = true; # for perf
sandbox.whitelistDbus = [
"system" # system is required for non-portal location services

View File

@@ -4,7 +4,7 @@
{
sane.programs."gnome.gnome-weather" = {
sandbox.method = "bwrap";
sandbox.wrapperType = "inplace";
sandbox.wrapperType = "inplace"; #< /share/org.gnome.Weather/org.gnome.Weather file refers to bins by full path
sandbox.whitelistWayland = true;
sandbox.net = "clearnet";
suggestedPrograms = [ "dconf" ]; #< stores city/location settings

View File

@@ -34,7 +34,6 @@ in
{
sane.programs.go2tv = {
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "clearnet";
sandbox.autodetectCliPaths = true;
# for GUI invocation, allow the common media directories

View File

@@ -23,7 +23,6 @@ in {
});
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistDbus = [ "user" ]; # it won't launch without it, dunno exactly why.
sandbox.whitelistWayland = true;
sandbox.net = "clearnet";

View File

@@ -15,7 +15,6 @@
"wl-clipboard"
];
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistWayland = true;
sandbox.whitelistDbus = [ "user" ];
sandbox.autodetectCliPaths = "existingFileOrParent";

View File

@@ -2,7 +2,6 @@
{
sane.programs.handbrake = {
sandbox.method = "landlock"; #< also supports bwrap, but landlock ensures we don't write to non-mounted tmpfs dir
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistDbus = [ "user" ]; # notifications
sandbox.whitelistWayland = true;
sandbox.extraHomePaths = [

View File

@@ -2,7 +2,6 @@
{
sane.programs.kdenlive = {
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.extraHomePaths = [
"Music"
"Pictures/from" # e.g. Videos taken from my phone

View File

@@ -11,7 +11,6 @@
});
sandbox.method = "bwrap"; # TODO:sandbox untested
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "clearnet";
sandbox.whitelistDbus = [ "user" ]; # needs to connect to dconf via dbus
sandbox.whitelistDri = true; #< required

View File

@@ -46,7 +46,6 @@ in {
sane.programs.koreader = {
packageUnwrapped = pkgs.koreader-from-src;
sandbox.method = "bwrap"; # sandboxes fine under landlock too, except for FTP
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "clearnet";
sandbox.whitelistDri = true; # reduces startup time and subjective page flip time
sandbox.whitelistWayland = true;

View File

@@ -2,7 +2,6 @@
{
sane.programs.lemoa = {
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "clearnet";
sandbox.whitelistDbus = [ "user" ]; # for clicking links
sandbox.whitelistDri = true;

View File

@@ -0,0 +1,8 @@
{ ... }:
{
sane.programs.less = {
sandbox.method = "bwrap";
sandbox.autodetectCliPaths = "existingFile";
env.PAGER = "less";
};
}

View File

@@ -12,7 +12,6 @@
}));
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistWayland = true;
sandbox.autodetectCliPaths = "parent";
sandbox.extraHomePaths = [

View File

@@ -10,19 +10,13 @@
# bwrap (loupe image viewer) doesn't like to run inside landlock
# "bwrap: failed to make / slave: Operation not permitted"
sandbox.method = "bwrap"; # supports landlock or bwrap
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistDri = true;
sandbox.whitelistWayland = true;
sandbox.whitelistDbus = [ "user" ]; #< so that it can in theory open the image viewer using fdo portal... but it doesn't :|
sandbox.extraHomePaths = [
".config/dconf" #< else it segfaults during post-process
# ".config/megapixels"
# ".config/xcb"
# ".xcb"
".local/share/applications" #< needed for viewing photos, until i can sort out the portal stuff
# ".local/share/icons"
# ".icons" #< actually needed!
# ".themes"
# ".nix-profile"
".cache/mesa_shader_cache" # loads way faster
"tmp"
"Pictures" #< TODO: make this Pictures/Photos and save photos there

View File

@@ -5,7 +5,6 @@
{
sane.programs.mepo = {
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "all"; # for tiles *and* for localhost comm to gpsd
sandbox.whitelistDri = true;
sandbox.whitelistWayland = true;

View File

@@ -1,6 +1,8 @@
# mimeo is an exec dispatcher like xdg-open, but why allows mapping different URL regexes to different handlers.
# mimeo is an exec dispatcher like xdg-open, but which allows mapping different URL regexes to different handlers.
# my setup sets mimeo as the default http/https handler,
# and from there it dispatches specialized rules, falling back to the original http/https handler if no URL specialization exists
#
# alternative to mimeo is jaro: <https://github.com/isamert/jaro>
{ config, lib, pkgs, ... }:
let
mimeo-open-desktop = pkgs.static-nix-shell.mkPython3Bin {

View File

@@ -1,195 +0,0 @@
# mpv docs:
# - <https://mpv.io/manual/master>
# - <https://github.com/mpv-player/mpv/wiki>
# curated mpv mods/scripts/users:
# - <https://github.com/stax76/awesome-mpv>
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.mpv;
in
{
sane.programs.mpv = {
configOption = with lib; mkOption {
default = {};
type = types.submodule {
options.vo = mkOption {
type = types.nullOr types.str;
default = null;
description = "--vo=FOO flag to pass to mpv";
};
};
};
packageUnwrapped = (pkgs.wrapMpv pkgs.mpv-unwrapped {
scripts = with pkgs.mpvScripts; [
mpris
uosc
# pkgs.mpv-uosc-latest
];
extraMakeWrapperArgs = lib.optionals (cfg.config.vo != null) [
# 2023/08/29: fixes an error where mpv on moby launches with the message
# "DRM_IOCTL_MODE_CREATE_DUMB failed: Cannot allocate memory"
# audio still works, and controls, screenshotting, etc -- just not the actual rendering
#
# this is likely a regression for mpv 0.36.0.
# the actual error message *appears* to come from the mesa library, but it's tough to trace.
#
# TODO(2023/12/03): remove once mesa 23.3.1 lands: <https://github.com/NixOS/nixpkgs/pull/265740>
#
# backend compatibility (2023/10/22):
# run with `--vo=help` to see a list of all output options.
# non-exhaustive (W=works, F=fails, A=audio-only, U=audio+ui only (no video))
# ? null Null video output
# A (default)
# A dmabuf-wayland Wayland dmabuf video output
# A libmpv render API for libmpv (mpv plays the audio, but doesn't even render a window)
# A vdpau VDPAU with X11
# F drm Direct Rendering Manager (software scaling)
# F gpu-next Video output based on libplacebo
# F vaapi VA API with X11
# F x11 X11 (software scaling)
# F xv X11/Xv
# U gpu Shader-based GPU Renderer
# W caca libcaca (terminal rendering)
# W sdl SDL 2.0 Renderer
# W wlshm Wayland SHM video output (software scaling)
"--add-flags" "--vo=${cfg.config.vo}"
];
}).overrideAttrs (base: {
buildCommand = base.buildCommand + ''
# runHook postFixup to allow sandbox wrappers to wrap the binaries
runHook postFixup
'';
});
sandbox.method = "bwrap";
sandbox.autodetectCliPaths = true;
sandbox.net = "all";
sandbox.whitelistAudio = true;
sandbox.whitelistDbus = [ "user" ]; #< mpris
sandbox.whitelistDri = true; #< mpv has excellent fallbacks to non-DRI, but DRI offers a good 30%-50% reduced CPU
sandbox.whitelistWayland = true;
sandbox.extraHomePaths = [
".config/mpv" #< else mpris plugin crashes on launch
# it's common for album (or audiobook, podcast) images/lyrics/metadata to live adjacent to the primary file.
# CLI detection is too poor to pick those up, so expose the common media dirs to the sandbox to make that *mostly* work.
"Books/local"
"Books/servo"
"Music"
"Videos/local"
"Videos/servo"
];
persist.byStore.plaintext = [
# for `watch_later`
".local/state/mpv"
];
fs.".config/mpv/input.conf".symlink.text = let
execInTerm = "${pkgs.xdg-terminal-exec}/bin/xdg-terminal-exec";
in ''
# docs:
# - <https://mpv.io/manual/master/#list-of-input-commands>
# - script-binding: <https://mpv.io/manual/master/#command-interface-script-binding>
# - properties: <https://mpv.io/manual/master/#property-list>
# let volume/power keys be interpreted by the system.
# this is important for sxmo.
# mpv defaults is POWER = close, VOLUME_{UP,DOWN} = adjust application-level volume
POWER ignore
VOLUME_UP ignore
VOLUME_DOWN ignore
# uosc menu
# text after the shebang is parsed by uosc to construct the menu and names
menu script-binding uosc/menu
s script-binding uosc/subtitles #! Subtitles
a script-binding uosc/audio #! Audio tracks
q script-binding uosc/stream-quality #! Stream quality
p script-binding uosc/items #! Playlist
c script-binding uosc/chapters #! Chapters
> script-binding uosc/next #! Navigation > Next
< script-binding uosc/prev #! Navigation > Prev
o script-binding uosc/open-file #! Navigation > Open file
# set video-aspect-override "-1" #! Utils > Aspect ratio > Default
# set video-aspect-override "16:9" #! Utils > Aspect ratio > 16:9
# set video-aspect-override "4:3" #! Utils > Aspect ratio > 4:3
# set video-aspect-override "2.35:1" #! Utils > Aspect ratio > 2.35:1
# script-binding uosc/audio-device #! Utils > Audio devices
# script-binding uosc/editions #! Utils > Editions
ctrl+s async screenshot #! Utils > Screenshot
alt+i script-binding uosc/keybinds #! Utils > Key bindings
O script-binding uosc/show-in-directory #! Utils > Show in directory
# script-binding uosc/open-config-directory #! Utils > Open config directory
# set pause yes; run ${execInTerm} go2tv -v "''${stream-open-filename}" #! Cast
# set pause yes; run ${execInTerm} go2tv -u "''${stream-open-filename}" #! Cast (...) > Stream
# set pause yes; run go2tv #! Cast (...) > GUI
# TODO: unify "Cast" and "Cast (stream)" options above.
'';
fs.".config/mpv/mpv.conf".symlink.text = ''
save-position-on-quit=yes
keep-open=yes
# force GUI, even for tracks w/o album art
# see: <https://www.reddit.com/r/mpv/comments/rvrrpt/oscosdgui_and_arch_linux/>
player-operation-mode=pseudo-gui
# use uosc instead (for On Screen Controls)
osc=no
# uosc provides its own seeking/volume indicators, so you also don't need this
osd-bar=no
# uosc will draw its own window controls if you disable window border
border=no
'';
fs.".config/mpv/script-opts/osc.conf".symlink.text = ''
# make the on-screen controls *always* visible
# unfortunately, this applies to full-screen as well
# - docs: <https://mpv.io/manual/master/#on-screen-controller-visibility>
# if uosc is installed, this file is unused
visibility=always
'';
fs.".config/mpv/script-opts/uosc.conf".symlink.text = let
play_pause_btn = "cycle:play_arrow:pause:no=pause/yes=play_arrow";
rev_btn = "command:replay_10:seek -10";
fwd_btn = "command:forward_30:seek 30";
in ''
# docs:
# - <https://github.com/tomasklaen/uosc>
# - <https://github.com/tomasklaen/uosc/blob/main/src/uosc.conf>
# - <https://superuser.com/questions/1775550/add-new-buttons-to-mpv-uosc-ui>
timeline_style=bar
timeline_persistency=paused,audio
controls_persistency=paused,audio
volume_persistency=audio
volume_opacity=0.75
# speed_persistency=paused,audio
# vvv want a close button?
top_bar=always
top_bar_persistency=paused
controls=menu,<video>subtitles,<has_many_audio>audio,<has_many_video>video,<has_many_edition>editions,<stream>stream-quality,space,${rev_btn},${play_pause_btn},${fwd_btn},space,speed:1.0,gap,<video>fullscreen
text_border=6.0
font_bold=yes
color=foreground=ff8080,background_text=ff8080
ui_scale=1.0
'';
# mime.priority = 200; # default = 100; 200 means to yield to other apps
mime.priority = 50; # default = 100; 50 in order to take precedence over vlc.
mime.associations."audio/flac" = "mpv.desktop";
mime.associations."audio/mpeg" = "mpv.desktop";
mime.associations."audio/x-opus+ogg" = "mpv.desktop";
mime.associations."audio/x-vorbis+ogg" = "mpv.desktop";
mime.associations."video/mp4" = "mpv.desktop";
mime.associations."video/quicktime" = "mpv.desktop";
mime.associations."video/webm" = "mpv.desktop";
mime.associations."video/x-flv" = "mpv.desktop";
mime.associations."video/x-matroska" = "mpv.desktop";
mime.urlAssociations."^https?://(www.)?youtube.com/watch\?.*v=" = "mpv.desktop";
mime.urlAssociations."^https?://(www.)?youtube.com/v/" = "mpv.desktop";
mime.urlAssociations."^https?://(www.)?youtu.be/.+" = "mpv.desktop";
};
}

View File

@@ -0,0 +1,3 @@
# font size used by mpv's console (`); default 16
# font_size=28
scale=2

View File

@@ -0,0 +1,166 @@
# curated mpv mods/scripts/users:
# - <https://github.com/stax76/awesome-mpv>
# mpv docs:
# - <https://mpv.io/manual/master>
# - <https://github.com/mpv-player/mpv/wiki>
# extensions i use:
# - <https://github.com/jonniek/mpv-playlistmanager>
# other extensions that could be useful:
# - list: <https://github.com/stax76/awesome-mpv>
# - list: <https://nudin.github.io/mpv-script-directory/>
# - browse DLNA shares: <https://github.com/chachmu/mpvDLNA>
# - act as a DLNS renderer (sink): <https://github.com/xfangfang/Macast>
# debugging:
# - enter console by pressing backtick.
# > `set volume 50` -> sets application volume to 50%
# > `set ao-volume 50` -> sets system-wide volume to 50%
# > `show-text "vol: ${volume}"` -> get the volume
# - show script output by running mpv with `--msg-level=all=trace`
# - and then just `print(...)` from lua & it'll show in terminal
# - invoke mpv with `--no-config` to have it not read ~/.config/mpv/*
# - press `i` to show decoder info
#
# usage tips:
# - `<` or `>` to navigate prev/next-file-in-folder (uosc)
# - shift+enter to view the playlist, then arrow-keys to navigate (mpv-playlistmanager)
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.mpv;
uosc = pkgs.mpvScripts.uosc.overrideAttrs (upstream: {
# patch so that the volume control corresponds to `ao-volume`, i.e. the system-wide volume.
# this is particularly nice for moby, because it avoids the awkwardness that system volume
# is hard to adjust while screen is on.
# note that only under alsa (`-ao=alsa`) does `ao-volume` actually correspond to system volume.
postPatch = (upstream.postPatch or "") + ''
substituteInPlace src/uosc/main.lua \
--replace-fail "mp.observe_property('volume'" "mp.observe_property('ao-volume'"
substituteInPlace src/uosc/elements/Volume.lua \
--replace-fail "mp.commandv('set', 'volume'" "mp.commandv('set', 'ao-volume'" \
--replace-fail "mp.set_property_native('volume'" "mp.set_property('ao-volume'"
# `ao-volume` isn't actually an observable property.
# as of 2024/03/02, they *may* be working on that:
# - <https://github.com/mpv-player/mpv/pull/13604#issuecomment-1971665736>
# in the meantime, just query the volume every tick (i.e. frame).
# alternative is mpv's JSON IPC feature, where i could notify its socket whenever pipewire volume changes.
cat <<EOF >> src/uosc/main.lua
function update_ao_volume()
local vol = mp.get_property('ao-volume')
if vol ~= nil then
vol = tonumber(vol)
if vol ~= state.volume then
set_state('volume', vol)
request_render()
end
end
end
-- tick seems to occur on every redraw (even when volume is hidden).
-- in practice: for every new frame of the source, or whenever the cursor is moved.
mp.register_event('tick', update_ao_volume)
-- if paused and cursor isn't moving, then `tick` isn't called. fallback to a timer.
mp.add_periodic_timer(2, update_ao_volume)
-- invoke immediately to ensure state.volume is non-nil
update_ao_volume()
if state.volume == nil then
state.volume = 0
end
EOF
'';
});
in
{
sane.programs.mpv = {
packageUnwrapped = with pkgs; wrapMpv mpv-unwrapped {
scripts = [
mpvScripts.mpris
mpvScripts.mpv-playlistmanager
uosc
# pkgs.mpv-uosc-latest
];
# extraMakeWrapperArgs = lib.optionals (cfg.config.vo != null) [
# # 2023/08/29: fixes an error where mpv on moby launches with the message
# # "DRM_IOCTL_MODE_CREATE_DUMB failed: Cannot allocate memory"
# # audio still works, and controls, screenshotting, etc -- just not the actual rendering
# #
# # this is likely a regression for mpv 0.36.0.
# # the actual error message *appears* to come from the mesa library, but it's tough to trace.
# #
# # 2024/03/02: no longer necessary, with mesa 23.3.1: <https://github.com/NixOS/nixpkgs/pull/265740>
# #
# # backend compatibility (2023/10/22):
# # run with `--vo=help` to see a list of all output options.
# # non-exhaustive (W=works, F=fails, A=audio-only, U=audio+ui only (no video))
# # ? null Null video output
# # A (default)
# # A dmabuf-wayland Wayland dmabuf video output
# # A libmpv render API for libmpv (mpv plays the audio, but doesn't even render a window)
# # A vdpau VDPAU with X11
# # F drm Direct Rendering Manager (software scaling)
# # F gpu-next Video output based on libplacebo
# # F vaapi VA API with X11
# # F x11 X11 (software scaling)
# # F xv X11/Xv
# # U gpu Shader-based GPU Renderer
# # W caca libcaca (terminal rendering)
# # W sdl SDL 2.0 Renderer
# # W wlshm Wayland SHM video output (software scaling)
# "--add-flags" "--vo=${cfg.config.vo}"
# ];
};
suggestedPrograms = [
"blast-to-default"
"go2tv"
"xdg-terminal-exec"
];
sandbox.method = "bwrap";
sandbox.autodetectCliPaths = true;
sandbox.net = "all";
sandbox.whitelistAudio = true;
sandbox.whitelistDbus = [ "user" ]; #< mpris
sandbox.whitelistDri = true; #< mpv has excellent fallbacks to non-DRI, but DRI offers a good 30%-50% reduced CPU
sandbox.whitelistWayland = true;
sandbox.extraHomePaths = [
".config/mpv" #< else mpris plugin crashes on launch
".local/share/applications" #< for xdg-terminal-exec (go2tv)
# it's common for album (or audiobook, podcast) images/lyrics/metadata to live adjacent to the primary file.
# CLI detection is too poor to pick those up, so expose the common media dirs to the sandbox to make that *mostly* work.
"Books/local"
"Books/servo"
"Music"
"Videos/gPodder"
"Videos/local"
"Videos/servo"
];
persist.byStore.plaintext = [
# for `watch_later`
".local/state/mpv"
];
fs.".config/mpv/scripts/sane/main.lua".symlink.target = ./sane-main.lua;
fs.".config/mpv/input.conf".symlink.target = ./input.conf;
fs.".config/mpv/mpv.conf".symlink.target = ./mpv.conf;
fs.".config/mpv/script-opts/osc.conf".symlink.target = ./osc.conf;
fs.".config/mpv/script-opts/console.conf".symlink.target = ./console.conf;
fs.".config/mpv/script-opts/uosc.conf".symlink.target = ./uosc.conf;
fs.".config/mpv/script-opts/playlistmanager.conf".symlink.target = ./playlistmanager.conf;
# mime.priority = 200; # default = 100; 200 means to yield to other apps
mime.priority = 50; # default = 100; 50 in order to take precedence over vlc.
mime.associations."audio/flac" = "mpv.desktop";
mime.associations."audio/mpeg" = "mpv.desktop";
mime.associations."audio/x-opus+ogg" = "mpv.desktop";
mime.associations."audio/x-vorbis+ogg" = "mpv.desktop";
mime.associations."video/mp4" = "mpv.desktop";
mime.associations."video/quicktime" = "mpv.desktop";
mime.associations."video/webm" = "mpv.desktop";
mime.associations."video/x-flv" = "mpv.desktop";
mime.associations."video/x-matroska" = "mpv.desktop";
mime.urlAssociations."^https?://(www.)?youtube.com/watch\?.*v=" = "mpv.desktop";
mime.urlAssociations."^https?://(www.)?youtube.com/v/" = "mpv.desktop";
mime.urlAssociations."^https?://(www.)?youtu.be/.+" = "mpv.desktop";
};
}

View File

@@ -0,0 +1,37 @@
# docs:
# - <https://mpv.io/manual/master/#list-of-input-commands>
# - script-binding: <https://mpv.io/manual/master/#command-interface-script-binding>
# - properties: <https://mpv.io/manual/master/#property-list>
# let volume/power keys be interpreted by the system.
# this is important for sxmo.
# mpv defaults is POWER = close, VOLUME_{UP,DOWN} = adjust application-level volume
POWER ignore
VOLUME_UP ignore
VOLUME_DOWN ignore
# uosc menu
# text after the shebang is parsed by uosc to construct the menu and names
menu script-binding uosc/menu
s script-binding uosc/subtitles #! Subtitles
a script-binding uosc/audio #! Audio tracks
q script-binding uosc/stream-quality #! Stream quality
p script-binding uosc/items #! Playlist
c script-binding uosc/chapters #! Chapters
> script-binding uosc/next #! Navigation > Next
< script-binding uosc/prev #! Navigation > Prev
o script-binding uosc/open-file #! Navigation > Open file
# set video-aspect-override "-1" #! Utils > Aspect ratio > Default
# set video-aspect-override "16:9" #! Utils > Aspect ratio > 16:9
# set video-aspect-override "4:3" #! Utils > Aspect ratio > 4:3
# set video-aspect-override "2.35:1" #! Utils > Aspect ratio > 2.35:1
# script-binding uosc/audio-device #! Utils > Audio devices
# script-binding uosc/editions #! Utils > Editions
ctrl+s async screenshot #! Utils > Screenshot
alt+i script-binding uosc/keybinds #! Utils > Key bindings
O script-binding uosc/show-in-directory #! Utils > Show in directory
# script-binding uosc/open-config-directory #! Utils > Open config directory
ctrl+r script-binding sane/blast #! Audiocast
ctrl+t script-binding sane/go2tv-video #! Cast
# script-binding sane/go2tv-stream #! Cast (...) > Stream
# script-binding sane/go2tv-gui #! Cast (...) > GUI

View File

@@ -0,0 +1,26 @@
# write ~/.local/state/mpv/watch_later on exit, to allow resume
save-position-on-quit=yes
# identify resumed files by filename only, since i use so many symlinks and doubt mpv does well with that.
ignore-path-in-watch-later-config
# keep-open: don't exit on completion of last file in playlist
keep-open=yes
# seeking once at the end of the file causes auto-resume
keep-open-pause=no
# force GUI, even for tracks w/o album art
# see: <https://www.reddit.com/r/mpv/comments/rvrrpt/oscosdgui_and_arch_linux/>
player-operation-mode=pseudo-gui
# use uosc instead (for On Screen Controls)
osc=no
# uosc provides its own seeking/volume indicators, so you also don't need this
osd-bar=no
# uosc will draw its own window controls if you disable window border
border=no
# ao=alsa so that uosc can work with ao-volume (see my uosc patch)
ao=alsa
# with `ao-volume`, the max actually is 100.
# to go higher you'll have to use the system's native controls.
volume-max=100

View File

@@ -0,0 +1,5 @@
# make the on-screen controls *always* visible
# unfortunately, this applies to full-screen as well
# - docs: <https://mpv.io/manual/master/#on-screen-controller-visibility>
# if uosc is installed, this file is unused
visibility=always

View File

@@ -0,0 +1,4 @@
# script docs: <https://github.com/jonniek/mpv-playlistmanager>
# auto-populate playlist with other files in the same directory, on launch.
loadfiles_on_start=yes

View File

@@ -0,0 +1,34 @@
function subprocess(in_terminal, args)
if in_terminal then
args = { "xdg-terminal-exec", table.unpack(args) }
end
mp.command_native({
name = "subprocess",
args = args,
detach = false,
capture_stdout = false,
capture_stderr = false,
-- capture_size=0,
passthrough_stdin = false,
playback_only = false,
})
end
function invoke_go2tv(in_terminal, args)
mp.commandv("set", "pause", "yes")
subprocess(in_terminal, { "go2tv", table.unpack(args) })
end
function invoke_go2tv_on_open_file(mode)
local path = mp.get_property("stream-open-filename");
return invoke_go2tv(true, { mode, path })
end
mp.add_key_binding(nil, "blast", function() subprocess(false, { "blast-to-default" }) end)
mp.add_key_binding(nil, 'go2tv-gui', function() invoke_go2tv(false, {}) end)
mp.add_key_binding(nil, 'go2tv-video', function() invoke_go2tv_on_open_file("-v") end)
mp.add_key_binding(nil, 'go2tv-stream', function() invoke_go2tv_on_open_file("-s") end)
-- uncomment for debugging:
-- if mpv fails to eval this script (e.g. syntax error), then it will fail to quit on launch
-- mp.command('quit')

View File

@@ -0,0 +1,32 @@
# docs:
# - <https://github.com/tomasklaen/uosc>
# - <https://github.com/tomasklaen/uosc/blob/main/src/uosc.conf>
# - <https://superuser.com/questions/1775550/add-new-buttons-to-mpv-uosc-ui>
timeline_style=bar
timeline_line_width=4
timeline_size=36
timeline_persistency=paused,audio
controls_persistency=paused,audio
volume_persistency=audio
# speed_persistency=paused,audio
# vvv want a close button?
top_bar=always
top_bar_persistency=paused,audio
controls=menu,<video>subtitles,<has_many_audio>audio,<has_many_video>video,<has_many_edition>editions,<stream>stream-quality,space,command:replay_10:seek -10,cycle:play_arrow:pause:no=pause/yes=play_arrow,command:forward_30:seek 30,space,speed:1.0,gap,<video>fullscreen
# text_border: shadow to place around icons/text which is rendered over the video
text_border=5.0
# border_radius: rounding of volume slider, etc.
border_radius=5.0
font_scale=1.5
font_bold=yes
# refine=text_width: slightly better text rendering
refine=text_width
color=foreground=ff8080,background_text=ff8080
# N.B.: if `opacity=` is set non-empty, then ALL items must be specified (else they get 0 opacity).
# opacity values *must* be a multiple of 0.1
opacity=timeline=0.8,position=1,chapters=0.8,slider=0.8,slider_gauge=0.8,controls=0,speed=0.8,menu=1,submenu=0.4,border=1,title=0.8,tooltip=1,thumbnail=1,curtain=0.8,idle_indicator=0.8,audio_indicator=0.5,buffering_indicator=0.3,playlist_position=0.8
stream_quality_options=1440,1080,720,480,360,240,144

View File

@@ -1,16 +1,16 @@
{ pkgs, ... }:
{
sane.programs."gnome.nautilus" = {
packageUnwrapped = pkgs.gnome.nautilus.overrideAttrs (orig: {
# some of its dbus services don't even refer to real paths
packageUnwrapped = pkgs.rmDbusServicesInPlace (pkgs.gnome.nautilus.overrideAttrs (orig: {
# enable the "Audio and Video Properties" pane. see: <https://nixos.wiki/wiki/Nautilus>
buildInputs = orig.buildInputs ++ (with pkgs.gst_all_1; [
gst-plugins-good
gst-plugins-bad
]);
});
}));
sandbox.method = "bwrap";
sandbox.wrapperType = "inplace";
sandbox.whitelistDbus = [ "user" ]; # for portals launching apps
sandbox.whitelistWayland = true;
sandbox.extraHomePaths = [

View File

@@ -88,7 +88,6 @@ in
{
sane.programs.neovim = {
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.autodetectCliPaths = "existingOrParent";
sandbox.whitelistWayland = true; # for system clipboard integration
# sandbox.whitelistPwd = true;

View File

@@ -11,7 +11,6 @@
});
sandbox.method = "firejail";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistWayland = true;
sandbox.net = "vpn";

View File

@@ -3,7 +3,6 @@
# provides `nix-locate`, backed by the manually run `nix-index`
sane.programs.nix-index = {
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "clearnet";
sandbox.extraPaths = [
"/nix"

View File

@@ -2,7 +2,6 @@
{
sane.programs.notejot = {
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistWayland = true;
suggestedPrograms = [ "dconf" ]; #< else it can't persist notes

View File

@@ -21,7 +21,6 @@ in
};
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.net = "clearnet";
secrets.".config/ntfy-sh/topic" = ../../../secrets/common/ntfy-sh-topic.bin;

View File

@@ -3,7 +3,6 @@
{
sane.programs.open-in-mpv = {
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistDbus = [ "user" ]; # for xdg-open/portals
# taken from <https://github.com/Baldomo/open-in-mpv>

View File

@@ -1,5 +1,5 @@
# administer with pw-cli, pw-mon, pw-top commands
{ config, lib, ... }:
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.pipewire;
in
@@ -18,6 +18,10 @@ in
sandbox.extraRuntimePaths = [ "/" ];
sandbox.extraPaths = [
"/dev/snd"
# desko/lappy don't need these, but moby complains if not present
"/dev/video0"
"/dev/video1"
"/dev/video2"
];
sandbox.extraHomePaths = [
# pulseaudio cookie
@@ -30,10 +34,23 @@ in
wantedBy = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/pipewire";
ExecStartPost = pkgs.writeShellScript "pipewire-wait-started" ''
waitFor() {
while [ ! -e "$1" ]; do
sleep 1
done
}
waitFor "$XDG_RUNTIME_DIR/pipewire-0"
waitFor "$XDG_RUNTIME_DIR/pipewire-0-manager"
'';
ExecStopPost = ''rm -f "$XDG_RUNTIME_DIR/{pipewire-0,pipewire-0.lock,pipewire-0-manager,pipewire-0-manager.lock}"'';
Type = "simple";
Restart = "always";
RestartSec = "5s";
};
# environment.PIPEWIRE_LOG_SYSTEMD = "false";
# environment.PIPEWIRE_DEBUG = "*:3,mod.raop*:5,pw.rtsp-client*:5";
};
services.pipewire-pulse = {
description = "pipewire-pulse: Pipewire compatibility layer for PulseAudio clients";
@@ -41,6 +58,16 @@ in
wantedBy = [ "pipewire.service" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/pipewire-pulse";
ExecStartPost = pkgs.writeShellScript "pipewire-pulse-wait-started" ''
waitFor() {
while [ ! -e "$1" ]; do
sleep 1
done
}
waitFor "$XDG_RUNTIME_DIR/pulse/native"
waitFor "$XDG_RUNTIME_DIR/pulse/pid"
'';
ExecStopPost = ''rm -f "$XDG_RUNTIME_DIR/pulse/{native,pid}"'';
Type = "simple";
Restart = "always";
RestartSec = "5s";

View File

@@ -2,7 +2,6 @@
{
sane.programs.planify = {
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistDbus = [ "user" ]; # for dconf? else it can't persist any tasks/notes
sandbox.whitelistWayland = true;

View File

@@ -2,7 +2,7 @@
{
sane.programs.playerctl = {
sandbox.method = "bwrap";
sandbox.wrapperType = "inplace";
sandbox.wrapperType = "inplace"; #< /lib/pkgconfig/playerctl.pc refers to $out by full path
sandbox.whitelistDbus = [ "user" ]; # notifications
services.playerctld = {

View File

@@ -3,7 +3,6 @@
sane.programs.portfolio-filemanager = {
# this is all taken pretty directly from nautilus config
sandbox.method = "bwrap";
sandbox.wrapperType = "inplace";
sandbox.whitelistDbus = [ "user" ]; # for portals launching apps
sandbox.whitelistWayland = true;
sandbox.extraHomePaths = [

View File

@@ -2,7 +2,6 @@
{
sane.programs.ripgrep = {
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.autodetectCliPaths = true;
sandbox.whitelistPwd = true;
sandbox.extraHomePaths = [

View File

@@ -6,33 +6,112 @@
configuration {
modes: "combi";
font: "mono 20";
show-icons: true;
combi-modes: "filebrowser,drun,run";
kb-accept-entry: "Return,KP_Enter,XF86PowerOff";
kb-row-up: "Up,XF86AudioRaiseVolume";
kb-row-down: "Down,XF86AudioLowerVolume";
filebrowser {
/* filebrowser starting directory */
directory: "/home";
/* display-name: text to prepend in combi mode */
display-name: "/";
/* `command` is the prefix to prepend (along with a space) *before* passing it off to `run-command` */
command: "xdg-open";
}
drun {
display-name: " ";
}
run {
display-name: "run ";
cache-dir: "~/.cache/rofi";
/* to position rofi to the top of the screen: */
/* location: 2; */
combi {
/* this is rendered in the filter box, here we disable it */
display-name: "";
}
/* combi-display-format: "{mode} {text}"; */
/* combi-display-format: "{text}"; */
combi-display-format: "{mode}{text}";
combi-modes: "filebrowser,drun";
drun {
display-name: " ";
}
drun-use-desktop-cache: true;
filebrowser {
/* directory: filebrowser starting directory. leave unset to start at the last directory. */
/* directory: "/home"; */
/* display-name: text to prepend in combi mode */
display-name: "/";
/* `command` is the prefix to prepend (along with a space) *before* passing it off to `run-command` */
command: "xdg-open";
directories-first: true;
/* sorting-method: name/atime/ctime/mtime */
sorting-method: "name";
show-hidden: false;
}
run {
display-name: "run ";
}
/* launch applications via my own launcher, which directs them through to xdg-desktop-portal */
run-command: "rofi-run-command '{app_id}.desktop' {cmd}";
drun-use-desktop-cache: true;
}
@theme "gruvbox-light"
/* theme */
* {
/* my own variables */
bg: #1d1721; /* slight purple */
fg0: #d8d8d8; /* inactive text (light grey) */
fg1: #ffffff; /* active text (white) */
accent0: #1f5e54; /* darker but saturated teal */
accent1: #418379; /* teal (matches nixos-bg) */
accent2: #5b938a; /* brighter but muted teal */
/* map my variables to variables rofi uses internally */
background-color: var(accent0);
background: var(accent0);
/* foreground: non-alternating text, scrollbar, borders, separators */
foreground: var(fg0);
/* override derived styles */
alternate-active-background: var(accent0);
alternate-normal-background: var(accent0);
alternate-active-foreground: var(fg0);
alternate-normal-foreground: var(fg0);
border-color: var(accent0);
text-color: var(fg0);
selected-active-background: var(accent1);
selected-normal-background: var(accent1);
selected-active-foreground: var(fg1);
selected-normal-foreground: var(fg1);
separatorcolor: var(accent1);
}
entry {
placeholder: "";
text-color: var(fg1);
}
num-rows, num-filtered-rows {
text-color: var(fg0);
}
prompt, textbox-prompt-colon {
/* hide */
text-color: var(accent0);
}
scrollbar {
handle-color: var(accent2);
}
window {
/* rofi supports very complex calculations here */
/* one may even read environment variables (useful for knowing if screen is rotated?) */
/* `calc(... min 100%)` ensures it never overflows */
/* rofi is aware of the top bar (waybar) and any virtual keyboards,
* so e.g. height: 100% will occupy 100% of the height *not* allocated to bars/kbds.
* however with y-offset, it becomes possible to overflow */
width: calc(960 min 100%);
/* 520px @ font size 20 gives 13 rows + filter */
/* 482px @ font size 20 gives 12 rows + filter */
/* 446px @ font size 20 gives 11 rows + filter */
/* 90.5% @ font size 20, sway scale 2.0, moby in landscape mode: gives 7 rows + filter */
height: calc(446 min 90.5%);
/* anchor the *north* edge of the window at the *north* location of the screen */
anchor: north;
location: north;
/* 11.2% lines up nicely with Firefox */
y-offset: 11.2%;
}

View File

@@ -25,28 +25,27 @@
{ pkgs, ... }:
let
rofi-unwrapped = pkgs.rofi-wayland-unwrapped.overrideAttrs (upstream: {
# my patches made for tip don't cleanly apply to stable, so advance the entire src
src = pkgs.fetchFromGitea {
domain = "git.uninsane.org";
owner = "colin";
repo = "rofi";
fetchSubmodules = true;
# rev = "dev-sane"; #< fetchFromGitea doesn't support tags (?)
rev = "1edfceaeefa2cae971ae90dc55811f3b7592a1b4";
hash = "sha256-oIWLwec1LRsss12S92ebBWQk14FBJWc6QcYxzOU3eFI=";
};
# patches = (upstream.patches or []) ++ [
# (pkgs.fetchpatch {
# url = "https://git.uninsane.org/colin/rofi/commit/d8bb0b9944ec1f3bf7479c9f127ec09d4198e87f.patch";
# name = "run-{shell-,}command: expand `{app_id}` inside the template string";
# hash = "sha256-XiZRvr+BARU7h3OPU0NUUEem3isnUVER69zucSqvNNk=";
# })
# ];
patches = (upstream.patches or []) ++ [
(pkgs.fetchpatch {
url = "https://git.uninsane.org/colin/rofi/commit/8e01fcd16f97f4c2a5bc63ade58c894a938f89d9.patch";
name = "run-{shell-,}command: expand `{app_id}` inside the template string";
hash = "sha256-DXafvvKrNyDOH11lpRdC2ljydb422ttY68oY5K3fKWo=";
})
(pkgs.fetchpatch {
url = "https://git.uninsane.org/colin/rofi/commit/249450a2b58c3cf7ced911cadb8c4c60d3315dd0.patch";
name = "filebrowser: include entries of d_type DT_UNKNOWN";
hash = "sha256-gz3N4uo7IWzzqaPHHVhby/e9NbtzcFJRQwgdNYxO/Yw=";
})
];
});
# rofi-emoji = pkgs.rofi-emoji.override {
# # plugins must be compiled against the same rofi they're loaded by
# inherit rofi-unwrapped;
# };
# rofi-file-browser = pkgs.rofi-file-browser.override {
# # plugins must be compiled against the same rofi they're loaded by
# rofi = rofi-unwrapped;
# };
in
{
sane.programs.rofi = {
@@ -54,8 +53,15 @@ in
# it's actively maintained though, and more of an overlay than a true fork.
packageUnwrapped = pkgs.rofi-wayland.override {
inherit rofi-unwrapped;
# rofi-emoji: "insert" mode doesn't work; use a wrapper like `splatmoji` instead.
# plugins = [ rofi-emoji ];
plugins = [
# rofi-[extended-]-file-browser: <https://github.com/marvinkreis/rofi-file-browser-extended>
# because the builtin rofi filebrowser only partially lists ~/Videos/servo/Shows, seemingly at random.
# but rofi-file-browser doesn't compile against my patched rofi (oops)
# rofi-file-browser
# rofi-emoji: "insert" mode doesn't work; use a wrapper like `splatmoji` instead.
# rofi-emoji
];
};
suggestedPrograms = [
@@ -63,11 +69,12 @@ in
];
sandbox.method = "bwrap";
sandbox.wrapperType = "wrappedDerivation";
sandbox.whitelistDbus = [ "user" ]; #< to launch apps via the portal
sandbox.whitelistWayland = true;
sandbox.extraHomePaths = [
".local/share/applications" #< to locate .desktop files
"Books/local"
"Books/servo"
"Music"
"Pictures/albums"
"Pictures/cat"
@@ -75,18 +82,22 @@ in
"Pictures/Photos"
"Pictures/Screenshots"
"Pictures/servo-macros"
"Videos/gPodder"
"Videos/local"
"Videos/servo"
"knowledge"
"tmp"
];
sandbox.extraPaths = [
"/mnt/servo/media"
"/mnt/servo/playground"
];
fs.".config/rofi/config.rasi".symlink.target = ./config.rasi;
# redirect its default drun cache location
fs.".cache/rofi3.druncache".symlink.target = "rofi/rofi3.druncache";
fs.".cache/rofi-drun-desktop.cache".symlink.target = "rofi/rofi-drun-desktop.cache";
persist.byStore.cryptClearOnBoot = [
# optional, for caching .desktop files rofi finds on disk (perf)
# this gets us a few things:
# - file browser remembers its last directory
# - caching of .desktop files (perf)
".cache/rofi"
];
};
@@ -95,13 +106,47 @@ in
packageUnwrapped = pkgs.static-nix-shell.mkBash {
pname = "rofi-run-command";
srcRoot = ./.;
pkgs = [ "glib" "xdg-utils" ];
pkgs = [ "sane-open-desktop" "xdg-utils" ];
};
sandbox.enable = false; #< trivial script, and all our deps are sandboxed
suggestedPrograms = [
"gdbus"
"sane-open-desktop"
"xdg-utils"
];
};
sane.programs.rofi-snippets = {
packageUnwrapped = pkgs.static-nix-shell.mkBash {
pname = "rofi-snippets";
srcRoot = ./.;
pkgs = [
"gnused"
"rofi"
"wtype"
];
nativeBuildInputs = [
pkgs.copyDesktopItems
];
desktopItems = [
(pkgs.makeDesktopItem {
name = "rofi-snippets";
exec = "rofi-snippets";
desktopName = "rofi macro to insert common texts";
})
];
};
# if i could remove the sed, then maybe possible to not sandbox.
sandbox.method = "bwrap";
sandbox.whitelistWayland = true;
sandbox.extraHomePaths = [
".cache/rofi"
".config/rofi/config.rasi"
];
suggestedPrograms = [ "rofi" ];
fs.".config/rofi-snippets/public.txt".symlink.target = ./snippets.txt;
secrets.".config/rofi-snippets/private.txt" = ../../../../secrets/common/snippets.txt.bin;
};
}

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p glib -p xdg-utils
#!nix-shell -i bash -p sane-open-desktop -p xdg-utils
# use:
# rofi-run-command <handler>.desktop [cmd [args ...]]
@@ -14,11 +14,13 @@ shift
binArgs=("$@")
if [ "$desktop" != .desktop ]; then
exec gdbus call --session --timeout 10 \
--dest org.freedesktop.portal.Desktop \
--object-path /org/freedesktop/portal/desktop \
--method org.freedesktop.portal.DynamicLauncher.Launch \
"$desktop" {}
# launching an app; the file browser position is no longer interesting: clear it so it opens in ~ next time.
# better UX would be to manage this in the other branch:
# - open in ~ by default, regardless of last directory
# - after launching a *file*, when that file is closed, re-open rofi in that file's directory.
# however, `xdg-open` and the `OpenFile` xdg-desktop-portal API don't give any obvious way to block for the app to close.
rm -f ~/.cache/rofi/rofi3.filebrowsercache
exec sane-open-desktop "$desktop"
elif [ "$binary" = "xdg-open" ]; then
exec xdg-open "$@"
fi

Some files were not shown because too many files have changed in this diff Show More