sway: port to sane.programs API
This commit is contained in:
@@ -28,7 +28,7 @@
|
|||||||
sane.nixcache.substituters.desko = false;
|
sane.nixcache.substituters.desko = false;
|
||||||
sane.nixcache.remote-builders.desko = false;
|
sane.nixcache.remote-builders.desko = false;
|
||||||
|
|
||||||
sane.gui.sway.enable = true;
|
sane.programs.sway.enableFor.user.colin = true;
|
||||||
sane.programs.iphoneUtils.enableFor.user.colin = true;
|
sane.programs.iphoneUtils.enableFor.user.colin = true;
|
||||||
sane.programs.steam.enableFor.user.colin = true;
|
sane.programs.steam.enableFor.user.colin = true;
|
||||||
|
|
||||||
|
@@ -12,10 +12,10 @@
|
|||||||
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;
|
|
||||||
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 ];
|
||||||
|
|
||||||
|
sane.programs.sway.enableFor.user.colin = true;
|
||||||
sane.programs."gnome.geary".config.autostart = true;
|
sane.programs."gnome.geary".config.autostart = true;
|
||||||
sane.programs.signal-desktop.config.autostart = true;
|
sane.programs.signal-desktop.config.autostart = true;
|
||||||
sane.programs.stepmania.enableFor.user.colin = true;
|
sane.programs.stepmania.enableFor.user.colin = true;
|
||||||
|
@@ -85,6 +85,7 @@
|
|||||||
./strings.nix
|
./strings.nix
|
||||||
./sublime-music.nix
|
./sublime-music.nix
|
||||||
./supertuxkart.nix
|
./supertuxkart.nix
|
||||||
|
./sway
|
||||||
./sway-autoscaler
|
./sway-autoscaler
|
||||||
./swaylock.nix
|
./swaylock.nix
|
||||||
./swaynotificationcenter.nix
|
./swaynotificationcenter.nix
|
||||||
|
274
hosts/common/programs/sway/default.nix
Normal file
274
hosts/common/programs/sway/default.nix
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
# docs: https://nixos.wiki/wiki/Sway
|
||||||
|
# sway-config docs: `man 5 sway`
|
||||||
|
let
|
||||||
|
cfg = config.sane.programs.sway;
|
||||||
|
wrapSway = configuredSway: let
|
||||||
|
# `wrapSway` exists to launch sway with our desired debugging facilities.
|
||||||
|
# i.e. redirect output to syslog.
|
||||||
|
systemd-cat = "${lib.getBin pkgs.systemd}/bin/systemd-cat";
|
||||||
|
swayLauncher = pkgs.writeShellScriptBin "sway" ''
|
||||||
|
# sway defaults to auto-generating a unix domain socket named "sway-ipc.$UID.NNNN.sock",
|
||||||
|
# which allows for multiple sway sessions under the same user.
|
||||||
|
# but the unpredictability makes static sandboxing & such difficult, so hardcode it:
|
||||||
|
export SWAYSOCK="$XDG_RUNTIME_DIR/sway-ipc.sock"
|
||||||
|
export XDG_CURRENT_DESKTOP=sway
|
||||||
|
|
||||||
|
echo "launching sway (sway.desktop)..." | ${systemd-cat} --identifier=sway
|
||||||
|
exec ${configuredSway}/bin/sway 2>&1 | ${systemd-cat} --identifier=sway
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
pkgs.symlinkJoin {
|
||||||
|
inherit (configuredSway) meta version;
|
||||||
|
name = "sway-wrapped";
|
||||||
|
paths = [
|
||||||
|
swayLauncher
|
||||||
|
configuredSway
|
||||||
|
];
|
||||||
|
};
|
||||||
|
swayPackage = wrapSway (pkgs.sway-unwrapped.overrideAttrs (_: {
|
||||||
|
# isNixOS = true; #< doesn't matter
|
||||||
|
# TODO: something else is dragging a xwayland-enabled wlroots into the environment,
|
||||||
|
# making this actually kinda wasteful.
|
||||||
|
enableXWayland = cfg.config.xwayland;
|
||||||
|
}));
|
||||||
|
in
|
||||||
|
{
|
||||||
|
sane.programs.sway = {
|
||||||
|
configOption = with lib; mkOption {
|
||||||
|
default = {};
|
||||||
|
type = types.submodule {
|
||||||
|
options = {
|
||||||
|
extra_lines = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
description = ''
|
||||||
|
extra lines to append to the sway config
|
||||||
|
'';
|
||||||
|
default = ''
|
||||||
|
# XXX: sway needs exclusive control of XF86Audio{Raise,Lower}Volume, so assign this from a block that it can override.
|
||||||
|
# TODO: factor the bindings out into proper options and be less hacky?
|
||||||
|
bindsym --locked XF86AudioRaiseVolume exec $volume_up
|
||||||
|
bindsym --locked XF86AudioLowerVolume exec $volume_down
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
background = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
};
|
||||||
|
font = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "pango:monospace 11";
|
||||||
|
description = ''
|
||||||
|
default font (for e.g. window titles)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
mod = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "Mod4";
|
||||||
|
description = ''
|
||||||
|
Super key (for non-application shortcuts).
|
||||||
|
- "Mod1" for Alt
|
||||||
|
- "Mod4" for logo key
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
workspace_layout = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "default";
|
||||||
|
description = ''
|
||||||
|
how to arrange windows within new workspaces, by default:
|
||||||
|
- "default" (split)
|
||||||
|
- "tabbed"
|
||||||
|
- etc
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
xwayland = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
whether or not to enable xwayland (allows running X11 apps on sway).
|
||||||
|
some electron apps (e.g. element-desktop) require xwayland.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
screenshot_cmd = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "grimshot copy area";
|
||||||
|
description = "command to run when user wants to take a screenshot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
packageUnwrapped = swayPackage;
|
||||||
|
suggestedPrograms = [
|
||||||
|
"guiApps"
|
||||||
|
"blueberry" # GUI bluetooth manager
|
||||||
|
"brightnessctl"
|
||||||
|
"conky" # for a nice background
|
||||||
|
"fontconfig"
|
||||||
|
"fuzzel"
|
||||||
|
# "gnome.gnome-bluetooth" # XXX(2023/05/14): broken
|
||||||
|
# "gnome.gnome-control-center" # XXX(2023/06/28): depends on webkitgtk4_1
|
||||||
|
"playerctl" # for waybar & particularly to have playerctld running
|
||||||
|
"pulsemixer" # for volume controls
|
||||||
|
"splatmoji" # used by sway config
|
||||||
|
"sway-contrib.grimshot" # used by sway config
|
||||||
|
# "swayidle" # enable if you need it
|
||||||
|
"swaylock" # used by sway config
|
||||||
|
"swaynotificationcenter" # notification daemon
|
||||||
|
"unl0kr" # greeter
|
||||||
|
"waybar" # used by sway config
|
||||||
|
"wdisplays" # like xrandr
|
||||||
|
"wl-clipboard"
|
||||||
|
"wob" # render volume changes on-screen
|
||||||
|
"xdg-desktop-portal"
|
||||||
|
# xdg-desktop-portal-gtk provides portals for:
|
||||||
|
# - org.freedesktop.impl.portal.Access
|
||||||
|
# - org.freedesktop.impl.portal.Account
|
||||||
|
# - org.freedesktop.impl.portal.DynamicLauncher
|
||||||
|
# - org.freedesktop.impl.portal.Email
|
||||||
|
# - org.freedesktop.impl.portal.FileChooser
|
||||||
|
# - org.freedesktop.impl.portal.Inhibit
|
||||||
|
# - org.freedesktop.impl.portal.Notification
|
||||||
|
# - org.freedesktop.impl.portal.Print
|
||||||
|
# and conditionally (i.e. unless buildPortalsInGnome = false) for:
|
||||||
|
# - org.freedesktop.impl.portal.AppChooser (@appchooser_iface@)
|
||||||
|
# - org.freedesktop.impl.portal.Lockdown (@lockdown_iface@)
|
||||||
|
# - org.freedesktop.impl.portal.Settings (@settings_iface@)
|
||||||
|
# - org.freedesktop.impl.portal.Wallpaper (@wallpaper_iface@)
|
||||||
|
"xdg-desktop-portal-gtk"
|
||||||
|
# xdg-desktop-portal-wlr provides portals for screenshots/screen sharing
|
||||||
|
"xdg-desktop-portal-wlr"
|
||||||
|
"xdg-terminal-exec" # used by sway config
|
||||||
|
];
|
||||||
|
|
||||||
|
secrets.".config/sane-sway/snippets.txt" = ../../../../secrets/common/snippets.txt.bin;
|
||||||
|
|
||||||
|
fs.".config/xdg-desktop-portal/sway-portals.conf".symlink.text = ''
|
||||||
|
# portals.conf docs: <https://flatpak.github.io/xdg-desktop-portal/docs/portals.conf.html>
|
||||||
|
[preferred]
|
||||||
|
default=wlr;gtk
|
||||||
|
'';
|
||||||
|
|
||||||
|
fs.".config/sway/config".symlink.target = pkgs.callPackage ./sway-config.nix {
|
||||||
|
inherit config;
|
||||||
|
swayCfg = cfg.config;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.sway-session = {
|
||||||
|
description = "sway-session: active iff sway desktop environment is baseline operational";
|
||||||
|
documentation = [
|
||||||
|
"https://github.com/swaywm/sway/issues/7862"
|
||||||
|
"https://github.com/alebastr/sway-systemd"
|
||||||
|
];
|
||||||
|
|
||||||
|
# we'd like to start graphical-session after sway is ready, but it's marked `RefuseManualStart` because Lennart.
|
||||||
|
# instead, create `sway-session.service` which `bindsTo` `graphical-session.target`.
|
||||||
|
# we can manually start `sway-session`, and the `bindsTo` means that it will start `graphical-session`,
|
||||||
|
# and then track `graphical-session`s state (that is: it'll stop when graphical-session stops).
|
||||||
|
#
|
||||||
|
# additionally, set `ConditionEnvironment` to guard that the sway environment variables *really have* been imported into systemd.
|
||||||
|
unitConfig.ConditionEnvironment = "SWAYSOCK";
|
||||||
|
# requiredBy = [ "graphical-session.target" ];
|
||||||
|
before = [ "graphical-session.target" ];
|
||||||
|
bindsTo = [ "graphical-session.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${pkgs.coreutils}/bin/true";
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
sane.gui.gtk = lib.mkIf cfg.enabled {
|
||||||
|
enable = lib.mkDefault true;
|
||||||
|
# gtk-theme = lib.mkDefault "Fluent-Light-compact";
|
||||||
|
gtk-theme = lib.mkDefault "Tokyonight-Light-B";
|
||||||
|
# icon-theme = lib.mkDefault "HighContrast"; # 4/5 coverage on moby
|
||||||
|
# icon-theme = lib.mkDefault "WhiteSur"; # 3.5/5 coverage on moby, but it provides a bunch for Fractal/Dino
|
||||||
|
# icon-theme = lib.mkDefault "Humanity"; # 3.5/5 coverage on moby, but it provides the bookmark icon
|
||||||
|
# icon-theme = lib.mkDefault "Paper"; # 3.5/5 coverage on moby, but it provides the bookmark icon
|
||||||
|
# icon-theme = lib.mkDefault "Nordzy"; # 3/5 coverage on moby
|
||||||
|
# icon-theme = lib.mkDefault "Fluent"; # 3/5 coverage on moby
|
||||||
|
# icon-theme = lib.mkDefault "Colloid"; # 3/5 coverage on moby
|
||||||
|
# icon-theme = lib.mkDefault "Qogir"; # 2.5/5 coverage on moby
|
||||||
|
# icon-theme = lib.mkDefault "rose-pine-dawn"; # 2.5/5 coverage on moby
|
||||||
|
# icon-theme = lib.mkDefault "Flat-Remix-Grey-Light"; # requires qtbase
|
||||||
|
};
|
||||||
|
|
||||||
|
# TODO: port to sane.programs
|
||||||
|
programs.xwayland = lib.mkIf cfg.enabled {
|
||||||
|
enable = cfg.config.xwayland;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.gvfs = lib.mkIf cfg.enabled {
|
||||||
|
enable = true; # allow nautilus to mount remote filesystems (e.g. ftp://...)
|
||||||
|
package = lib.mkDefault (pkgs.gvfs.override {
|
||||||
|
# i don't need to mount samba shares, and samba build is expensive/flaky (mostly for cross, but even problematic on native)
|
||||||
|
samba = null;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
# unlike other DEs, sway configures no audio stack
|
||||||
|
# administer with pw-cli, pw-mon, pw-top commands
|
||||||
|
services.pipewire = lib.mkIf cfg.enabled {
|
||||||
|
enable = true;
|
||||||
|
alsa.enable = true;
|
||||||
|
alsa.support32Bit = true; # ??
|
||||||
|
# emulate pulseaudio for legacy apps (e.g. sxmo-utils)
|
||||||
|
pulse.enable = true;
|
||||||
|
};
|
||||||
|
systemd.user.services."pipewire".wantedBy = lib.optionals cfg.enabled [ "graphical-session.target" ];
|
||||||
|
|
||||||
|
# rtkit/RealtimeKit: allow applications which want realtime audio (e.g. Dino? Pulseaudio server?) to request it.
|
||||||
|
# this might require more configuration (e.g. polkit-related) to work exactly as desired.
|
||||||
|
# - readme outlines requirements: <https://github.com/heftig/rtkit>
|
||||||
|
# XXX(2023/10/12): rtkit does not play well on moby. any application sending audio out dies after 10s.
|
||||||
|
# security.rtkit.enable = true;
|
||||||
|
# persist per-device volume levels
|
||||||
|
sane.user.persist.byStore.plaintext = lib.optionals cfg.enabled [ ".local/state/wireplumber" ];
|
||||||
|
|
||||||
|
# persist per-device volume settings across power cycles.
|
||||||
|
# pipewire sits atop the kernel ALSA API, so alsa-utils knows about device volumes.
|
||||||
|
# but wireplumber also tries to do some of this
|
||||||
|
# systemd.services.alsa-store = {
|
||||||
|
# # based on <repo:nixos/nixpkgs:nixos/modules/services/audio/alsa.nix>
|
||||||
|
# description = "Store Sound Card State";
|
||||||
|
# wantedBy = [ "multi-user.target" ];
|
||||||
|
# serviceConfig = {
|
||||||
|
# Type = "oneshot";
|
||||||
|
# RemainAfterExit = true;
|
||||||
|
# ExecStart = "${pkgs.alsa-utils}/sbin/alsactl restore";
|
||||||
|
# ExecStop = "${pkgs.alsa-utils}/sbin/alsactl store --ignore";
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
# sane.persist.sys.byStore.plaintext = [ "/var/lib/alsa" ];
|
||||||
|
|
||||||
|
# TODO: this can go elsewhere
|
||||||
|
# networking = lib.mkIf cfg.enabled {
|
||||||
|
# networkmanager.enable = true;
|
||||||
|
# wireless.enable = lib.mkForce false;
|
||||||
|
# };
|
||||||
|
hardware.bluetooth = lib.mkIf cfg.enabled {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
services.blueman = lib.mkIf cfg.enabled {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# gsd provides Rfkill, which is required for the bluetooth pane in gnome-control-center to work
|
||||||
|
# services.gnome.gnome-settings-daemon.enable = true;
|
||||||
|
|
||||||
|
# start the components of gsd we need at login
|
||||||
|
# systemd.user.targets."org.gnome.SettingsDaemon.Rfkill".wantedBy = [ "graphical-session.target" ];
|
||||||
|
# go ahead and `systemctl --user cat gnome-session-initialized.target`. i dare you.
|
||||||
|
# the only way i can figure out how to get Rfkill to actually load is to just disable all the shit it depends on.
|
||||||
|
# it doesn't actually seem to need ANY of them in the first place T_T
|
||||||
|
# systemd.user.targets."gnome-session-initialized".enable = false;
|
||||||
|
|
||||||
|
# bluez can't connect to audio devices unless pipewire is running.
|
||||||
|
# a system service can't depend on a user service, so just launch it at graphical-session
|
||||||
|
}
|
||||||
|
|
@@ -4,6 +4,7 @@
|
|||||||
, writeShellApplication
|
, writeShellApplication
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
|
# TODO: port this snip_cmd_pkg to an ordinary `sane.programs`
|
||||||
prog = config.sane.programs;
|
prog = config.sane.programs;
|
||||||
# "bookmarking"/snippets inspired by Luke Smith:
|
# "bookmarking"/snippets inspired by Luke Smith:
|
||||||
# - <https://www.youtube.com/watch?v=d_11QaTlf1I>
|
# - <https://www.youtube.com/watch?v=d_11QaTlf1I>
|
||||||
@@ -15,7 +16,7 @@ let
|
|||||||
prog.wtype.package
|
prog.wtype.package
|
||||||
];
|
];
|
||||||
text = ''
|
text = ''
|
||||||
snippet=$(cat ${../snippets.txt} ~/.config/sane-sway/snippets.txt | \
|
snippet=$(cat ${./snippets.txt} ~/.config/sane-sway/snippets.txt | \
|
||||||
fuzzel -d -i -w 60 | \
|
fuzzel -d -i -w 60 | \
|
||||||
sed 's/ #.*$//')
|
sed 's/ #.*$//')
|
||||||
wtype "$snippet"
|
wtype "$snippet"
|
@@ -11,7 +11,6 @@ in
|
|||||||
./greetd.nix
|
./greetd.nix
|
||||||
./gtk.nix
|
./gtk.nix
|
||||||
./phosh.nix
|
./phosh.nix
|
||||||
./sway
|
|
||||||
./sxmo
|
./sxmo
|
||||||
./theme
|
./theme
|
||||||
];
|
];
|
||||||
|
@@ -1,268 +0,0 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
# docs: https://nixos.wiki/wiki/Sway
|
|
||||||
# sway-config docs: `man 5 sway`
|
|
||||||
let
|
|
||||||
cfg = config.sane.gui.sway;
|
|
||||||
wrapSway = configuredSway: let
|
|
||||||
# `wrapSway` exists to launch sway with our desired debugging facilities.
|
|
||||||
# i.e. redirect output to syslog.
|
|
||||||
systemd-cat = "${lib.getBin pkgs.systemd}/bin/systemd-cat";
|
|
||||||
swayLauncher = pkgs.writeShellScriptBin "sway" ''
|
|
||||||
# sway defaults to auto-generating a unix domain socket named "sway-ipc.$UID.NNNN.sock",
|
|
||||||
# which allows for multiple sway sessions under the same user.
|
|
||||||
# but the unpredictability makes static sandboxing & such difficult, so hardcode it:
|
|
||||||
export SWAYSOCK="$XDG_RUNTIME_DIR/sway-ipc.sock"
|
|
||||||
export XDG_CURRENT_DESKTOP=sway
|
|
||||||
|
|
||||||
echo "launching sway (sway.desktop)..." | ${systemd-cat} --identifier=sway
|
|
||||||
exec ${configuredSway}/bin/sway 2>&1 | ${systemd-cat} --identifier=sway
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
pkgs.symlinkJoin {
|
|
||||||
inherit (configuredSway) meta version;
|
|
||||||
name = "sway-wrapped";
|
|
||||||
paths = [
|
|
||||||
swayLauncher
|
|
||||||
configuredSway
|
|
||||||
];
|
|
||||||
};
|
|
||||||
swayPackage = wrapSway (pkgs.sway-unwrapped.overrideAttrs (_: {
|
|
||||||
# isNixOS = true; #< doesn't matter
|
|
||||||
# TODO: something else is dragging a xwayland-enabled wlroots into the environment,
|
|
||||||
# making this actually kinda wasteful.
|
|
||||||
enableXWayland = cfg.config.xwayland;
|
|
||||||
}));
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options = with lib; {
|
|
||||||
sane.gui.sway.enable = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
};
|
|
||||||
sane.gui.sway.config = {
|
|
||||||
extra_lines = mkOption {
|
|
||||||
type = types.lines;
|
|
||||||
description = ''
|
|
||||||
extra lines to append to the sway config
|
|
||||||
'';
|
|
||||||
default = ''
|
|
||||||
# XXX: sway needs exclusive control of XF86Audio{Raise,Lower}Volume, so assign this from a block that it can override.
|
|
||||||
# TODO: factor the bindings out into proper options and be less hacky?
|
|
||||||
bindsym --locked XF86AudioRaiseVolume exec $volume_up
|
|
||||||
bindsym --locked XF86AudioLowerVolume exec $volume_down
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
background = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
};
|
|
||||||
font = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "pango:monospace 11";
|
|
||||||
description = ''
|
|
||||||
default font (for e.g. window titles)
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
mod = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "Mod4";
|
|
||||||
description = ''
|
|
||||||
Super key (for non-application shortcuts).
|
|
||||||
- "Mod1" for Alt
|
|
||||||
- "Mod4" for logo key
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
workspace_layout = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "default";
|
|
||||||
description = ''
|
|
||||||
how to arrange windows within new workspaces, by default:
|
|
||||||
- "default" (split)
|
|
||||||
- "tabbed"
|
|
||||||
- etc
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
xwayland = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
whether or not to enable xwayland (allows running X11 apps on sway).
|
|
||||||
some electron apps (e.g. element-desktop) require xwayland.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
screenshot_cmd = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "grimshot copy area";
|
|
||||||
description = "command to run when user wants to take a screenshot";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkMerge [
|
|
||||||
{
|
|
||||||
sane.programs.sway = {
|
|
||||||
packageUnwrapped = swayPackage;
|
|
||||||
suggestedPrograms = [
|
|
||||||
"guiApps"
|
|
||||||
"blueberry" # GUI bluetooth manager
|
|
||||||
"brightnessctl"
|
|
||||||
"conky" # for a nice background
|
|
||||||
"fontconfig"
|
|
||||||
"fuzzel"
|
|
||||||
# "gnome.gnome-bluetooth" # XXX(2023/05/14): broken
|
|
||||||
# "gnome.gnome-control-center" # XXX(2023/06/28): depends on webkitgtk4_1
|
|
||||||
"playerctl" # for waybar & particularly to have playerctld running
|
|
||||||
"pulsemixer" # for volume controls
|
|
||||||
"splatmoji" # used by sway config
|
|
||||||
"sway-contrib.grimshot" # used by sway config
|
|
||||||
# "swayidle" # enable if you need it
|
|
||||||
"swaylock" # used by sway config
|
|
||||||
"swaynotificationcenter" # notification daemon
|
|
||||||
"unl0kr" # greeter
|
|
||||||
"waybar" # used by sway config
|
|
||||||
"wdisplays" # like xrandr
|
|
||||||
"wl-clipboard"
|
|
||||||
"wob" # render volume changes on-screen
|
|
||||||
"xdg-desktop-portal"
|
|
||||||
# xdg-desktop-portal-gtk provides portals for:
|
|
||||||
# - org.freedesktop.impl.portal.Access
|
|
||||||
# - org.freedesktop.impl.portal.Account
|
|
||||||
# - org.freedesktop.impl.portal.DynamicLauncher
|
|
||||||
# - org.freedesktop.impl.portal.Email
|
|
||||||
# - org.freedesktop.impl.portal.FileChooser
|
|
||||||
# - org.freedesktop.impl.portal.Inhibit
|
|
||||||
# - org.freedesktop.impl.portal.Notification
|
|
||||||
# - org.freedesktop.impl.portal.Print
|
|
||||||
# and conditionally (i.e. unless buildPortalsInGnome = false) for:
|
|
||||||
# - org.freedesktop.impl.portal.AppChooser (@appchooser_iface@)
|
|
||||||
# - org.freedesktop.impl.portal.Lockdown (@lockdown_iface@)
|
|
||||||
# - org.freedesktop.impl.portal.Settings (@settings_iface@)
|
|
||||||
# - org.freedesktop.impl.portal.Wallpaper (@wallpaper_iface@)
|
|
||||||
"xdg-desktop-portal-gtk"
|
|
||||||
# xdg-desktop-portal-wlr provides portals for screenshots/screen sharing
|
|
||||||
"xdg-desktop-portal-wlr"
|
|
||||||
"xdg-terminal-exec" # used by sway config
|
|
||||||
];
|
|
||||||
|
|
||||||
secrets.".config/sane-sway/snippets.txt" = ../../../../secrets/common/snippets.txt.bin;
|
|
||||||
|
|
||||||
fs.".config/xdg-desktop-portal/sway-portals.conf".symlink.text = ''
|
|
||||||
# portals.conf docs: <https://flatpak.github.io/xdg-desktop-portal/docs/portals.conf.html>
|
|
||||||
[preferred]
|
|
||||||
default=wlr;gtk
|
|
||||||
'';
|
|
||||||
|
|
||||||
fs.".config/sway/config".symlink.target = pkgs.callPackage ./sway-config.nix {
|
|
||||||
inherit config;
|
|
||||||
swayCfg = cfg.config;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.sway-session = {
|
|
||||||
description = "sway-session: active iff sway desktop environment is baseline operational";
|
|
||||||
documentation = [
|
|
||||||
"https://github.com/swaywm/sway/issues/7862"
|
|
||||||
"https://github.com/alebastr/sway-systemd"
|
|
||||||
];
|
|
||||||
|
|
||||||
# we'd like to start graphical-session after sway is ready, but it's marked `RefuseManualStart` because Lennart.
|
|
||||||
# instead, create `sway-session.service` which `bindsTo` `graphical-session.target`.
|
|
||||||
# we can manually start `sway-session`, and the `bindsTo` means that it will start `graphical-session`,
|
|
||||||
# and then track `graphical-session`s state (that is: it'll stop when graphical-session stops).
|
|
||||||
#
|
|
||||||
# additionally, set `ConditionEnvironment` to guard that the sway environment variables *really have* been imported into systemd.
|
|
||||||
unitConfig.ConditionEnvironment = "SWAYSOCK";
|
|
||||||
# requiredBy = [ "graphical-session.target" ];
|
|
||||||
before = [ "graphical-session.target" ];
|
|
||||||
bindsTo = [ "graphical-session.target" ];
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${pkgs.coreutils}/bin/true";
|
|
||||||
Type = "oneshot";
|
|
||||||
RemainAfterExit = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
(lib.mkIf cfg.enable {
|
|
||||||
sane.programs.sway.enableFor.user.colin = 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 "Tokyonight-Light-B";
|
|
||||||
# sane.gui.gtk.icon-theme = lib.mkDefault "HighContrast"; # 4/5 coverage on moby
|
|
||||||
# sane.gui.gtk.icon-theme = lib.mkDefault "WhiteSur"; # 3.5/5 coverage on moby, but it provides a bunch for Fractal/Dino
|
|
||||||
# sane.gui.gtk.icon-theme = lib.mkDefault "Humanity"; # 3.5/5 coverage on moby, but it provides the bookmark icon
|
|
||||||
# sane.gui.gtk.icon-theme = lib.mkDefault "Paper"; # 3.5/5 coverage on moby, but it provides the bookmark icon
|
|
||||||
# sane.gui.gtk.icon-theme = lib.mkDefault "Nordzy"; # 3/5 coverage on moby
|
|
||||||
# sane.gui.gtk.icon-theme = lib.mkDefault "Fluent"; # 3/5 coverage on moby
|
|
||||||
# sane.gui.gtk.icon-theme = lib.mkDefault "Colloid"; # 3/5 coverage on moby
|
|
||||||
# sane.gui.gtk.icon-theme = lib.mkDefault "Qogir"; # 2.5/5 coverage on moby
|
|
||||||
# sane.gui.gtk.icon-theme = lib.mkDefault "rose-pine-dawn"; # 2.5/5 coverage on moby
|
|
||||||
# sane.gui.gtk.icon-theme = lib.mkDefault "Flat-Remix-Grey-Light"; # requires qtbase
|
|
||||||
|
|
||||||
# unlike other DEs, sway configures no audio stack
|
|
||||||
# administer with pw-cli, pw-mon, pw-top commands
|
|
||||||
services.pipewire = {
|
|
||||||
enable = true;
|
|
||||||
alsa.enable = true;
|
|
||||||
alsa.support32Bit = true; # ??
|
|
||||||
# emulate pulseaudio for legacy apps (e.g. sxmo-utils)
|
|
||||||
pulse.enable = true;
|
|
||||||
};
|
|
||||||
services.gvfs.enable = true; # allow nautilus to mount remote filesystems (e.g. ftp://...)
|
|
||||||
services.gvfs.package = lib.mkDefault (pkgs.gvfs.override {
|
|
||||||
# i don't need to mount samba shares, and samba build is expensive/flaky (mostly for cross, but even problematic on native)
|
|
||||||
samba = null;
|
|
||||||
});
|
|
||||||
# rtkit/RealtimeKit: allow applications which want realtime audio (e.g. Dino? Pulseaudio server?) to request it.
|
|
||||||
# this might require more configuration (e.g. polkit-related) to work exactly as desired.
|
|
||||||
# - readme outlines requirements: <https://github.com/heftig/rtkit>
|
|
||||||
# XXX(2023/10/12): rtkit does not play well on moby. any application sending audio out dies after 10s.
|
|
||||||
# security.rtkit.enable = true;
|
|
||||||
# persist per-device volume levels
|
|
||||||
sane.user.persist.byStore.plaintext = [ ".local/state/wireplumber" ];
|
|
||||||
|
|
||||||
# persist per-device volume settings across power cycles.
|
|
||||||
# pipewire sits atop the kernel ALSA API, so alsa-utils knows about device volumes.
|
|
||||||
# but wireplumber also tries to do some of this
|
|
||||||
# systemd.services.alsa-store = {
|
|
||||||
# # based on <repo:nixos/nixpkgs:nixos/modules/services/audio/alsa.nix>
|
|
||||||
# description = "Store Sound Card State";
|
|
||||||
# wantedBy = [ "multi-user.target" ];
|
|
||||||
# serviceConfig = {
|
|
||||||
# Type = "oneshot";
|
|
||||||
# RemainAfterExit = true;
|
|
||||||
# ExecStart = "${pkgs.alsa-utils}/sbin/alsactl restore";
|
|
||||||
# ExecStop = "${pkgs.alsa-utils}/sbin/alsactl store --ignore";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
# sane.persist.sys.byStore.plaintext = [ "/var/lib/alsa" ];
|
|
||||||
|
|
||||||
networking.networkmanager.enable = true;
|
|
||||||
networking.wireless.enable = lib.mkForce false;
|
|
||||||
|
|
||||||
hardware.bluetooth.enable = true;
|
|
||||||
services.blueman.enable = true;
|
|
||||||
|
|
||||||
# gsd provides Rfkill, which is required for the bluetooth pane in gnome-control-center to work
|
|
||||||
# services.gnome.gnome-settings-daemon.enable = true;
|
|
||||||
|
|
||||||
# start the components of gsd we need at login
|
|
||||||
# systemd.user.targets."org.gnome.SettingsDaemon.Rfkill".wantedBy = [ "graphical-session.target" ];
|
|
||||||
# go ahead and `systemctl --user cat gnome-session-initialized.target`. i dare you.
|
|
||||||
# the only way i can figure out how to get Rfkill to actually load is to just disable all the shit it depends on.
|
|
||||||
# it doesn't actually seem to need ANY of them in the first place T_T
|
|
||||||
# systemd.user.targets."gnome-session-initialized".enable = false;
|
|
||||||
|
|
||||||
# bluez can't connect to audio devices unless pipewire is running.
|
|
||||||
# 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" ];
|
|
||||||
|
|
||||||
programs.xwayland.enable = cfg.config.xwayland;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@@ -292,108 +292,106 @@ in
|
|||||||
|
|
||||||
(lib.mkIf cfg.enable (lib.mkMerge [
|
(lib.mkIf cfg.enable (lib.mkMerge [
|
||||||
{
|
{
|
||||||
|
sane.programs.sway.enableFor.user.colin = true;
|
||||||
sane.programs.unl0kr.enableFor.user.colin = (cfg.greeter == "unl0kr");
|
sane.programs.unl0kr.enableFor.user.colin = (cfg.greeter == "unl0kr");
|
||||||
sane.programs.waybar.config = {
|
sane.programs.waybar.config = {
|
||||||
top = import ./waybar-top.nix { inherit pkgs; };
|
top = import ./waybar-top.nix { inherit pkgs; };
|
||||||
# reset extra waybar style
|
# reset extra waybar style
|
||||||
extra_style = "";
|
extra_style = "";
|
||||||
};
|
};
|
||||||
sane.gui.sway = {
|
sane.programs.sway.config = {
|
||||||
enable = true;
|
# N.B. missing from upstream sxmo config here is:
|
||||||
config = {
|
# - `bindsym $mod+g exec sxmo_hook_locker.sh`
|
||||||
# N.B. missing from upstream sxmo config here is:
|
# - `bindsym $mod+t exec sxmo_appmenu.sh power`
|
||||||
# - `bindsym $mod+g exec sxmo_hook_locker.sh`
|
# - `bindsym $mod+i exec sxmo_wmmenu.sh windowswitcher`
|
||||||
# - `bindsym $mod+t exec sxmo_appmenu.sh power`
|
# - `bindsym $mod+p exec sxmo_appmenu.sh`
|
||||||
# - `bindsym $mod+i exec sxmo_wmmenu.sh windowswitcher`
|
# - `bindsym $mod+Shift+p exec sxmo_appmenu.sh sys`
|
||||||
# - `bindsym $mod+p exec sxmo_appmenu.sh`
|
# - `input * xkb_options compose:ralt`
|
||||||
# - `bindsym $mod+Shift+p exec sxmo_appmenu.sh sys`
|
# these could be added, but i don't see much benefit.
|
||||||
# - `input * xkb_options compose:ralt`
|
font = "pango:monospace 10";
|
||||||
# these could be added, but i don't see much benefit.
|
mod = "Mod1"; # prefer Alt
|
||||||
font = "pango:monospace 10";
|
# about xwayland:
|
||||||
mod = "Mod1"; # prefer Alt
|
# - required by many electron apps, though some electron apps support NIXOS_OZONE_WL=1 for native wayland.
|
||||||
# about xwayland:
|
# - when xwayland is enabled, KOreader incorrectly chooses the X11 backend
|
||||||
# - required by many electron apps, though some electron apps support NIXOS_OZONE_WL=1 for native wayland.
|
# -> slower; blurrier
|
||||||
# - when xwayland is enabled, KOreader incorrectly chooses the X11 backend
|
# - xwayland uses a small amount of memory (like 30MiB, IIRC?)
|
||||||
# -> slower; blurrier
|
xwayland = false;
|
||||||
# - xwayland uses a small amount of memory (like 30MiB, IIRC?)
|
workspace_layout = "tabbed";
|
||||||
xwayland = false;
|
|
||||||
workspace_layout = "tabbed";
|
|
||||||
|
|
||||||
screenshot_cmd = "sxmo_screenshot.sh";
|
screenshot_cmd = "sxmo_screenshot.sh";
|
||||||
extra_lines =
|
extra_lines =
|
||||||
let
|
let
|
||||||
sxmo_init = pkgs.writeShellScript "sxmo_init.sh" ''
|
sxmo_init = pkgs.writeShellScript "sxmo_init.sh" ''
|
||||||
# perform the same behavior as sxmo_{x,w}init.sh -- but without actually launching wayland/X11
|
# perform the same behavior as sxmo_{x,w}init.sh -- but without actually launching wayland/X11
|
||||||
# this amounts to:
|
# this amounts to:
|
||||||
# - setting env vars (e.g. getting the hooks onto PATH)
|
# - setting env vars (e.g. getting the hooks onto PATH)
|
||||||
# - placing default configs in ~ for sxmo-launched services (sxmo_migrate.sh)
|
# - placing default configs in ~ for sxmo-launched services (sxmo_migrate.sh)
|
||||||
# - binding vol/power buttons (sxmo_swayinitconf.sh)
|
# - binding vol/power buttons (sxmo_swayinitconf.sh)
|
||||||
# - launching sxmo_hook_start.sh
|
# - launching sxmo_hook_start.sh
|
||||||
#
|
#
|
||||||
# the commands here are similar to upstream sxmo_winit.sh, but not identical and the ordering may be different
|
# the commands here are similar to upstream sxmo_winit.sh, but not identical and the ordering may be different
|
||||||
|
|
||||||
# profile may contain SXMO_DEVICE_NAME which is used by _sxmo_load_environment so load it early
|
# profile may contain SXMO_DEVICE_NAME which is used by _sxmo_load_environment so load it early
|
||||||
source "$XDG_CONFIG_HOME/sxmo/profile"
|
source "$XDG_CONFIG_HOME/sxmo/profile"
|
||||||
# sourcing upstream sxmo_init.sh triggers _sxmo_load_environment
|
# sourcing upstream sxmo_init.sh triggers _sxmo_load_environment
|
||||||
# which ensures SXMO_* environment variables are set
|
# which ensures SXMO_* environment variables are set
|
||||||
source ${package}/etc/profile.d/sxmo_init.sh
|
source ${package}/etc/profile.d/sxmo_init.sh
|
||||||
# _sxmo_prepare_dirs ensures ~/.cache/sxmo & other XDG dirs exist with correct perms & owner
|
# _sxmo_prepare_dirs ensures ~/.cache/sxmo & other XDG dirs exist with correct perms & owner
|
||||||
_sxmo_prepare_dirs
|
_sxmo_prepare_dirs
|
||||||
# migrate tells sxmo to provide the following default files:
|
# migrate tells sxmo to provide the following default files:
|
||||||
# - ~/.config/sxmo/profile
|
# - ~/.config/sxmo/profile
|
||||||
# - ~/.config/fontconfig/conf.d/50-sxmo.conf
|
# - ~/.config/fontconfig/conf.d/50-sxmo.conf
|
||||||
# - ~/.config/sxmo/sway
|
# - ~/.config/sxmo/sway
|
||||||
# - ~/.config/foot/foot.ini
|
# - ~/.config/foot/foot.ini
|
||||||
# - ~/.config/mako/config
|
# - ~/.config/mako/config
|
||||||
# - ~/.config/sxmo/bonsai_tree.json
|
# - ~/.config/sxmo/bonsai_tree.json
|
||||||
# - ~/.config/wob/wob.ini
|
# - ~/.config/wob/wob.ini
|
||||||
# - ~/.config/sxmo/conky.conf
|
# - ~/.config/sxmo/conky.conf
|
||||||
sxmo_migrate.sh sync
|
sxmo_migrate.sh sync
|
||||||
# various things may have happened above that require me to re-load the profile here:
|
# various things may have happened above that require me to re-load the profile here:
|
||||||
# - _sxmo_load_environment sources a deviceprofile.sh file, which may override my profile settings.
|
# - _sxmo_load_environment sources a deviceprofile.sh file, which may override my profile settings.
|
||||||
# very obvious if you set a non-default SXMO_SWAY_SCALE.
|
# very obvious if you set a non-default SXMO_SWAY_SCALE.
|
||||||
# - sxmo_migrate.sh may have provided a default profile, if i failed to
|
# - sxmo_migrate.sh may have provided a default profile, if i failed to
|
||||||
source "$XDG_CONFIG_HOME/sxmo/profile"
|
source "$XDG_CONFIG_HOME/sxmo/profile"
|
||||||
# place my non-specialized hooks at higher precedence than the default device-hooks
|
# place my non-specialized hooks at higher precedence than the default device-hooks
|
||||||
# alternative would be to move my hooks to ~/.config/sxmo/hooks/<device-name>.
|
# alternative would be to move my hooks to ~/.config/sxmo/hooks/<device-name>.
|
||||||
export PATH="$XDG_CONFIG_HOME/sxmo/hooks:$PATH"
|
export PATH="$XDG_CONFIG_HOME/sxmo/hooks:$PATH"
|
||||||
|
|
||||||
# kill anything leftover from the previous sxmo run. this way we can (try to) be reentrant
|
# kill anything leftover from the previous sxmo run. this way we can (try to) be reentrant
|
||||||
echo "sxmo_init: killing stale daemons (if active)"
|
echo "sxmo_init: killing stale daemons (if active)"
|
||||||
sxmo_jobs.sh stop all
|
sxmo_jobs.sh stop all
|
||||||
pkill bemenu
|
pkill bemenu
|
||||||
pkill wvkbd
|
pkill wvkbd
|
||||||
pkill superd
|
pkill superd
|
||||||
|
|
||||||
# configure vol/power-button input mapping (upstream SXMO has this in sway config)
|
# configure vol/power-button input mapping (upstream SXMO has this in sway config)
|
||||||
echo "sxmo_init: configuring sway bindings/displays with:"
|
echo "sxmo_init: configuring sway bindings/displays with:"
|
||||||
echo "SXMO_POWER_BUTTON: $SXMO_POWER_BUTTON"
|
echo "SXMO_POWER_BUTTON: $SXMO_POWER_BUTTON"
|
||||||
echo "SXMO_VOLUME_BUTTON: $SXMO_VOLUME_BUTTON"
|
echo "SXMO_VOLUME_BUTTON: $SXMO_VOLUME_BUTTON"
|
||||||
echo "SXMO_SWAY_SCALE: $SXMO_SWAY_SCALE"
|
echo "SXMO_SWAY_SCALE: $SXMO_SWAY_SCALE"
|
||||||
sxmo_swayinitconf.sh
|
sxmo_swayinitconf.sh
|
||||||
|
|
||||||
echo "sxmo_init: invoking sxmo_hook_start.sh with:"
|
echo "sxmo_init: invoking sxmo_hook_start.sh with:"
|
||||||
echo "PATH: $PATH"
|
echo "PATH: $PATH"
|
||||||
sxmo_hook_start.sh
|
sxmo_hook_start.sh
|
||||||
'';
|
|
||||||
in ''
|
|
||||||
# TODO: some of this is probably unnecessary
|
|
||||||
mode "menu" {
|
|
||||||
# just a placeholder for "menu" mode
|
|
||||||
bindsym --input-device=1:1:1c21800.lradc XF86AudioMute exec nothing
|
|
||||||
}
|
|
||||||
bindsym button2 kill
|
|
||||||
bindswitch lid:on exec sxmo_wm.sh dpms on
|
|
||||||
bindswitch lid:off exec sxmo_wm.sh dpms off
|
|
||||||
|
|
||||||
exec 'printf %s "$SWAYSOCK" > "$XDG_RUNTIME_DIR"/sxmo.swaysock'
|
|
||||||
|
|
||||||
# XXX(2023/12/04): this shouldn't be necessary, but without this Komikku fails to launch because XDG_SESSION_TYPE is unset
|
|
||||||
|
|
||||||
exec dbus-update-activation-environment --systemd XDG_SESSION_TYPE
|
|
||||||
exec_always ${sxmo_init}
|
|
||||||
'';
|
'';
|
||||||
};
|
in ''
|
||||||
|
# TODO: some of this is probably unnecessary
|
||||||
|
mode "menu" {
|
||||||
|
# just a placeholder for "menu" mode
|
||||||
|
bindsym --input-device=1:1:1c21800.lradc XF86AudioMute exec nothing
|
||||||
|
}
|
||||||
|
bindsym button2 kill
|
||||||
|
bindswitch lid:on exec sxmo_wm.sh dpms on
|
||||||
|
bindswitch lid:off exec sxmo_wm.sh dpms off
|
||||||
|
|
||||||
|
exec 'printf %s "$SWAYSOCK" > "$XDG_RUNTIME_DIR"/sxmo.swaysock'
|
||||||
|
|
||||||
|
# XXX(2023/12/04): this shouldn't be necessary, but without this Komikku fails to launch because XDG_SESSION_TYPE is unset
|
||||||
|
|
||||||
|
exec dbus-update-activation-environment --systemd XDG_SESSION_TYPE
|
||||||
|
exec_always ${sxmo_init}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
sane.programs.sxmoApps.enableFor.user.colin = true;
|
sane.programs.sxmoApps.enableFor.user.colin = true;
|
||||||
|
@@ -22,7 +22,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
sane.gui.sway.config.background = lib.mkDefault cfg.png;
|
sane.programs.sway.config.background = lib.mkDefault cfg.png;
|
||||||
sane.gui.sxmo.settings.SXMO_BG_IMG = lib.mkDefault (builtins.toString cfg.png);
|
sane.gui.sxmo.settings.SXMO_BG_IMG = lib.mkDefault (builtins.toString cfg.png);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user