Compare commits
24 Commits
dev-export
...
sxmo-sway-
Author | SHA1 | Date | |
---|---|---|---|
e89805cd17 | |||
680ab2c189 | |||
10095e3ce5 | |||
a2b8e23eee | |||
0587c14af5 | |||
6a83e0ce6c | |||
72960aa963 | |||
5f4f047769 | |||
a880ba254b | |||
4d75c3d97a | |||
90511ed765 | |||
aa3b85511f | |||
5d90cbcc98 | |||
0525f99813 | |||
769019f2f5 | |||
dcaba0f0ee | |||
d33b6eec59 | |||
20aef83496 | |||
3cc4a1ea19 | |||
a41fefa906 | |||
c00bba3fcf | |||
63fab5899b | |||
357b6ef06e | |||
4fdf74fdbe |
6
flake.lock
generated
6
flake.lock
generated
@@ -85,11 +85,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-unpatched": {
|
"nixpkgs-unpatched": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1693377291,
|
"lastModified": 1693663421,
|
||||||
"narHash": "sha256-vYGY9bnqEeIncNarDZYhm6KdLKgXMS+HA2mTRaWEc80=",
|
"narHash": "sha256-ImMIlWE/idjcZAfxKK8sQA7A1Gi/O58u5/CJA+mxvl8=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "e7f38be3775bab9659575f192ece011c033655f0",
|
"rev": "e56990880811a451abd32515698c712788be5720",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
13
flake.nix
13
flake.nix
@@ -333,6 +333,19 @@
|
|||||||
-I ../../
|
-I ../../
|
||||||
'');
|
'');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
check-host-configs = {
|
||||||
|
type = "app";
|
||||||
|
program = builtins.toString (pkgs.writeShellScript
|
||||||
|
"check-host-configs"
|
||||||
|
(builtins.concatStringsSep "\n" (builtins.map
|
||||||
|
(host: "nix build '.#nixosConfigurations.${host}.config.system.build.toplevel' --out-link ./result-${host} -j1 $@ &")
|
||||||
|
[ "desko" "lappy" "servo" "moby" "rescue" ]
|
||||||
|
# not part of the `map`. wait for all builds to complete
|
||||||
|
++ [ "wait" ]
|
||||||
|
))
|
||||||
|
);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
templates = {
|
templates = {
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
sane.services.wg-home.ip = config.sane.hosts.by-name."lappy".wg-home.ip;
|
sane.services.wg-home.ip = config.sane.hosts.by-name."lappy".wg-home.ip;
|
||||||
|
|
||||||
# sane.guest.enable = true;
|
# sane.guest.enable = true;
|
||||||
sane.gui.sway.enable = true;
|
sane.gui.sxmo.enable = true;
|
||||||
boot.loader.efi.canTouchEfiVariables = false;
|
boot.loader.efi.canTouchEfiVariables = false;
|
||||||
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
sane.gui.sxmo = {
|
sane.gui.sxmo = {
|
||||||
greeter = "sway";
|
greeter = "greetd-sway-gtkgreet";
|
||||||
settings = {
|
settings = {
|
||||||
# XXX: make sure the user is part of the `input` group!
|
# 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";
|
SXMO_LISGD_INPUT_DEVICE = "/dev/input/by-id/usb-Wacom_Co._Ltd._Pen_and_multitouch_sensor-event-if00";
|
||||||
@@ -27,6 +27,9 @@
|
|||||||
# - SXMO_SWAY_SCALE
|
# - SXMO_SWAY_SCALE
|
||||||
# see <repo:mil/sxmo-utils:scripts/deviceprofiles>
|
# see <repo:mil/sxmo-utils:scripts/deviceprofiles>
|
||||||
# SXMO_DEVICE_NAME = "pine64,pinephone-1.2";
|
# 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-latest.overrideAttrs (base: {
|
package = pkgs.sxmo-utils-latest.overrideAttrs (base: {
|
||||||
postPatch = (base.postPatch or "") + ''
|
postPatch = (base.postPatch or "") + ''
|
||||||
|
@@ -14,9 +14,25 @@
|
|||||||
#
|
#
|
||||||
# compliance tests:
|
# compliance tests:
|
||||||
# - <https://compliance.conversations.im/server/uninsane.org/#xep0352>
|
# - <https://compliance.conversations.im/server/uninsane.org/#xep0352>
|
||||||
|
#
|
||||||
|
# administration:
|
||||||
|
# - `sudo -u ejabberd ejabberdctl help`
|
||||||
|
#
|
||||||
|
# federation/support matrix:
|
||||||
|
# - avatars
|
||||||
|
# - nixnet.services + dino: works in MUCs but not DMs (as of 2023 H1)
|
||||||
|
# - movim.eu + dino: works in DMs, MUCs untested (as of 2023/08/29)
|
||||||
|
# - calls
|
||||||
|
# - local + dino: audio, video, works in DMs (as of 2023/08/29)
|
||||||
|
# - movim.eu + dino: audio, video, works in DMs, no matter which side initiates (as of 2023/08/30)
|
||||||
|
# - +native-cell-number@cheogram.com + dino: audio works in DMs, no matter which side initiates (as of 2023/09/01)
|
||||||
|
# - can receive calls even if sender isn't in my roster
|
||||||
|
# - this is presumably using JMP.chat's SIP servers, which then convert it to XMPP call
|
||||||
|
#
|
||||||
|
# bugs:
|
||||||
|
# - 2023/09/01: will randomly stop federating. `systemctl restart ejabberd` fixes, but takes 10 minutes.
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
# XXX: avatar support works in MUCs but not DMs
|
|
||||||
let
|
let
|
||||||
# TODO: this range could be larger, but right now that's costly because each element is its own UPnP forward
|
# TODO: this range could be larger, but right now that's costly because each element is its own UPnP forward
|
||||||
# TURN port range (inclusive)
|
# TURN port range (inclusive)
|
||||||
|
@@ -5,21 +5,33 @@
|
|||||||
./sftpgo.nix
|
./sftpgo.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
users.groups.export = {};
|
||||||
|
|
||||||
fileSystems."/var/export/media" = {
|
fileSystems."/var/export/media" = {
|
||||||
# everything in here could be considered publicly readable (based on the viewer's legal jurisdiction)
|
# everything in here could be considered publicly readable (based on the viewer's legal jurisdiction)
|
||||||
device = "/var/lib/uninsane/media";
|
device = "/var/lib/uninsane/media";
|
||||||
options = [ "rbind" ];
|
options = [ "rbind" ];
|
||||||
};
|
};
|
||||||
fileSystems."/var/export/playground" = {
|
# fileSystems."/var/export/playground" = {
|
||||||
device = config.fileSystems."/mnt/persist/ext".device;
|
# device = config.fileSystems."/mnt/persist/ext".device;
|
||||||
fsType = "btrfs";
|
# fsType = "btrfs";
|
||||||
options = [
|
# options = [
|
||||||
"subvol=export-playground"
|
# "subvol=export-playground"
|
||||||
"compress=zstd"
|
# "compress=zstd"
|
||||||
"defaults"
|
# "defaults"
|
||||||
|
# ];
|
||||||
|
# };
|
||||||
|
# N.B.: the backing directory should be manually created here **as a btrfs subvolume** and with a quota.
|
||||||
|
# - `sudo btrfs subvolume create /mnt/persist/ext/persist/var/export/playground`
|
||||||
|
# - `sudo btrfs quota enable /mnt/persist/ext/persist/var/export/playground`
|
||||||
|
# - `sudo btrfs quota rescan -sw /mnt/persist/ext/persist/var/export/playground`
|
||||||
|
# to adjust the limits (which apply at the block layer, i.e. post-compression):
|
||||||
|
# - `sudo btrfs qgroup limit 20G /mnt/persist/ext/persist/var/export/playground`
|
||||||
|
# to query the quota/status:
|
||||||
|
# - `sudo btrfs qgroup show -re /var/export/playground`
|
||||||
|
sane.persist.sys.ext = [
|
||||||
|
{ user = "root"; group = "export"; mode = "0775"; path = "/var/export/playground"; }
|
||||||
];
|
];
|
||||||
};
|
|
||||||
|
|
||||||
sane.fs."/var/export/README.md" = {
|
sane.fs."/var/export/README.md" = {
|
||||||
wantedBy = [ "nfs.service" "sftpgo.service" ];
|
wantedBy = [ "nfs.service" "sftpgo.service" ];
|
||||||
@@ -29,14 +41,13 @@
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# sane.fs."/var/lib/sftpgo/export/playground/README.md" = {
|
sane.fs."/var/export/playground/README.md" = {
|
||||||
# wantedBy = [ "nfs.service" "sftpgo.service" ];
|
wantedBy = [ "nfs.service" "sftpgo.service" ];
|
||||||
# file.text = ''
|
file.text = ''
|
||||||
# this directory is intentionally read+write by anyone.
|
this directory is intentionally read+write by anyone with access (i.e. on the LAN).
|
||||||
# there are no rules, except a server-level quota:
|
- share files
|
||||||
# - share files
|
- write poetry
|
||||||
# - write poetry
|
- be a friendly troll
|
||||||
# - be a friendly troll
|
'';
|
||||||
# '';
|
};
|
||||||
# };
|
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,20 @@
|
|||||||
# docs:
|
# docs:
|
||||||
# - <https://nixos.wiki/wiki/NFS>
|
# - <https://nixos.wiki/wiki/NFS>
|
||||||
# - <https://wiki.gentoo.org/wiki/Nfs-utils>
|
# - <https://wiki.gentoo.org/wiki/Nfs-utils>
|
||||||
|
# system files:
|
||||||
|
# - /etc/exports
|
||||||
|
# system services:
|
||||||
|
# - nfs-server.service
|
||||||
|
# - nfs-idmapd.service
|
||||||
|
# - nfs-mountd.service
|
||||||
|
# - nfsdcld.service
|
||||||
|
# - rpc-statd.service
|
||||||
|
# - rpcbind.service
|
||||||
|
#
|
||||||
|
# TODO: force files to be 755, or 750.
|
||||||
|
# - could maybe be done with some mount option?
|
||||||
|
|
||||||
{ ... }:
|
{ config, lib, ... }:
|
||||||
{
|
{
|
||||||
services.nfs.server.enable = true;
|
services.nfs.server.enable = true;
|
||||||
|
|
||||||
@@ -52,10 +64,47 @@
|
|||||||
# - no_root_squash, root_squash (default): map requests from uid 0 to user `nobody`.
|
# - no_root_squash, root_squash (default): map requests from uid 0 to user `nobody`.
|
||||||
# - crossmnt: reveal filesystems that are mounted under this endpoint
|
# - crossmnt: reveal filesystems that are mounted under this endpoint
|
||||||
# - fsid: must be zero for the root export
|
# - fsid: must be zero for the root export
|
||||||
|
# - fsid=root is alias for fsid=0
|
||||||
# - mountpoint[=/path]: only export the directory if it's a mountpoint. used to avoid exporting failed mounts.
|
# - mountpoint[=/path]: only export the directory if it's a mountpoint. used to avoid exporting failed mounts.
|
||||||
|
# - all_squash: rewrite all client requests such that they come from anonuid/anongid
|
||||||
|
# - any files a user creates are owned by local anonuid/anongid.
|
||||||
|
# - users can read any local file which anonuid/anongid would be able to read.
|
||||||
|
# - users can't chown to/away from anonuid/anongid.
|
||||||
|
# - users can chmod files they own, to anything (making them unreadable to non-`nfsuser` export users, like FTP).
|
||||||
|
# - `stat` remains unchanged, returning the real UIDs/GIDs to the client.
|
||||||
|
# - thus programs which check `uid` or `gid` before trying an operation may incorrectly conclude they can't perform some op.
|
||||||
#
|
#
|
||||||
# 10.0.0.0/8 to export (readonly) both to LAN (unencrypted) and wg vpn (encrypted)
|
# 10.0.0.0/8 to export both to LAN (readonly, unencrypted) and wg vpn (read-write, encrypted)
|
||||||
services.nfs.server.exports = ''
|
services.nfs.server.exports =
|
||||||
/var/export 10.78.79.0/22(ro,crossmnt,fsid=0,subtree_check) 10.0.10.0/24(rw,no_root_squash,crossmnt,fsid=0,subtree_check)
|
let
|
||||||
'';
|
fmtExport = { export, baseOpts, extraLanOpts ? [], extraVpnOpts ? [] }:
|
||||||
|
let
|
||||||
|
always = [ "subtree_check" ];
|
||||||
|
lanOpts = always ++ baseOpts ++ extraLanOpts;
|
||||||
|
vpnOpts = always ++ baseOpts ++ extraVpnOpts;
|
||||||
|
in "${export} 10.78.79.0/22(${lib.concatStringsSep "," lanOpts}) 10.0.10.0/24(${lib.concatStringsSep "," vpnOpts})";
|
||||||
|
in lib.concatStringsSep "\n" [
|
||||||
|
(fmtExport {
|
||||||
|
export = "/var/export";
|
||||||
|
baseOpts = [ "crossmnt" "fsid=root" ];
|
||||||
|
extraLanOpts = [ "ro" ];
|
||||||
|
extraVpnOpts = [ "rw" "no_root_squash" ];
|
||||||
|
})
|
||||||
|
(fmtExport {
|
||||||
|
export = "/var/export/playground";
|
||||||
|
baseOpts = [
|
||||||
|
"mountpoint"
|
||||||
|
"all_squash"
|
||||||
|
"rw"
|
||||||
|
"anonuid=${builtins.toString config.users.users.nfsuser.uid}"
|
||||||
|
"anongid=${builtins.toString config.users.groups.export.gid}"
|
||||||
|
];
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
users.users.nfsuser = {
|
||||||
|
description = "virtual user for anonymous NFS operations";
|
||||||
|
group = "export";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@@ -9,9 +9,6 @@
|
|||||||
#
|
#
|
||||||
# TODO: change umask so sftpgo-created files default to 644.
|
# TODO: change umask so sftpgo-created files default to 644.
|
||||||
# - it does indeed appear that the 600 is not something sftpgo is explicitly doing.
|
# - it does indeed appear that the 600 is not something sftpgo is explicitly doing.
|
||||||
#
|
|
||||||
# TODO: enforce a "quota" by placing /playground on a btrfs subvolume
|
|
||||||
# - sane.persist API could expose a `subvolume` option to make this feel natural
|
|
||||||
|
|
||||||
|
|
||||||
{ config, lib, pkgs, sane-lib, ... }:
|
{ config, lib, pkgs, sane-lib, ... }:
|
||||||
@@ -126,6 +123,7 @@ in
|
|||||||
|
|
||||||
services.sftpgo = {
|
services.sftpgo = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
group = "export";
|
||||||
settings = {
|
settings = {
|
||||||
ftpd = {
|
ftpd = {
|
||||||
bindings = [
|
bindings = [
|
||||||
@@ -172,22 +170,10 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# fileSystems."/var/lib/sftpgo/export/media" = {
|
users.users.sftpgo.extraGroups = [ "export" ];
|
||||||
# # everything in here could be considered publicly readable (based on the viewer's legal jurisdiction)
|
|
||||||
# device = "/var/lib/uninsane/media";
|
systemd.services.sftpgo.serviceConfig = {
|
||||||
# options = [ "rbind" ];
|
ReadOnlyPaths = [ "/var/export" ];
|
||||||
# };
|
ReadWritePaths = [ "/var/export/playground" ];
|
||||||
# sane.persist.sys.plaintext = [
|
};
|
||||||
# { user = "sftpgo"; group = "sftpgo"; path = "/var/lib/sftpgo/export/playground"; }
|
|
||||||
# ];
|
|
||||||
# sane.fs."/var/lib/sftpgo/export/playground/README.md" = {
|
|
||||||
# wantedBy = [ "sftpgo.service" ];
|
|
||||||
# file.text = ''
|
|
||||||
# this directory is intentionally read+write by anyone.
|
|
||||||
# there are no rules, except a server-level quota:
|
|
||||||
# - share files
|
|
||||||
# - write poetry
|
|
||||||
# - be a friendly troll
|
|
||||||
# '';
|
|
||||||
# };
|
|
||||||
}
|
}
|
||||||
|
@@ -111,6 +111,12 @@ lib.mkMerge [
|
|||||||
fsType = "nfs";
|
fsType = "nfs";
|
||||||
options = fsOpts.nfs ++ fsOpts.auto ++ fsOpts.wg;
|
options = fsOpts.nfs ++ fsOpts.auto ++ fsOpts.wg;
|
||||||
};
|
};
|
||||||
|
fileSystems."/mnt/servo-nfs/playground" = {
|
||||||
|
device = "servo-hn:/playground";
|
||||||
|
noCheck = true;
|
||||||
|
fsType = "nfs";
|
||||||
|
options = fsOpts.nfs ++ fsOpts.auto ++ fsOpts.wg;
|
||||||
|
};
|
||||||
# fileSystems."/mnt/servo-media-nfs" = {
|
# fileSystems."/mnt/servo-media-nfs" = {
|
||||||
# device = "servo-hn:/media";
|
# device = "servo-hn:/media";
|
||||||
# noCheck = true;
|
# noCheck = true;
|
||||||
|
@@ -44,6 +44,8 @@
|
|||||||
sane.ids.sftpgo.gid = 2410;
|
sane.ids.sftpgo.gid = 2410;
|
||||||
sane.ids.trust-dns.uid = 2411;
|
sane.ids.trust-dns.uid = 2411;
|
||||||
sane.ids.trust-dns.gid = 2411;
|
sane.ids.trust-dns.gid = 2411;
|
||||||
|
sane.ids.export.gid = 2412;
|
||||||
|
sane.ids.nfsuser.uid = 2413;
|
||||||
|
|
||||||
sane.ids.colin.uid = 1000;
|
sane.ids.colin.uid = 1000;
|
||||||
sane.ids.guest.uid = 1100;
|
sane.ids.guest.uid = 1100;
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
./fractal.nix
|
./fractal.nix
|
||||||
./fwupd.nix
|
./fwupd.nix
|
||||||
./g4music.nix
|
./g4music.nix
|
||||||
|
./gajim.nix
|
||||||
./git.nix
|
./git.nix
|
||||||
./gnome-feeds.nix
|
./gnome-feeds.nix
|
||||||
./gnome-keyring.nix
|
./gnome-keyring.nix
|
||||||
|
13
hosts/common/programs/gajim.nix
Normal file
13
hosts/common/programs/gajim.nix
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
sane.programs.gajim = {
|
||||||
|
persist.private = [
|
||||||
|
# avatars, thumbnails...
|
||||||
|
".cache/gajim"
|
||||||
|
# sqlite database labeled "settings". definitely includes UI theming
|
||||||
|
".config/gajim"
|
||||||
|
# omemo keys, downloads, logs
|
||||||
|
".local/share/gajim"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
@@ -28,21 +28,26 @@
|
|||||||
{ config, lib, sane-lib, ... }:
|
{ config, lib, sane-lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (lib.strings) hasSuffix removeSuffix;
|
|
||||||
secretsForHost = host: let
|
secretsForHost = host: let
|
||||||
extraAttrsForPath = path: lib.optionalAttrs (sane-lib.path.isChild "guest" path && builtins.hasAttr "guest" config.users.users) {
|
extraAttrsForPath = path: lib.optionalAttrs (sane-lib.path.isChild "guest" path && builtins.hasAttr "guest" config.users.users) {
|
||||||
owner = "guest";
|
owner = "guest";
|
||||||
};
|
};
|
||||||
|
secretsInSrc = (
|
||||||
|
if builtins.pathExists ../../secrets/${host} then
|
||||||
|
sane-lib.enumerateFilePaths ../../secrets/${host}
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
);
|
||||||
in sane-lib.joinAttrsets (
|
in sane-lib.joinAttrsets (
|
||||||
map
|
map
|
||||||
(path: lib.optionalAttrs (hasSuffix ".bin" path) (sane-lib.nameValueToAttrs {
|
(path: lib.optionalAttrs (lib.hasSuffix ".bin" path) (sane-lib.nameValueToAttrs {
|
||||||
name = removeSuffix ".bin" path;
|
name = lib.removeSuffix ".bin" path;
|
||||||
value = {
|
value = {
|
||||||
sopsFile = ../../secrets/${host}/${path};
|
sopsFile = ../../secrets/${host}/${path};
|
||||||
format = "binary";
|
format = "binary";
|
||||||
} // (extraAttrsForPath path);
|
} // (extraAttrsForPath path);
|
||||||
}))
|
}))
|
||||||
(sane-lib.enumerateFilePaths ../../secrets/${host})
|
secretsInSrc
|
||||||
);
|
);
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
group = "users";
|
group = "users";
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
"dialout" # required for modem access (moby)
|
"dialout" # required for modem access (moby)
|
||||||
|
"export" # to read filesystem exports (servo)
|
||||||
"feedbackd"
|
"feedbackd"
|
||||||
"input" # for /dev/input/<xyz>: sxmo
|
"input" # for /dev/input/<xyz>: sxmo
|
||||||
"networkmanager"
|
"networkmanager"
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./gnome.nix
|
./gnome.nix
|
||||||
|
./greetd.nix
|
||||||
./gtk.nix
|
./gtk.nix
|
||||||
./phosh.nix
|
./phosh.nix
|
||||||
./sway
|
./sway
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
# "celluloid" # mpv frontend
|
# "celluloid" # mpv frontend
|
||||||
"chatty" # matrix/xmpp/irc client
|
"chatty" # matrix/xmpp/irc client
|
||||||
"cozy" # audiobook player
|
"cozy" # audiobook player
|
||||||
|
"dino" # XMPP client
|
||||||
# "emote"
|
# "emote"
|
||||||
"epiphany" # gnome's web browser
|
"epiphany" # gnome's web browser
|
||||||
"evince" # works on phosh
|
"evince" # works on phosh
|
||||||
@@ -68,11 +70,10 @@
|
|||||||
"brave" # for the integrated wallet -- as a backup
|
"brave" # for the integrated wallet -- as a backup
|
||||||
"cantata" # music player (mpd frontend)
|
"cantata" # music player (mpd frontend)
|
||||||
# "chromium" # chromium takes hours to build. brave is chromium-based, distributed in binary form, so prefer it.
|
# "chromium" # chromium takes hours to build. brave is chromium-based, distributed in binary form, so prefer it.
|
||||||
"dino" # XMPP client
|
|
||||||
"electrum"
|
"electrum"
|
||||||
"element-desktop"
|
"element-desktop"
|
||||||
# "font-manager" #< depends on webkitgtk4_0 (expensive to build)
|
# "font-manager" #< depends on webkitgtk4_0 (expensive to build)
|
||||||
# "gajim" # XMPP client
|
"gajim" # XMPP client. cross build tries to import host gobject-introspection types (2023/09/01)
|
||||||
"gimp" # broken on phosh
|
"gimp" # broken on phosh
|
||||||
"gnome.dconf-editor"
|
"gnome.dconf-editor"
|
||||||
# "gnome.file-roller"
|
# "gnome.file-roller"
|
||||||
|
128
hosts/modules/gui/greetd.nix
Normal file
128
hosts/modules/gui/greetd.nix
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
# greetd source/docs:
|
||||||
|
# - <https://git.sr.ht/~kennylevinsen/greetd>
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
systemd-cat = "${pkgs.systemd}/bin/systemd-cat";
|
||||||
|
runWithLogger = identifier: cmd: pkgs.writeShellScriptBin identifier ''
|
||||||
|
echo "launching ${identifier}..." | ${systemd-cat} --identifier=${identifier}
|
||||||
|
${cmd} 2>&1 | ${systemd-cat} --identifier=${identifier}
|
||||||
|
'';
|
||||||
|
cfg = config.sane.gui.greetd;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = with lib; {
|
||||||
|
sane.gui.greetd.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
sane.gui.greetd.session.command = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
name to use for the default session in syslog.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
sane.gui.greetd.session.name = mkOption {
|
||||||
|
default = "greetd-session";
|
||||||
|
type = types.str;
|
||||||
|
description = "name of session to use in logger";
|
||||||
|
};
|
||||||
|
sane.gui.greetd.session.user = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
# helpers for common things to layer on top of greetd
|
||||||
|
sane.gui.greetd.sway.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
use sway as a wayland compositor in which to host a graphical greeter like gtkgreet, phog, etc.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
sane.gui.greetd.sway.greeterCmd = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
command for sway to `exec` that provides the actual graphical greeter.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
sane.gui.greetd.sway.gtkgreet.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
have sway launch gtkgreet instead of directly presenting a desktop.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
sane.gui.greetd.sway.gtkgreet.session.command = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
command for gtkgreet to execute on successful authentication.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
sane.gui.greetd.sway.gtkgreet.session.name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
name to use for the default session in syslog and in the gtkgreet menu.
|
||||||
|
note that this `sessionName` will become a binary on the user's PATH.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
sane.gui.greetd.sway.gtkgreet.session.user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "colin";
|
||||||
|
description = ''
|
||||||
|
name of user which one expects to login as.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||||
|
(lib.mkIf cfg.sway.enable {
|
||||||
|
sane.gui.greetd.session = if cfg.sway.greeterCmd != null then {
|
||||||
|
name = "sway-as-greeter";
|
||||||
|
command = let
|
||||||
|
swayAsGreeterConfig = pkgs.writeText "sway-as-greeter-config" ''
|
||||||
|
exec ${cfg.sway.greeterCmd}
|
||||||
|
'';
|
||||||
|
in "${pkgs.sway}/bin/sway --debug --config ${swayAsGreeterConfig}";
|
||||||
|
} else {
|
||||||
|
name = "sway";
|
||||||
|
user = lib.mkDefault "colin";
|
||||||
|
command = "${pkgs.sway}/bin/sway --debug";
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(lib.mkIf cfg.sway.gtkgreet.enable (
|
||||||
|
let
|
||||||
|
inherit (cfg.sway.gtkgreet) session;
|
||||||
|
sessionProvider = runWithLogger session.name session.command;
|
||||||
|
in {
|
||||||
|
# gtkgreet shows the --command argument in the UI
|
||||||
|
# - so we want it to look nice (not a /nix/store/... path)
|
||||||
|
# - to do that we put it in the user's PATH.
|
||||||
|
sane.gui.greetd.sway.greeterCmd = "${pkgs.greetd.gtkgreet}/bin/gtkgreet --layer-shell --command ${session.name}";
|
||||||
|
users.users.${session.user}.packages = [ sessionProvider ];
|
||||||
|
}
|
||||||
|
))
|
||||||
|
|
||||||
|
{
|
||||||
|
services.greetd = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# i could have gtkgreet launch the session directly: but stdout/stderr gets dropped
|
||||||
|
# settings.default_session.command = cfg.session.command;
|
||||||
|
|
||||||
|
# wrapper to launch with stdout/stderr redirected to system journal.
|
||||||
|
settings.default_session.command = let
|
||||||
|
launchWithLogger = runWithLogger cfg.session.name cfg.session.command;
|
||||||
|
in "${launchWithLogger}/bin/${cfg.session.name}";
|
||||||
|
};
|
||||||
|
|
||||||
|
# persisting fontconfig & mesa_shader_cache improves start time by ~5x
|
||||||
|
users.users.greeter.home = "/var/lib/greeter";
|
||||||
|
sane.persist.sys.plaintext = [
|
||||||
|
{ user = "greeter"; group = "greeter"; path = "/var/lib/greeter/.cache/fontconfig"; }
|
||||||
|
{ user = "greeter"; group = "greeter"; path = "/var/lib/greeter/.cache/mesa_shader_cache"; }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
@@ -1,44 +1,12 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
# docs: https://nixos.wiki/wiki/Sway
|
# docs: https://nixos.wiki/wiki/Sway
|
||||||
with lib;
|
# sway-config docs: `man 5 sway`
|
||||||
let
|
let
|
||||||
cfg = config.sane.gui.sway;
|
cfg = config.sane.gui.sway;
|
||||||
|
|
||||||
# bare sway launcher
|
|
||||||
sway-launcher = pkgs.writeShellScriptBin "sway-launcher" ''
|
|
||||||
${pkgs.sway}/bin/sway --debug > /var/log/sway/sway.log 2>&1
|
|
||||||
'';
|
|
||||||
# start sway and have it construct the gtkgreeter
|
|
||||||
sway-as-greeter = pkgs.writeShellScriptBin "sway-as-greeter" ''
|
|
||||||
${pkgs.sway}/bin/sway --debug --config ${sway-config-into-gtkgreet} > /var/log/sway/sway-as-greeter.log 2>&1
|
|
||||||
'';
|
|
||||||
# (config file for the above)
|
|
||||||
sway-config-into-gtkgreet = pkgs.writeText "greetd-sway-config" ''
|
|
||||||
exec "${gtkgreet-launcher}"
|
|
||||||
'';
|
|
||||||
# gtkgreet which launches a layered sway instance
|
|
||||||
gtkgreet-launcher = pkgs.writeShellScript "gtkgreet-launcher" ''
|
|
||||||
# NB: the "command" field here is run in the user's shell.
|
|
||||||
# so that command must exist on the specific user's path who is logging in. it doesn't need to exist system-wide.
|
|
||||||
${pkgs.greetd.gtkgreet}/bin/gtkgreet --layer-shell --command sway-launcher
|
|
||||||
'';
|
|
||||||
greeter-session = {
|
|
||||||
# greeter session config
|
|
||||||
command = "${sway-as-greeter}/bin/sway-as-greeter";
|
|
||||||
# alternatives:
|
|
||||||
# - TTY: `command = "${pkgs.greetd.greetd}/bin/agreety --cmd ${pkgs.sway}/bin/sway";`
|
|
||||||
# - autologin: `command = "${pkgs.sway}/bin/sway"; user = "colin";`
|
|
||||||
# - Dumb Login (doesn't work)": `command = "${pkgs.greetd.dlm}/bin/dlm";`
|
|
||||||
};
|
|
||||||
greeterless-session = {
|
|
||||||
# no greeter
|
|
||||||
command = "${sway-launcher}/bin/sway-launcher";
|
|
||||||
user = "colin";
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options = {
|
options = with lib; {
|
||||||
sane.gui.sway.enable = mkOption {
|
sane.gui.sway.enable = mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
@@ -51,8 +19,16 @@ in
|
|||||||
default = true;
|
default = true;
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
};
|
};
|
||||||
|
sane.gui.sway.installConfigs = mkOption {
|
||||||
|
default = true;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
populate ~/.config/sway/config & co with defaults provided by this module.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
config = mkMerge [
|
};
|
||||||
|
|
||||||
|
config = lib.mkMerge [
|
||||||
{
|
{
|
||||||
sane.programs.swayApps = {
|
sane.programs.swayApps = {
|
||||||
package = null;
|
package = null;
|
||||||
@@ -75,11 +51,9 @@ in
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
(mkIf cfg.enable {
|
(lib.mkIf cfg.enable {
|
||||||
sane.programs.fontconfig.enableFor.system = true;
|
sane.programs.fontconfig.enableFor.system = true;
|
||||||
sane.programs.swayApps.enableFor.user.colin = true;
|
sane.programs.swayApps.enableFor.user.colin = true;
|
||||||
# we need the greeter's command to be on our PATH
|
|
||||||
users.users.colin.packages = [ sway-launcher ];
|
|
||||||
|
|
||||||
sane.gui.gtk.enable = lib.mkDefault true;
|
sane.gui.gtk.enable = lib.mkDefault true;
|
||||||
# sane.gui.gtk.gtk-theme = lib.mkDefault "Fluent-Light-compact";
|
# sane.gui.gtk.gtk-theme = lib.mkDefault "Fluent-Light-compact";
|
||||||
@@ -88,13 +62,12 @@ in
|
|||||||
# swap in these lines to use SDDM instead of `services.greetd`.
|
# swap in these lines to use SDDM instead of `services.greetd`.
|
||||||
# services.xserver.displayManager.sddm.enable = true;
|
# services.xserver.displayManager.sddm.enable = true;
|
||||||
# services.xserver.enable = true;
|
# services.xserver.enable = true;
|
||||||
services.greetd = {
|
sane.gui.greetd.enable = true;
|
||||||
# greetd source/docs:
|
sane.gui.greetd.sway.enable = true; # have greetd launch a sway compositor in which we host a greeter
|
||||||
# - <https://git.sr.ht/~kennylevinsen/greetd>
|
sane.gui.greetd.sway.gtkgreet = lib.mkIf cfg.useGreeter {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
session.name = "sway-on-gtkgreet";
|
||||||
default_session = if cfg.useGreeter then greeter-session else greeterless-session;
|
session.command = "${pkgs.sway}/bin/sway --debug";
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# unlike other DEs, sway configures no audio stack
|
# unlike other DEs, sway configures no audio stack
|
||||||
@@ -103,6 +76,7 @@ in
|
|||||||
enable = true;
|
enable = true;
|
||||||
alsa.enable = true;
|
alsa.enable = true;
|
||||||
alsa.support32Bit = true; # ??
|
alsa.support32Bit = true; # ??
|
||||||
|
# emulate pulseaudio for legacy apps (e.g. sxmo-utils)
|
||||||
pulse.enable = true;
|
pulse.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -124,11 +98,6 @@ in
|
|||||||
# a system service can't depend on a user service, so just launch it at graphical-session
|
# a system service can't depend on a user service, so just launch it at graphical-session
|
||||||
systemd.user.services."pipewire".wantedBy = [ "graphical-session.target" ];
|
systemd.user.services."pipewire".wantedBy = [ "graphical-session.target" ];
|
||||||
|
|
||||||
sane.fs."/var/log/sway" = {
|
|
||||||
dir.acl.mode = "0777";
|
|
||||||
wantedBeforeBy = [ "greetd.service" "display-manager.service" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.sway = {
|
programs.sway = {
|
||||||
# provides xdg-desktop-portal-wlr, which exposes on dbus:
|
# provides xdg-desktop-portal-wlr, which exposes on dbus:
|
||||||
# - org.freedesktop.impl.portal.ScreenCast
|
# - org.freedesktop.impl.portal.ScreenCast
|
||||||
@@ -162,17 +131,19 @@ in
|
|||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
sane.user.fs.".config/sway/config".symlink.text =
|
sane.user.fs = lib.mkIf cfg.installConfigs {
|
||||||
|
".config/sway/config".symlink.text =
|
||||||
import ./sway-config.nix { inherit pkgs; };
|
import ./sway-config.nix { inherit pkgs; };
|
||||||
|
|
||||||
sane.user.fs.".config/waybar/config".symlink.target =
|
".config/waybar/config".symlink.target =
|
||||||
let
|
let
|
||||||
waybar-config = import ./waybar-config.nix { inherit pkgs; };
|
waybar-config = import ./waybar-config.nix { inherit pkgs; };
|
||||||
in
|
in
|
||||||
(pkgs.formats.json {}).generate "waybar-config.json" waybar-config;
|
(pkgs.formats.json {}).generate "waybar-config.json" waybar-config;
|
||||||
|
|
||||||
sane.user.fs.".config/waybar/style.css".symlink.text =
|
".config/waybar/style.css".symlink.text =
|
||||||
builtins.readFile ./waybar-style.css;
|
builtins.readFile ./waybar-style.css;
|
||||||
|
};
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,8 @@ let
|
|||||||
# mod = "Mod1"; # Alt
|
# mod = "Mod1"; # Alt
|
||||||
mod = "Mod4"; # Super
|
mod = "Mod4"; # Super
|
||||||
in ''
|
in ''
|
||||||
|
# xwayland disable
|
||||||
|
|
||||||
### default font
|
### default font
|
||||||
font pango:monospace 8
|
font pango:monospace 8
|
||||||
|
|
||||||
@@ -32,13 +34,12 @@ in ''
|
|||||||
default_floating_border pixel 2
|
default_floating_border pixel 2
|
||||||
hide_edge_borders smart
|
hide_edge_borders smart
|
||||||
|
|
||||||
### defaults
|
#### focus_wrapping: behavior when trying to focus past the edge of a container
|
||||||
|
#### no => preserve last focus. helpful mostly when `focus_follows_mouse yes`
|
||||||
focus_wrapping no
|
focus_wrapping no
|
||||||
focus_follows_mouse yes
|
focus_follows_mouse yes
|
||||||
focus_on_window_activation smart
|
#### workspace_layout default => workspaces use splits by default (as opposed to e.g. tabbed)
|
||||||
mouse_warping output
|
|
||||||
workspace_layout default
|
workspace_layout default
|
||||||
workspace_auto_back_and_forth no
|
|
||||||
|
|
||||||
### default colors (#border #background #text #indicator #childBorder)
|
### default colors (#border #background #text #indicator #childBorder)
|
||||||
client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577
|
client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577
|
||||||
|
@@ -45,6 +45,10 @@
|
|||||||
# - gestures: lisgd
|
# - gestures: lisgd
|
||||||
# - on-screen keyboard: wvkbd (if wayland), svkbd (if X)
|
# - on-screen keyboard: wvkbd (if wayland), svkbd (if X)
|
||||||
#
|
#
|
||||||
|
# TODO:
|
||||||
|
# - don't duplicate so much of hosts/modules/gui/sway
|
||||||
|
# - might help if i bring more under my control, and launch sxmo via sway instead of the opposite
|
||||||
|
# - theme `mako` notifications
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
@@ -73,10 +77,10 @@ in
|
|||||||
sane.gui.sxmo.greeter = mkOption {
|
sane.gui.sxmo.greeter = mkOption {
|
||||||
type = types.enum [
|
type = types.enum [
|
||||||
"greetd-phog"
|
"greetd-phog"
|
||||||
|
"greetd-sway-gtkgreet"
|
||||||
"greetd-sway-phog"
|
"greetd-sway-phog"
|
||||||
"greetd-sxmo"
|
"greetd-sxmo"
|
||||||
"lightdm-mobile"
|
"lightdm-mobile"
|
||||||
"sway-gtkgreet"
|
|
||||||
];
|
];
|
||||||
# default = "lightdm-mobile";
|
# default = "lightdm-mobile";
|
||||||
default = "greetd-sway-phog";
|
default = "greetd-sway-phog";
|
||||||
@@ -88,9 +92,7 @@ in
|
|||||||
"greetd-sxmo" => launch sxmo directly from greetd, no auth.
|
"greetd-sxmo" => launch sxmo directly from greetd, no auth.
|
||||||
this means no keychain unlocked or encrypted home mounted.
|
this means no keychain unlocked or encrypted home mounted.
|
||||||
"lightdm-mobile" => keypad style greeter. can only enter digits 0-9 as password.
|
"lightdm-mobile" => keypad style greeter. can only enter digits 0-9 as password.
|
||||||
"sway-gtkgreet" => layered sway greeter. behaves as if you booted to swaylock.
|
"greetd-sway-gtkgreet" => layered sway greeter. keyboard-only user/pass input; impractical on mobile.
|
||||||
this isn't practically usable on mobile because of keyboard input.
|
|
||||||
also, it takes literally 6 minutes to appear
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
sane.gui.sxmo.package = mkOption {
|
sane.gui.sxmo.package = mkOption {
|
||||||
@@ -138,6 +140,7 @@ in
|
|||||||
SXMO_BAR_SHOW_BAT_PER = mkSettingsOpt "1" "show battery percentage in statusbar";
|
SXMO_BAR_SHOW_BAT_PER = mkSettingsOpt "1" "show battery percentage in statusbar";
|
||||||
SXMO_DISABLE_CONFIGVERSION_CHECK = mkSettingsOpt "1" "allow omitting the configversion line from user-provided sxmo dotfiles";
|
SXMO_DISABLE_CONFIGVERSION_CHECK = mkSettingsOpt "1" "allow omitting the configversion line from user-provided sxmo dotfiles";
|
||||||
SXMO_UNLOCK_IDLE_TIME = mkSettingsOpt "300" "how many seconds of inactivity before locking the screen"; # lock -> screenoff happens 8s later, not configurable
|
SXMO_UNLOCK_IDLE_TIME = mkSettingsOpt "300" "how many seconds of inactivity before locking the screen"; # lock -> screenoff happens 8s later, not configurable
|
||||||
|
# SXMO_WM = mkSettingsOpt "sway" "sway or dwm. ordinarily initialized by sxmo_{x,w}init.sh";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
default = {};
|
default = {};
|
||||||
@@ -160,8 +163,11 @@ in
|
|||||||
package = null;
|
package = null;
|
||||||
suggestedPrograms = [
|
suggestedPrograms = [
|
||||||
"guiApps"
|
"guiApps"
|
||||||
|
"mako" # notification daemon
|
||||||
"sfeed" # want this here so that the user's ~/.sfeed/sfeedrc gets created
|
"sfeed" # want this here so that the user's ~/.sfeed/sfeedrc gets created
|
||||||
"superd" # make superctl (used by sxmo) be on PATH
|
"superd" # make superctl (used by sxmo) be on PATH
|
||||||
|
"sway-contrib.grimshot"
|
||||||
|
"wdisplays" # like xrandr
|
||||||
];
|
];
|
||||||
|
|
||||||
persist.cryptClearOnBoot = [
|
persist.cryptClearOnBoot = [
|
||||||
@@ -181,21 +187,19 @@ in
|
|||||||
|
|
||||||
(lib.mkIf cfg.enable (lib.mkMerge [
|
(lib.mkIf cfg.enable (lib.mkMerge [
|
||||||
{
|
{
|
||||||
|
sane.gui.sway = {
|
||||||
|
enable = true;
|
||||||
|
# we manage these ourselves (TODO: merge these into sway config as well)
|
||||||
|
useGreeter = false;
|
||||||
|
installConfigs = false;
|
||||||
|
};
|
||||||
|
|
||||||
sane.programs.sxmoApps.enableFor.user.colin = true;
|
sane.programs.sxmoApps.enableFor.user.colin = true;
|
||||||
sane.gui.gtk.enable = lib.mkDefault true;
|
|
||||||
|
|
||||||
# sxmo internally uses doas instead of sudo
|
# sxmo internally uses doas instead of sudo
|
||||||
security.doas.enable = true;
|
security.doas.enable = true;
|
||||||
security.doas.wheelNeedsPassword = false;
|
security.doas.wheelNeedsPassword = false;
|
||||||
|
|
||||||
# TODO: move this further to the host-specific config?
|
|
||||||
networking.useDHCP = false;
|
|
||||||
networking.networkmanager.enable = true;
|
|
||||||
networking.wireless.enable = lib.mkForce false;
|
|
||||||
|
|
||||||
hardware.bluetooth.enable = true;
|
|
||||||
services.blueman.enable = true;
|
|
||||||
|
|
||||||
hardware.opengl.enable = true;
|
hardware.opengl.enable = true;
|
||||||
|
|
||||||
# TODO: nerdfonts is 4GB. it accepts an option to ship only some fonts: probably want to use that.
|
# TODO: nerdfonts is 4GB. it accepts an option to ship only some fonts: probably want to use that.
|
||||||
@@ -204,21 +208,11 @@ in
|
|||||||
# lightdm-mobile-greeter: "The name org.a11y.Bus was not provided by any .service files"
|
# lightdm-mobile-greeter: "The name org.a11y.Bus was not provided by any .service files"
|
||||||
services.gnome.at-spi2-core.enable = true;
|
services.gnome.at-spi2-core.enable = true;
|
||||||
|
|
||||||
# sxmo has first-class support only for pulseaudio and alsa -- not pipewire.
|
|
||||||
# however, pipewire can emulate pulseaudio support via `services.pipewire.pulse.enable = true`
|
|
||||||
# after which the stock pulseaudio binaries magically work
|
|
||||||
# administer with pw-cli, pw-mon, pw-top commands
|
|
||||||
services.pipewire = {
|
|
||||||
enable = true;
|
|
||||||
alsa.enable = true;
|
|
||||||
alsa.support32Bit = true; # ??
|
|
||||||
pulse.enable = true;
|
|
||||||
};
|
|
||||||
systemd.user.services."pipewire".wantedBy = [ "graphical-session.target" ];
|
|
||||||
|
|
||||||
# TODO: could use `displayManager.sessionPackages`?
|
# TODO: could use `displayManager.sessionPackages`?
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
cfg.package
|
cfg.package
|
||||||
|
pkgs.bonsai # sway (not sxmo) needs to exec `bonsaictl` by name (sxmo_swayinitconf.sh)
|
||||||
] ++ lib.optionals (cfg.terminal != null) [ pkgs."${cfg.terminal}" ]
|
] ++ lib.optionals (cfg.terminal != null) [ pkgs."${cfg.terminal}" ]
|
||||||
++ lib.optionals (cfg.keyboard != null) [ pkgs."${cfg.keyboard}" ];
|
++ lib.optionals (cfg.keyboard != null) [ pkgs."${cfg.keyboard}" ];
|
||||||
|
|
||||||
@@ -232,13 +226,20 @@ in
|
|||||||
cfg.settings
|
cfg.settings
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# sxmo puts in /share/sxmo:
|
||||||
|
# - profile.d/sxmo_init.sh
|
||||||
|
# - appcfg/
|
||||||
|
# - default_hooks/
|
||||||
|
# - and more
|
||||||
|
# environment.pathsToLink = [ "/share/sxmo" ];
|
||||||
|
|
||||||
systemd.services."sxmo-set-permissions" = {
|
systemd.services."sxmo-set-permissions" = {
|
||||||
description = "configure specific /sys and /dev nodes to be writable by sxmo scripts";
|
description = "configure specific /sys and /dev nodes to be writable by sxmo scripts";
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
ExecStart = "${cfg.package}/bin/sxmo_setpermissions.sh";
|
ExecStart = "${cfg.package}/bin/sxmo_setpermissions.sh";
|
||||||
};
|
};
|
||||||
wantedBy = [ "display-manager.service" ];
|
wantedBy = [ "multi-user.service" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
# if superd fails to start a service within 100ms, it'll try to start again
|
# if superd fails to start a service within 100ms, it'll try to start again
|
||||||
@@ -277,9 +278,40 @@ in
|
|||||||
in
|
in
|
||||||
lib.generators.toKeyValue { inherit mkKeyValue; } cfg.settings;
|
lib.generators.toKeyValue { inherit mkKeyValue; } cfg.settings;
|
||||||
|
|
||||||
sane.user.fs.".config/sxmo/sway".symlink.target = pkgs.substituteAll {
|
sane.user.fs.".config/sway/config".symlink.target = pkgs.substituteAll {
|
||||||
src = ./sway-config;
|
src = ./sway-config;
|
||||||
waybar = "${pkgs.waybar}/bin/waybar";
|
waybar = "${pkgs.waybar}/bin/waybar";
|
||||||
|
bemenu_run = "${pkgs.bemenu}/bin/bemenu-run";
|
||||||
|
term = "${pkgs.xdg-terminal-exec}/bin/xdg-terminal-exec";
|
||||||
|
sxmo_init = pkgs.writeShellScript "sxmo_init.sh" ''
|
||||||
|
# perform the same behavior as sxmo_{x,w}init.sh -- but without actually launching wayland/X11
|
||||||
|
# this amounts to:
|
||||||
|
# - setting env vars (e.g. getting the hooks onto PATH)
|
||||||
|
# - placing default configs in ~ for sxmo-launched services (sxmo_migrate.sh)
|
||||||
|
# - launching sxmo_hook_start.sh
|
||||||
|
source ${cfg.package}/etc/profile.d/sxmo_init.sh
|
||||||
|
# XXX: upstream sources `profile` later (after sxmo_migrate)
|
||||||
|
# but _sxmo_load_environments uses `SXMO_DEVICE_NAME`,
|
||||||
|
# and i ship that via the profile, so order it such
|
||||||
|
source "$XDG_CONFIG_HOME/sxmo/profile"
|
||||||
|
_sxmo_load_environments
|
||||||
|
_sxmo_prepare_dirs
|
||||||
|
sxmo_migrate.sh sync
|
||||||
|
|
||||||
|
# kill anything leftover from the previous sxmo run. this way we can (try to) be reentrant
|
||||||
|
echo "sxmo_init: killing stale daemons (if active)"
|
||||||
|
sxmo_daemons.sh stop all
|
||||||
|
pkill bemenu
|
||||||
|
pkill wvkbd
|
||||||
|
pkill superd
|
||||||
|
|
||||||
|
# configure vol/power-button input mapping (upstream SXMO has this in sway config)
|
||||||
|
sxmo_swayinitconf.sh
|
||||||
|
|
||||||
|
echo "sxmo_init: invoking sxmo_hook_start.sh with:"
|
||||||
|
echo "PATH: $PATH"
|
||||||
|
sxmo_hook_start.sh
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
sane.user.fs.".config/waybar/config".symlink.target =
|
sane.user.fs.".config/waybar/config".symlink.target =
|
||||||
@@ -334,78 +366,44 @@ in
|
|||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
(lib.mkIf (cfg.greeter == "sway-gtkgreet") {
|
(lib.mkIf (cfg.greeter == "greetd-sway-gtkgreet") {
|
||||||
services.greetd = {
|
sane.gui.greetd = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# borrowed from gui/sway
|
sway.enable = true;
|
||||||
settings.default_session.command =
|
sway.gtkgreet.enable = true;
|
||||||
let
|
sway.gtkgreet.session.name = "sxmo-on-gtkgreet";
|
||||||
# start sway and have it construct the gtkgreeter
|
# sway.gtkgreet.session.command = "${cfg.package}/bin/sxmo_winit.sh";
|
||||||
sway-as-greeter = runWithLogger "sway-as-greeter" "${pkgs.sway}/bin/sway --debug --config ${sway-config-into-gtkgreet}";
|
sway.gtkgreet.session.command = "${pkgs.sway}/bin/sway --debug";
|
||||||
# (config file for the above)
|
|
||||||
sway-config-into-gtkgreet = pkgs.writeText "greetd-sway-config" ''
|
|
||||||
exec "${gtkgreet-launcher}"
|
|
||||||
'';
|
|
||||||
# gtkgreet which launches a layered sway instance
|
|
||||||
gtkgreet-launcher = pkgs.writeShellScript "gtkgreet-launcher" ''
|
|
||||||
# NB: the "command" field here is run in the user's shell.
|
|
||||||
# so that command must exist on the specific user's path who is logging in. it doesn't need to exist system-wide.
|
|
||||||
${pkgs.greetd.gtkgreet}/bin/gtkgreet --layer-shell --command sxmo_winit.sh
|
|
||||||
'';
|
|
||||||
in "${sway-as-greeter}";
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
(lib.mkIf (cfg.greeter == "greetd-sway-phog") {
|
(lib.mkIf (cfg.greeter == "greetd-sway-phog") {
|
||||||
services.greetd = {
|
sane.gui.greetd = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# borrowed from gui/sway
|
sway.enable = true;
|
||||||
settings.default_session.command =
|
sway.greeterCmd = "${pkgs.phog}/libexec/phog";
|
||||||
let
|
|
||||||
# start sway and have it construct the greeter
|
|
||||||
sway-as-greeter = runWithLogger "sway-as-greeter" "${pkgs.sway}/bin/sway --debug --config ${sway-config-into-phog}";
|
|
||||||
# (config file for the above)
|
|
||||||
sway-config-into-phog = pkgs.writeText "greetd-sway-config" ''
|
|
||||||
exec "${pkgs.phog}/libexec/phog"
|
|
||||||
'';
|
|
||||||
in "${sway-as-greeter}";
|
|
||||||
};
|
};
|
||||||
# phog locates sxmo_winit.sh via <env>/share/wayland-sessions
|
# phog locates sxmo_winit.sh via <env>/share/wayland-sessions
|
||||||
environment.pathsToLink = [ "/share/wayland-sessions" ];
|
environment.pathsToLink = [ "/share/wayland-sessions" ];
|
||||||
|
|
||||||
# persisting fontconfig & mesa_shader_cache improves start time from like 6 minutes to 1 minute
|
|
||||||
# TODO: this should apply to any greetd implementation
|
|
||||||
users.users.greeter.home = "/var/lib/greeter";
|
|
||||||
sane.persist.sys.plaintext = [
|
|
||||||
{ user = "greeter"; group = "greeter"; path = "/var/lib/greeter/.cache/fontconfig"; }
|
|
||||||
{ user = "greeter"; group = "greeter"; path = "/var/lib/greeter/.cache/mesa_shader_cache"; }
|
|
||||||
];
|
|
||||||
})
|
})
|
||||||
|
|
||||||
(lib.mkIf (cfg.greeter == "greetd-phog") {
|
(lib.mkIf (cfg.greeter == "greetd-phog") {
|
||||||
services.greetd = {
|
sane.gui.greetd = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
session.name = "phog";
|
||||||
# launch directly: but stdout/stderr gets dropped
|
session.command = "${pkgs.phog}/bin/phog";
|
||||||
# settings.default_session.command = "${pkgs.phog}/bin/phog";
|
|
||||||
|
|
||||||
# wrapper to launch phog and redirect logs to system journal.
|
|
||||||
settings.default_session.command = let
|
|
||||||
launch-phog = runWithLogger "phog" "${pkgs.phog}/bin/phog";
|
|
||||||
in "${launch-phog}";
|
|
||||||
};
|
};
|
||||||
|
# phog locates sxmo_winit.sh via <env>/share/wayland-sessions
|
||||||
environment.pathsToLink = [ "/share/wayland-sessions" ];
|
environment.pathsToLink = [ "/share/wayland-sessions" ];
|
||||||
})
|
})
|
||||||
|
|
||||||
(lib.mkIf (cfg.greeter == "greetd-sxmo") {
|
(lib.mkIf (cfg.greeter == "greetd-sxmo") {
|
||||||
services.greetd = {
|
sane.gui.greetd = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings.default_session = {
|
session.name = "sxmo";
|
||||||
command = let
|
# session.command = "${cfg.package}/bin/sxmo_winit.sh";
|
||||||
launch-sxmo = runWithLogger "sxmo" "${cfg.package}/bin/sxmo_winit.sh";
|
session.command = "${pkgs.sway}/bin/sway --debug";
|
||||||
in "${launch-sxmo}";
|
session.user = "colin";
|
||||||
user = "colin";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -14,11 +14,13 @@ set $down j
|
|||||||
set $up k
|
set $up k
|
||||||
set $right l
|
set $right l
|
||||||
# Your preferred terminal emulator
|
# Your preferred terminal emulator
|
||||||
set $term sxmo_terminal.sh
|
# set $term sxmo_terminal.sh
|
||||||
|
set $term @term@
|
||||||
# Your preferred application launcher
|
# Your preferred application launcher
|
||||||
# Note: pass the final command to swaymsg so that the resulting window can be opened
|
# Note: pass the final command to swaymsg so that the resulting window can be opened
|
||||||
# on the original workspace that the command was run on.
|
# on the original workspace that the command was run on.
|
||||||
set $menu bemenu-run
|
# N.B. bemenu-run relies on BEMENU_OPTS being set: without this it won't even be visible.
|
||||||
|
set $menu @bemenu_run@
|
||||||
|
|
||||||
# xwayland enable|disable|force
|
# xwayland enable|disable|force
|
||||||
# - enable: lazily launch xwayland on first client connection
|
# - enable: lazily launch xwayland on first client connection
|
||||||
@@ -29,7 +31,9 @@ xwayland disable
|
|||||||
|
|
||||||
font "Sxmo 10"
|
font "Sxmo 10"
|
||||||
|
|
||||||
exec_always sxmo_swayinitconf.sh
|
# configure vol/power-button input maps
|
||||||
|
# XXX: this references env vars like SXMO_VOLUME_BUTTON => needs to happen after sourcing profile
|
||||||
|
# exec_always sxmo_swayinitconf.sh
|
||||||
|
|
||||||
exec_always dbus-update-activation-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
|
exec_always dbus-update-activation-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
|
||||||
|
|
||||||
@@ -263,4 +267,4 @@ include /etc/sway/config.d/*
|
|||||||
|
|
||||||
exec 'printf %s "$SWAYSOCK" > "$XDG_RUNTIME_DIR"/sxmo.swaysock'
|
exec 'printf %s "$SWAYSOCK" > "$XDG_RUNTIME_DIR"/sxmo.swaysock'
|
||||||
|
|
||||||
exec sxmo_hook_start.sh
|
exec_always @sxmo_init@
|
||||||
|
@@ -514,14 +514,14 @@ in {
|
|||||||
});
|
});
|
||||||
|
|
||||||
# 2023/07/31: upstreaming is blocked on ostree dep
|
# 2023/07/31: upstreaming is blocked on ostree dep
|
||||||
# flatpak = prev.flatpak.overrideAttrs (upstream: {
|
flatpak = prev.flatpak.overrideAttrs (upstream: {
|
||||||
# # fixes "No package 'libxml-2.0' found"
|
# fixes "No package 'libxml-2.0' found"
|
||||||
# buildInputs = upstream.buildInputs ++ [ final.libxml2 ];
|
buildInputs = upstream.buildInputs ++ [ final.libxml2 ];
|
||||||
# configureFlags = upstream.configureFlags ++ [
|
configureFlags = upstream.configureFlags ++ [
|
||||||
# "--enable-selinux-module=no" # fixes "checking for /usr/share/selinux/devel/Makefile... configure: error: cannot check for file existence when cross compiling"
|
"--enable-selinux-module=no" # fixes "checking for /usr/share/selinux/devel/Makefile... configure: error: cannot check for file existence when cross compiling"
|
||||||
# "--disable-gtk-doc" # fixes "You must have gtk-doc >= 1.20 installed to build documentation for Flatpak"
|
"--disable-gtk-doc" # fixes "You must have gtk-doc >= 1.20 installed to build documentation for Flatpak"
|
||||||
# ];
|
];
|
||||||
# });
|
});
|
||||||
|
|
||||||
# future: use `buildRustPackage`?
|
# future: use `buildRustPackage`?
|
||||||
# - find another rust package that uses a `-sys` crate (with a build script)?
|
# - find another rust package that uses a `-sys` crate (with a build script)?
|
||||||
@@ -1313,6 +1313,7 @@ in {
|
|||||||
# fixes "/nix/store/0wk6nr1mryvylf5g5frckjam7g7p9gpi-bash-5.2-p15/bin/bash: line 2: --prefix=ods_manager: command not found"
|
# fixes "/nix/store/0wk6nr1mryvylf5g5frckjam7g7p9gpi-bash-5.2-p15/bin/bash: line 2: --prefix=ods_manager: command not found"
|
||||||
# - dbus-glib should maybe be removed from buildInputs, too? but doing so breaks upstream configure
|
# - dbus-glib should maybe be removed from buildInputs, too? but doing so breaks upstream configure
|
||||||
obex_data_server = addNativeInputs [ final.dbus-glib ] prev.obex_data_server;
|
obex_data_server = addNativeInputs [ final.dbus-glib ] prev.obex_data_server;
|
||||||
|
|
||||||
# openfortivpn = prev.openfortivpn.override {
|
# openfortivpn = prev.openfortivpn.override {
|
||||||
# # fixes "checking for /proc/net/route... configure: error: cannot check for file existence when cross compiling"
|
# # fixes "checking for /proc/net/route... configure: error: cannot check for file existence when cross compiling"
|
||||||
# inherit (emulated) stdenv;
|
# inherit (emulated) stdenv;
|
||||||
@@ -1321,12 +1322,20 @@ in {
|
|||||||
# # fixes "configure: error: Need GPGME_PTHREAD version 1.1.8 or later"
|
# # fixes "configure: error: Need GPGME_PTHREAD version 1.1.8 or later"
|
||||||
# inherit (emulated) stdenv;
|
# inherit (emulated) stdenv;
|
||||||
# };
|
# };
|
||||||
# ostree = prev.ostree.overrideAttrs (upstream: {
|
|
||||||
# # fixes: "configure: error: Need GPGME_PTHREAD version 1.1.8 or later"
|
# 2023/09/02: upstreaming is implemented on servo `wip-ostree` branch
|
||||||
# # new failure mode: "./src/libotutil/ot-gpg-utils.h:22:10: fatal error: gpgme.h: No such file or directory"
|
ostree = prev.ostree.overrideAttrs (upstream: {
|
||||||
# # buildInputs = lib.remove final.gpgme upstream.buildInputs;
|
# fixes: "configure: error: Need GPGME_PTHREAD version 1.1.8 or later"
|
||||||
|
# new failure mode: "./src/libotutil/ot-gpg-utils.h:22:10: fatal error: gpgme.h: No such file or directory"
|
||||||
|
# buildInputs = lib.remove final.gpgme upstream.buildInputs;
|
||||||
# nativeBuildInputs = upstream.nativeBuildInputs ++ [ final.gpgme ];
|
# nativeBuildInputs = upstream.nativeBuildInputs ++ [ final.gpgme ];
|
||||||
# });
|
# buildInputs = lib.remove final.gjs upstream.buildInputs;
|
||||||
|
# configureFlags = lib.remove "--enable-installed-tests" upstream.configureFlags;
|
||||||
|
postPatch = (upstream.postPatch or "") + ''
|
||||||
|
substituteInPlace Makefile-libostree.am \
|
||||||
|
--replace "CC=gcc" "CC=${final.stdenv.cc.targetPrefix}cc"
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
# fixes (meson) "Program 'glib-mkenums mkenums' not found or not executable"
|
# fixes (meson) "Program 'glib-mkenums mkenums' not found or not executable"
|
||||||
# 2023/07/27: upstreaming is blocked on p11-kit, argyllcms, libavif cross compilation
|
# 2023/07/27: upstreaming is blocked on p11-kit, argyllcms, libavif cross compilation
|
||||||
|
Reference in New Issue
Block a user