2023-07-12 10:03:58 +00:00
|
|
|
{ config, lib, pkgs, ... }:
|
2023-09-01 23:59:21 +00:00
|
|
|
|
2022-06-07 00:35:28 +00:00
|
|
|
# docs: https://nixos.wiki/wiki/Sway
|
2023-09-02 10:37:09 +00:00
|
|
|
# sway-config docs: `man 5 sway`
|
2022-06-07 00:35:28 +00:00
|
|
|
let
|
2022-08-01 07:23:49 +00:00
|
|
|
cfg = config.sane.gui.sway;
|
2022-06-07 00:35:28 +00:00
|
|
|
in
|
|
|
|
{
|
2023-09-01 23:59:21 +00:00
|
|
|
options = with lib; {
|
2022-08-01 07:23:49 +00:00
|
|
|
sane.gui.sway.enable = mkOption {
|
2022-06-07 00:35:28 +00:00
|
|
|
default = false;
|
|
|
|
type = types.bool;
|
|
|
|
};
|
2022-10-22 08:31:51 +00:00
|
|
|
sane.gui.sway.useGreeter = mkOption {
|
|
|
|
description = ''
|
|
|
|
launch sway via a greeter (like greetd's gtkgreet).
|
|
|
|
sway is usable without a greeter, but skipping the greeter means no PAM session.
|
|
|
|
'';
|
2023-01-29 08:13:09 +00:00
|
|
|
default = true;
|
2022-10-22 08:31:51 +00:00
|
|
|
type = types.bool;
|
|
|
|
};
|
2023-09-04 11:10:30 +00:00
|
|
|
sane.gui.sway.installConfigs = mkOption {
|
|
|
|
default = true;
|
|
|
|
type = types.bool;
|
|
|
|
description = ''
|
|
|
|
populate ~/.config/sway/config & co with defaults provided by this module.
|
|
|
|
'';
|
|
|
|
};
|
2023-09-05 04:25:58 +00:00
|
|
|
sane.gui.sway.config = {
|
|
|
|
extra_lines = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
description = ''
|
|
|
|
extra lines to append to the sway config
|
|
|
|
'';
|
2023-09-05 04:51:12 +00:00
|
|
|
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
|
|
|
|
'';
|
2023-09-05 04:25:58 +00:00
|
|
|
};
|
|
|
|
font = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "pango:monospace 11";
|
|
|
|
description = ''
|
|
|
|
default font (for e.g. window titles)
|
|
|
|
'';
|
|
|
|
};
|
2023-09-05 16:13:23 +00:00
|
|
|
background = mkOption {
|
|
|
|
type = types.path;
|
|
|
|
};
|
2023-09-05 04:25:58 +00:00
|
|
|
mod = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "Mod4";
|
|
|
|
description = ''
|
|
|
|
Super key (for non-application shortcuts).
|
|
|
|
- "Mod1" for Alt
|
|
|
|
- "Mod4" for logo key
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
workspace_layout = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "default";
|
|
|
|
description = ''
|
|
|
|
how to arrange windows within new workspaces, by default:
|
|
|
|
- "default" (split)
|
|
|
|
- "tabbed"
|
|
|
|
- etc
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
# TODO: split these into their own option scope
|
|
|
|
brightness_down_cmd = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "${pkgs.brightnessctl}/bin/brightnessctl set -2%";
|
|
|
|
description = "command to run when use wants to decrease screen brightness";
|
|
|
|
};
|
|
|
|
brightness_up_cmd = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "${pkgs.brightnessctl}/bin/brightnessctl set +2%";
|
|
|
|
description = "command to run when use wants to increase screen brightness";
|
|
|
|
};
|
|
|
|
screenshot_cmd = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "${pkgs.sway-contrib.grimshot}/bin/grimshot copy area";
|
|
|
|
description = "command to run when user wants to take a screenshot";
|
|
|
|
};
|
|
|
|
status_cmd = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "${pkgs.i3status}/bin/i3status";
|
|
|
|
description = "command to run that populates the status section of the topbar";
|
|
|
|
};
|
|
|
|
};
|
2023-09-05 03:43:32 +00:00
|
|
|
sane.gui.sway.waybar.top = mkOption {
|
|
|
|
type = types.submodule {
|
|
|
|
# `attrsOf types.anything` (v.s. plain `attrs`) causes merging of the toplevel items.
|
|
|
|
# this allows for `waybar.top.x = lib.mkDefault a;` with `waybar.top.x = b;` to resolve to `b`.
|
|
|
|
# but note that `waybar.top.x.y = <multiple assignment>` won't be handled as desired.
|
|
|
|
freeformType = types.attrsOf types.anything;
|
|
|
|
};
|
|
|
|
default = {};
|
|
|
|
description = ''
|
|
|
|
Waybar configuration for the bar at the top of the display.
|
|
|
|
see: <https://github.com/Alexays/Waybar/wiki/Configuration>
|
|
|
|
example:
|
|
|
|
```nix
|
|
|
|
{
|
|
|
|
height = 40;
|
|
|
|
modules-left = [ "sway/workspaces" "sway/mode" ];
|
|
|
|
...
|
|
|
|
}
|
|
|
|
```
|
|
|
|
'';
|
|
|
|
};
|
2022-06-07 00:35:28 +00:00
|
|
|
};
|
2023-09-01 23:59:21 +00:00
|
|
|
|
|
|
|
config = lib.mkMerge [
|
2023-02-04 00:43:00 +00:00
|
|
|
{
|
|
|
|
sane.programs.swayApps = {
|
|
|
|
package = null;
|
|
|
|
suggestedPrograms = [
|
2023-02-04 00:50:47 +00:00
|
|
|
"guiApps"
|
2023-09-05 08:31:50 +00:00
|
|
|
"conky" # for a nice background
|
2023-04-24 07:22:33 +00:00
|
|
|
"splatmoji" # used by us, but 'enabling' it gets us persistence & cfg
|
2023-02-04 00:43:00 +00:00
|
|
|
"swaylock"
|
|
|
|
"swayidle"
|
|
|
|
"wl-clipboard"
|
2023-05-15 02:42:33 +00:00
|
|
|
"blueberry" # GUI bluetooth manager
|
2023-02-04 00:43:00 +00:00
|
|
|
"mako" # notification daemon
|
|
|
|
# # "pavucontrol"
|
2023-05-15 02:42:33 +00:00
|
|
|
# "gnome.gnome-bluetooth" # XXX(2023/05/14): broken
|
2023-06-29 10:56:56 +00:00
|
|
|
# "gnome.gnome-control-center" # XXX(2023/06/28): depends on webkitgtk4_1
|
2023-03-03 10:22:41 +00:00
|
|
|
"sway-contrib.grimshot"
|
2023-06-29 10:56:56 +00:00
|
|
|
"wdisplays" # like xrandr
|
2023-02-04 00:43:00 +00:00
|
|
|
];
|
2023-07-15 00:23:14 +00:00
|
|
|
|
|
|
|
secrets.".config/sane-sway/snippets.txt" = ../../../../secrets/common/snippets.txt.bin;
|
2022-06-07 00:35:28 +00:00
|
|
|
};
|
2023-09-05 03:43:32 +00:00
|
|
|
|
|
|
|
# default waybar
|
|
|
|
sane.gui.sway.waybar.top = import ./waybar-top.nix { inherit lib pkgs; };
|
2023-02-04 00:43:00 +00:00
|
|
|
}
|
2022-06-07 00:35:28 +00:00
|
|
|
|
2023-09-01 23:59:21 +00:00
|
|
|
(lib.mkIf cfg.enable {
|
2023-07-08 02:22:43 +00:00
|
|
|
sane.programs.fontconfig.enableFor.system = true;
|
2023-02-04 00:43:00 +00:00
|
|
|
sane.programs.swayApps.enableFor.user.colin = true;
|
2023-07-08 02:22:43 +00:00
|
|
|
|
2023-07-02 09:37:07 +00:00
|
|
|
sane.gui.gtk.enable = lib.mkDefault true;
|
2023-07-02 11:33:01 +00:00
|
|
|
# sane.gui.gtk.gtk-theme = lib.mkDefault "Fluent-Light-compact";
|
|
|
|
sane.gui.gtk.gtk-theme = lib.mkDefault "Tokyonight-Light-B";
|
2023-02-04 00:43:00 +00:00
|
|
|
|
|
|
|
# swap in these lines to use SDDM instead of `services.greetd`.
|
|
|
|
# services.xserver.displayManager.sddm.enable = true;
|
|
|
|
# services.xserver.enable = true;
|
2023-09-01 23:59:21 +00:00
|
|
|
sane.gui.greetd.enable = true;
|
|
|
|
sane.gui.greetd.sway.enable = true; # have greetd launch a sway compositor in which we host a greeter
|
|
|
|
sane.gui.greetd.sway.gtkgreet = lib.mkIf cfg.useGreeter {
|
2023-02-04 00:43:00 +00:00
|
|
|
enable = true;
|
2023-09-02 00:54:05 +00:00
|
|
|
session.name = "sway-on-gtkgreet";
|
|
|
|
session.command = "${pkgs.sway}/bin/sway --debug";
|
2023-02-04 00:43:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
# 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; # ??
|
2023-09-04 11:10:30 +00:00
|
|
|
# emulate pulseaudio for legacy apps (e.g. sxmo-utils)
|
2023-02-04 00:43:00 +00:00
|
|
|
pulse.enable = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
networking.useDHCP = false;
|
|
|
|
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
|
2023-06-29 10:56:56 +00:00
|
|
|
# services.gnome.gnome-settings-daemon.enable = true;
|
2023-02-04 00:43:00 +00:00
|
|
|
# start the components of gsd we need at login
|
2023-06-29 10:56:56 +00:00
|
|
|
# systemd.user.targets."org.gnome.SettingsDaemon.Rfkill".wantedBy = [ "graphical-session.target" ];
|
2023-02-04 00:43:00 +00:00
|
|
|
# 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
|
2023-06-29 10:56:56 +00:00
|
|
|
# systemd.user.targets."gnome-session-initialized".enable = false;
|
2023-02-04 00:43:00 +00:00
|
|
|
# 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.sway = {
|
2023-08-02 08:16:05 +00:00
|
|
|
# provides xdg-desktop-portal-wlr, which exposes on dbus:
|
|
|
|
# - org.freedesktop.impl.portal.ScreenCast
|
|
|
|
# - org.freedesktop.impl.portal.Screenshot
|
2023-02-04 00:43:00 +00:00
|
|
|
enable = true;
|
2023-08-02 08:19:56 +00:00
|
|
|
extraPackages = []; # nixos adds swaylock, swayidle, foot, dmenu by default
|
2023-08-02 07:40:57 +00:00
|
|
|
# "wrapGAppsHook wrapper to execute sway with required environment variables for GTK applications."
|
2023-02-04 00:43:00 +00:00
|
|
|
wrapperFeatures.gtk = true;
|
|
|
|
};
|
2023-08-02 08:16:05 +00:00
|
|
|
# provide 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.Background (@background_iface@)
|
|
|
|
# - org.freedesktop.impl.portal.Lockdown (@lockdown_iface@)
|
|
|
|
# - org.freedesktop.impl.portal.RemoteDesktop (@remotedesktop_iface@)
|
|
|
|
# - org.freedesktop.impl.portal.ScreenCast (@screencast_iface@)
|
|
|
|
# - org.freedesktop.impl.portal.Screenshot (@screenshot_iface@)
|
|
|
|
# - org.freedesktop.impl.portal.Settings (@settings_iface@)
|
|
|
|
# - org.freedesktop.impl.portal.Wallpaper (@wallpaper_iface@)
|
|
|
|
xdg.portal.extraPortals = [
|
|
|
|
(pkgs.xdg-desktop-portal-gtk.override {
|
|
|
|
buildPortalsInGnome = false;
|
|
|
|
})
|
|
|
|
];
|
|
|
|
|
2023-09-05 03:43:32 +00:00
|
|
|
sane.user.fs = {
|
2023-09-04 11:10:30 +00:00
|
|
|
".config/waybar/config".symlink.target =
|
2023-09-05 03:43:32 +00:00
|
|
|
(pkgs.formats.json {}).generate "waybar-config.json" [
|
|
|
|
({ layer = "top"; } // cfg.waybar.top)
|
|
|
|
];
|
2023-02-04 00:43:00 +00:00
|
|
|
|
2023-09-04 11:10:30 +00:00
|
|
|
".config/waybar/style.css".symlink.text =
|
|
|
|
builtins.readFile ./waybar-style.css;
|
2023-09-05 03:43:32 +00:00
|
|
|
|
|
|
|
".config/sway/config" = lib.mkIf cfg.installConfigs {
|
2023-09-05 04:25:58 +00:00
|
|
|
symlink.target = import ./sway-config.nix {
|
|
|
|
inherit pkgs;
|
|
|
|
inherit (cfg) config;
|
|
|
|
};
|
2023-09-05 03:43:32 +00:00
|
|
|
};
|
2023-09-04 11:10:30 +00:00
|
|
|
};
|
2023-02-04 00:43:00 +00:00
|
|
|
})
|
|
|
|
];
|
2022-06-07 00:35:28 +00:00
|
|
|
}
|
|
|
|
|