Files
nixfiles/lyrathorpe/swaywm.nix
T
Emma Thorpe b04391809e feat(sway): port keybindings, modes and tweaks from dotfiles
Adapted from emmaisadev/dotfiles (sway/config.d) into the Nix config:

- Screenshots to swappy: Print = drag a region, Shift+Print = focused
  window (a writeShellScript reusing the grimshot.sh tree/jq logic).
  Replaces the old plain full-screen grim->file.
- Workspace cycle Mod+z / Mod+x (prev/next).
- Media keys (playerctl) and mic mute (wpctl source).
- Re-home `focus mode_toggle` onto Mod+Alt+space (Mod+Space is the
  launcher now).
- Clipboard history: services.clipman stores copies; Mod+c picks one
  through a Catppuccin-themed fuzzel (programs.fuzzel).
- Binding modes: a layout submenu (Mod+y -> s/w/e, which also restores
  split-toggle that Mod+e gave up to nemo) and a power menu
  (Mod+Shift+x -> lock/exit/sleep/reboot/shutdown). Mod+l still locks
  immediately.
- Touchpad tap + natural scroll (laptops; inert on desktop).
- Solid Catppuccin base as the wallpaper (output * bg, no image).
- foot: term=xterm-256color and scrollback 100000 (colours unchanged).
- swaywm.nix: add slurp/swappy/jq/playerctl to the session packages.

Skipped from the dotfiles: named workspaces + app auto-assign, the foot
--server/footclient setup, and pactl/MX-Master/lxqt device-specific bits.
All in the shared files, so every Sway host gets it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 20:49:36 +01:00

162 lines
5.5 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
cfg = config.features.swayDesktop;
# Catppuccin Mocha (shared with the Sway desktop, see lyrathorpe/home/sway.nix).
ctp = import ./catppuccin-mocha.nix;
in
{
options = {
features.swayDesktop.enable = lib.mkEnableOption "Enable Sway Desktop";
};
config = lib.mkIf cfg.enable {
programs.sway = {
enable = true;
wrapperFeatures.gtk = true;
extraSessionCommands = ''
# QT
export QT_QPA_PLATFORM="wayland;xcb"
export QT_QPA_PLATFORMTHEME=qt5ct
# SDL
export SDL_VIDEODRIVER=wayland
# Java
export _JAVA_AWT_WM_NONREPARENTING=1
# Misc
export CLUTTER_BACKEND=wayland
export WINIT_UNIX_BACKEND=wayland
export MOZ_ENABLE_WAYLAND=1
'';
# Core Wayland utilities. The lock screen, idle daemon, status bar and
# notification daemon are configured per-user in home/sway.nix.
extraPackages = with pkgs; [
brightnessctl
foot
grim
slurp # region selection for screenshots
swappy # screenshot annotation/save
jq # used by the focused-window screenshot bind
playerctl # MPRIS media keys
sway-launcher-desktop
pavucontrol
];
};
fonts.packages = with pkgs; [
noto-fonts
noto-fonts-color-emoji
font-awesome
];
# Wayland login screen (replaces console/getty login on every Sway host).
# greetd runs ReGreet inside the cage kiosk compositor; the Sway session is
# offered automatically because programs.sway registers itself via
# services.displayManager.sessionPackages. Hosts that turn off
# features.swayDesktop (e.g. EDaaS) keep plain TTY login.
programs.regreet.enable = true;
# Theme the greeter to match the Sway desktop (Catppuccin Mocha). ReGreet is
# GTK; recolour via CSS (covering both libadwaita named colours and plain
# GTK node selectors) and use the same Noto Sans as the bar/notifications.
programs.regreet.font = {
name = "Noto Sans";
package = pkgs.noto-fonts;
size = 16;
};
programs.regreet.extraCss = ''
/* GTK4 Adwaita legacy names (what plain GTK4 actually references). */
@define-color theme_bg_color #${ctp.base};
@define-color theme_fg_color #${ctp.text};
@define-color theme_base_color #${ctp.mantle};
@define-color theme_text_color #${ctp.text};
@define-color theme_selected_bg_color #${ctp.blue};
@define-color theme_selected_fg_color #${ctp.base};
@define-color insensitive_bg_color #${ctp.mantle};
@define-color insensitive_fg_color #${ctp.overlay0};
@define-color borders #${ctp.surface1};
@define-color warning_color #${ctp.peach};
@define-color error_color #${ctp.red};
@define-color success_color #${ctp.green};
/* libadwaita names (inert on plain GTK4, kept for forward-compat). */
@define-color window_bg_color #${ctp.base};
@define-color window_fg_color #${ctp.text};
@define-color view_bg_color #${ctp.mantle};
@define-color view_fg_color #${ctp.text};
@define-color card_bg_color #${ctp.surface0};
@define-color card_fg_color #${ctp.text};
@define-color accent_bg_color #${ctp.blue};
@define-color accent_fg_color #${ctp.base};
@define-color accent_color #${ctp.blue};
@define-color destructive_bg_color #${ctp.red};
@define-color destructive_fg_color #${ctp.base};
window {
background-color: #${ctp.base};
color: #${ctp.text};
}
label {
color: #${ctp.text};
}
entry {
background-color: #${ctp.surface0};
color: #${ctp.text};
border: 1px solid #${ctp.surface1};
}
entry:focus-within {
border-color: #${ctp.blue};
}
button,
combobox button {
background-color: #${ctp.surface0};
color: #${ctp.text};
border: 1px solid #${ctp.surface1};
}
button:hover {
background-color: #${ctp.surface1};
}
button:active,
button:checked {
background-color: #${ctp.blue};
color: #${ctp.base};
}
'';
# cage reads the XKB_* environment at startup, so force the greeter onto the
# same Dvorak layout as the Sway session (home/sway.nix) -- otherwise the
# password field would be QWERTY. Dvorak is the "us" layout's variant, NOT a
# layout of its own: "dvorak" alone has no symbols/ file, so the keymap
# fails to compile and the greeter ends up with no keyboard at all (the
# greeter has no fallback, unlike a running Sway session). This overrides the
# greetd command regreet sets with mkDefault.
services.greetd.settings.default_session.command =
let
greeter = pkgs.writeShellScript "regreet-cage" ''
export XKB_DEFAULT_LAYOUT=us
export XKB_DEFAULT_VARIANT=dvorak
# ReGreet is plain GTK4 (no libadwaita); force the dark Adwaita variant
# so the extraCss accents sit on a dark base instead of light Adwaita.
export GTK_THEME=Adwaita:dark
exec ${pkgs.dbus}/bin/dbus-run-session ${lib.getExe pkgs.cage} -s -- ${lib.getExe config.programs.regreet.package}
'';
in
"${greeter}";
# Desktop portals: enables screen sharing (wlroots) and native file pickers
# for Wayland apps such as Element and Firefox.
xdg.portal = {
enable = true;
wlr.enable = true;
extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
config.common.default = "*";
};
};
}