Compare commits

...

25 commits

Author SHA1 Message Date
e7d2ace6ef Update flake.lock 2026-07-02 19:56:43 +02:00
cb8bf9a66b Migrate lightdm module to new options
The old services.xserver.displayManager are moved out of xserver
2026-07-02 19:56:43 +02:00
d0bc33fbf9 Add networkmanager_dmenu keybinding 2026-07-02 19:56:43 +02:00
bb8559f665 Use greetd and regreet instead of lightdm
LightDM brings problems with setting up the session which leads to
kanshi, swayidle and such services to not get the correct environment
variables like `WAYLAND_DISPLAY`.
2026-07-02 19:56:43 +02:00
ddc717a6c0 Use correct command for shutdown from sway 2026-07-02 19:56:43 +02:00
ea4841403a Set default sway workspace 2026-07-02 19:56:43 +02:00
c7fb1dd4ce Use same broker as os for sway 2026-07-02 19:56:43 +02:00
b6909c162b Add screen dimming and switching off displays on idle 2026-07-02 19:56:43 +02:00
81a4822e2d Reorder pam swaylock rules
This enables entering a password in swaylock without providing
fingerprint.
2026-07-02 19:56:43 +02:00
74581599cd Lowercase app_id of Element 2026-07-02 19:56:43 +02:00
25139ece89 Configure swaylock and swayidle 2026-07-02 19:56:43 +02:00
30207ec5f0 Remove dependency on i3exit
Configure commands directly in sway.
2026-07-02 19:56:43 +02:00
3e3dff15f7 Migrate floating modifiers
`class` is an X11 attribute, sway uses `app_id`.
2026-07-02 19:56:43 +02:00
0458bdcced Add focus wrapping in sway
This enables cycling through tabbed windows endlessly.
2026-07-02 19:56:43 +02:00
591f8f4da7 Use rofi as output chooser for screencast
Slurp does not allow for selecting windows.
2026-07-02 19:56:43 +02:00
c2d242301c Add m15 configuration to kanshi 2026-07-02 19:56:43 +02:00
f46b9ab129 Configure vmVariant for more cores and memory
When testing the config in a vm, have more ressources available.
Otherwise oom errors can occur.
2026-07-02 19:56:43 +02:00
0c605d9684 Set default session to sway 2026-07-02 19:56:43 +02:00
716e54dd12 Add custom lightdm-gtk module for default session
The upstream module does not allow for setting a default session,
although this is possible in lightdm-gtk-greeter for more than two years
now.
2026-07-02 19:56:43 +02:00
531ae9b443 Start solaar minimized on startup 2026-07-02 19:56:43 +02:00
89eff861f3 Enable base and gtk wrapper features for sway 2026-07-02 19:56:43 +02:00
479ccf3fc3 Fix path for nixos wallpaper 2026-07-02 19:56:43 +02:00
cb17bea00c Configure xdg portals for sway 2026-07-02 19:56:43 +02:00
2ff0164960 Add initial sway configuration
Still misses configuration for login screen, lock screen and idle
management.
2026-07-02 19:56:43 +02:00
5fdf5b5d9d Update flake.lock 2026-07-02 19:56:43 +02:00
10 changed files with 551 additions and 17 deletions

24
flake.lock generated
View file

@ -197,11 +197,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1781319724, "lastModified": 1782704057,
"narHash": "sha256-ZGuxexEMo4Xv28KJ0dX/m/PHN4oZIOnxHZpNTyrvx4M=", "narHash": "sha256-G1I1gd32F7mp9LAe1DaZ4ZL7NX5gyiKwdCMwro1Vrck=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "8355f0a16b2dbb06a97959a918af5b239bbe05ae", "rev": "868d0a692de703c2de98fab61968e4e310b7c28e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -261,11 +261,11 @@
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
"lastModified": 1781168557, "lastModified": 1782562157,
"narHash": "sha256-LOnLQ2tpYF9gqIDDr3+j3DbpJJr/QCH6zPRT2GzEUOE=", "narHash": "sha256-a7+T6QSeowynwZ1ZJJbP8T8ntAytvrui8kFGJmIZt2c=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "6358ff76821101c178e3ab4919a62799bfe3652e", "rev": "a9cf7546a938c737b079e738de73934a13de9784",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -338,11 +338,11 @@
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1781074563, "lastModified": 1782723713,
"narHash": "sha256-md8WlXOlfnIeHeOScMTTHFyf2d6iaTwPl2apR5EQ3P4=", "narHash": "sha256-oPXCU/SSUokcGaJREHibG1CBX3+s/W7orDWQOZDsEeQ=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "9ae611a455b90cf061d8f332b977e387bda8e1ca", "rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -354,11 +354,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1781216227, "lastModified": 1782847225,
"narHash": "sha256-9mUW6gNwoN2SWc/l0fW4svPNOulXLl8ijqKyeSOGgJE=", "narHash": "sha256-JC9PjqKYG9ve5U8aDOLQipp3+KLANBHUvGdLZlxzdKI=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a0374025a863d007d98e3297f6aa46cc3141c2f0", "rev": "95ca1e203c0750115fd4a6f17d5a245dfe6b1edd",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -105,6 +105,12 @@
home-manager.extraSpecialArgs = inputs // specialArgs; home-manager.extraSpecialArgs = inputs // specialArgs;
home-manager.users.${username} = import ./users/${username}/home.nix; home-manager.users.${username} = import ./users/${username}/home.nix;
} }
{
virtualisation.vmVariant.virtualisation = {
memorySize = 8192;
cores = 3;
};
}
]; ];
}; };

32
home/kanshi.nix Normal file
View file

@ -0,0 +1,32 @@
{
...
}: let
t27 = "Lenovo Group Limited T27h-30*";
m15 = "Lenovo Group Limited M15*";
in {
services.kanshi = {
enable = true;
settings = [
{ output.criteria = "eDP-1"; output.scale = 1.0; }
{ output.criteria = t27; }
{ output.criteria = m15; }
{ profile.name = "mobile";
profile.outputs = [
{ criteria = "eDP-1"; }
];
}
{ profile.name = "t27" ;
profile.outputs = [
{ criteria = "eDP-1"; position = "152,1440"; }
{ criteria = t27; position = "0,0"; }
];
}
{ profile.name = "m15" ;
profile.outputs = [
{ criteria = "eDP-1"; position = "0,1080"; }
{ criteria = m15; position = "168,0"; }
];
}
];
};
}

271
home/sway.nix Normal file
View file

@ -0,0 +1,271 @@
{
pkgs,
lib,
config,
osConfig,
...
}: let
modifier = "Mod4";
cfg = config.wayland.windowManager.sway;
background = "${pkgs.nixos-artwork.wallpapers.simple-dark-gray-bottom}/share/wallpapers/simple-dark-gray/contents/images/nix-wallpaper-simple-dark-gray_bottom.png";
applications = "(D)iscord, Slac(k), (E)lement, (N)extcloud, (M)usic, (B)luetooth, (V)alent";
exit = "(l)ock, (e)xit, switch_(u)ser, (s)uspend, (h)ibernate, (r)eboot, (Shift+s)hutdown";
in {
home.packages = with pkgs; [
wdisplays
rofi
ydotool
];
wayland.windowManager.sway = {
enable = true;
wrapperFeatures = {
base = true;
gtk = true;
};
systemd.dbusImplementation = osConfig.services.dbus.implementation;
config = {
modifier = modifier;
terminal = lib.getExe pkgs.sakura;
menu = "${lib.getExe pkgs.rofi} -show drun";
defaultWorkspace = "workspace number 1";
fonts = {
names = [ "FontAwesome5Free" "xft:URWGothic-Book" ];
size = 11.0;
};
input = {
"*" = {
xkb_layout = "eu";
};
"type:touchpad" = {
tap = "enabled";
natural_scroll = "enabled";
};
};
output = {
"*" = {
bg = "${background} fill";
};
eDP-1 = {
scale = "1";
};
};
startup = [
{ command = (lib.getExe pkgs.dunst); }
{ command = (lib.getExe pkgs.networkmanagerapplet); }
{ command = "${lib.getExe pkgs.solaar} -w hide"; }
{ command = "${pkgs.ydotool}/bin/ydotoold"; }
];
keybindings = lib.mkOptionDefault {
"${modifier}+Ctrl+${cfg.config.left}" = "move workspace to output left";
"${modifier}+Ctrl+${cfg.config.down}" = "move workspace to output down";
"${modifier}+Ctrl+${cfg.config.up}" = "move workspace to output up";
"${modifier}+Ctrl+${cfg.config.right}" = "move workspace to output right";
"${modifier}+Ctrl+1" = "move container to workspace number 1; workspace number 1";
"${modifier}+Ctrl+2" = "move container to workspace number 2; workspace number 2";
"${modifier}+Ctrl+3" = "move container to workspace number 3; workspace number 3";
"${modifier}+Ctrl+4" = "move container to workspace number 4; workspace number 4";
"${modifier}+Ctrl+5" = "move container to workspace number 5; workspace number 5";
"${modifier}+Ctrl+6" = "move container to workspace number 6; workspace number 6";
"${modifier}+Ctrl+7" = "move container to workspace number 7; workspace number 7";
"${modifier}+Ctrl+8" = "move container to workspace number 8; workspace number 8";
"${modifier}+Ctrl+9" = "move container to workspace number 9; workspace number 9";
"${modifier}+Ctrl+0" = "move container to workspace number 10; workspace number 10";
"${modifier}+Shift+p" = "exec rofi-rbw --action copy";
"XF86MonBrightnessUp" = "exec ${lib.getExe pkgs.brightnessctl} s +10%";
"${modifier}+Tab" = "exec ${lib.getExe pkgs.rofi} -show window";
"XF86MonBrightnessDown" = "exec ${lib.getExe pkgs.brightnessctl} s 10%-";
"XF86AudioRaiseVolume" = "exec ${pkgs.alsa-utils}/bin/amixer -q set Master 5%+ unmute";
"XF86AudioLowerVolume" = "exec ${pkgs.alsa-utils}/bin/amixer -q set Master 5%- unmute";
"XF86AudioMute" = "exec ${pkgs.alsa-utils}/bin/amixer -q set Master toggle";
"XF86AudioMicMute" = "exec ${pkgs.alsa-utils}/bin/amixer -q set Capture toggle";
"${modifier}+c" = "exec ${pkgs.alsa-utils}/bin/amixer -q set Capture toggle";
"XF86AudioPlay" = "exec ${lib.getExe pkgs.playerctl} play-pause";
"${modifier}+ctrl+space" = "exec ${lib.getExe pkgs.playerctl} play-pause";
"${modifier}+z" = "exec ${lib.getExe pkgs.playerctl} volume 5-";
"${modifier}+a" = "exec ${lib.getExe pkgs.playerctl} volume 5+";
"XF86AudioNext" = "exec ${lib.getExe pkgs.playerctl} next";
"XF86AudioPrev" = "exec ${lib.getExe pkgs.playerctl} previous";
"${modifier}+F2" = "exec ${lib.getExe pkgs.firefox}";
"${modifier}+Ctrl+F2" = "exec ${lib.getExe pkgs.rofirefox}";
"${modifier}+Shift+F2" = "exec ${lib.getExe pkgs.firefox} --private-window";
"${modifier}+F3" = "exec nemo";
"${modifier}+F4" = "exec ${lib.getExe pkgs.thunderbird}";
"${modifier}+Ctrl+w" = "exec ${lib.getExe pkgs.networkmanager_dmenu}";
"${modifier}+Shift+d" = ''mode "${applications}"'';
"${modifier}+Escape" = ''mode "${exit}"'';
};
modes = {
resize = {
"${cfg.config.left}" = "resize shrink width 10 px";
"${cfg.config.down}" = "resize grow height 10 px";
"${cfg.config.up}" = "resize shrink height 10 px";
"${cfg.config.right}" = "resize grow width 10 px";
"Left" = "resize shrink width 10 px";
"Down" = "resize grow height 10 px";
"Up" = "resize shrink height 10 px";
"Right" = "resize grow width 10 px";
"Escape" = "mode default";
"Return" = "mode default";
};
"${applications}" = {
"d" = "exec flatpak run com.discordapp.Discord";
"k" = "exec flatpak run com.slack.Slack";
"e" = "exec element-desktop --password-store=gnome-libsecret";
"Shift+e" = "exec element-desktop --password-store=gnome-libsecret --profile=JuliusFreudenberger";
"n" = "exec nextcloud";
"m" = "exec flatpak run com.spotify.Client";
"b" = "exec blueman";
"v" = "exec valent";
"Escape" = "mode default";
"Return" = "mode default";
};
"${exit}" = {
"l" = "exec ${pkgs.systemd}/bin/loginctl lock-session, mode default";
"s" = "exec ${pkgs.systemd}/bin/systemctl suspend, mode default";
"u" = "exec ${pkgs.lightdm}/bin/dm-tool lock, mode default";
"e" = "exec ${pkgs.sway}/bin/swaymsg exit, mode default";
"h" = "exec ${pkgs.systemd}/bin/systemctl hibernate, mode default";
"r" = "exec ${pkgs.systemd}/bin/systemctl reboot, mode default";
"Shift+s" = "exec ${pkgs.systemd}/bin/systemctl poweroff, mode default";
"Escape" = "mode default";
"Return" = "mode default";
};
};
assigns = {
"6" = [{ app_id = "thunderbird"; }];
"5" = [{ app_id = "^element$|^com.slack.Slack$"; }];
};
floating.criteria = [
{ title = "MuseScore: Play Panel"; }
{ app_id = "org.pulseaudio.pavucontrol"; }
{ app_id = "system-config-printer";}
{ app_id = "mate-calc"; }
{ app_id = ".blueman-manager-wrapped"; }
{ app_id = "nm-connection-editor"; }
{ app_id = "Zotero"; window_role = "Toplevel"; }
{ app_id = "com.nextcloud.desktopclient.nextcloud"; }
];
colors = {
background = "#2B2C2B";
focused = {
background = "#556064";
border = "#556064";
childBorder = "#556064";
text = "#80FFF9";
indicator = "#FDF6E3";
};
focusedInactive = {
background = "#2F3D44";
border = "#2F3D44";
childBorder = "#2F3D44";
text = "#1ABC9C";
indicator = "#454948";
};
unfocused = {
background = "#2F3D44";
border = "#2F3D44";
childBorder = "#2F3D44";
text = "#1ABC9C";
indicator = "#454948";
};
urgent = {
background = "#FDF6E3";
border = "#CB4B16";
childBorder = "#CB4B16";
text = "#1ABC9C";
indicator = "#268BD2";
};
placeholder = {
background = "#0c0c0c";
border = "#000000";
childBorder = "#000000";
text = "#ffffff";
indicator = "#000000";
};
};
bars = [
{
mode = "dock";
hiddenState = "hide";
position = "bottom";
workspaceButtons = true;
workspaceNumbers = true;
statusCommand = "${lib.getExe pkgs.i3blocks} -c ~/.config/i3/i3blocks.conf";
fonts = {
names = [ "xft:URWGothic-Book" ];
size = 11.0;
};
extraConfig = ''
icon_theme Arc
'';
colors = {
background = "#222D31";
statusline = "#F9FAF9";
separator = "#454947";
focusedWorkspace = {
border = "#F9FAF9";
background = "#16a085";
text = "#292F34";
};
activeWorkspace = {
border = "#595B5B";
background = "#353836";
text = "#FDF6E3";
};
inactiveWorkspace = {
border = "#595B5B";
background = "#222D31";
text = "#EEE8D5";
};
urgentWorkspace = {
border = "#16a085";
background = "#FDF6E3";
text = "#E5201D";
};
bindingMode = {
border = "#16a085";
background = "#2C2C2C";
text = "#F9FAF9";
};
};
}
];
};
extraConfig = ''
assign [class = "^discord$"] 5
focus_wrapping yes
'';
};
programs.swaylock = {
enable = true;
settings = {
image = background;
};
};
services.swayidle = let
dimDuration = 15;
dimScreen = "${lib.getExe pkgs.chayang} -d ${toString dimDuration}";
swaylock = "${lib.getExe pkgs.swaylock} -f";
switchOutput = "${pkgs.sway}/bin/swaymsg 'output * power'";
in {
enable = true;
events = {
before-sleep = swaylock;
lock = swaylock;
after-resume = "${switchOutput} on";
};
timeouts = [
{ timeout = 300; command = "${dimScreen} && ${switchOutput} off && ${swaylock}"; resumeCommand = "${switchOutput} on"; }
];
};
services.wlsunset = {
enable = true;
latitude = osConfig.location.latitude;
longitude = osConfig.location.longitude;
};
}

View file

@ -13,10 +13,12 @@
../../modules/network-client.nix ../../modules/network-client.nix
../../modules/locale.nix ../../modules/locale.nix
../../modules/timezone-imperatively.nix ../../modules/timezone-imperatively.nix
../../modules/lightdm-gtk.nix
../../modules/boot-login.nix ../../modules/boot-login.nix
../../modules/fonts.nix ../../modules/fonts.nix
../../modules/cli-essentials.nix ../../modules/cli-essentials.nix
../../modules/i3.nix ../../modules/i3.nix
../../modules/sway.nix
../../modules/fingerprint.nix ../../modules/fingerprint.nix
../../modules/logitech.nix ../../modules/logitech.nix
../../modules/connectivity.nix ../../modules/connectivity.nix

View file

@ -1,5 +1,6 @@
{ {
pkgs, pkgs,
lib,
... ...
}: { }: {
boot = { boot = {
@ -12,11 +13,13 @@
}; };
services = { services = {
displayManager.defaultSession = "sway";
xserver.displayManager = { xserver.displayManager = {
lightdm = { lightdm = {
enable = true; enable = false;
greeters.gtk = { greeters.gtk.enable = false;
enable = true; greeters.gtk-custom = {
enable = false;
theme = { theme = {
name = "Adwaita-dark"; name = "Adwaita-dark";
}; };
@ -29,4 +32,22 @@
}; };
}; };
services.greetd = {
enable = true;
settings = {
skip_selection = true;
};
};
programs.regreet = {
enable = true;
theme = {
name = "Adwaita-dark";
};
iconTheme = {
name = "Arc";
package = pkgs.arc-icon-theme;
};
};
} }

View file

@ -1,7 +1,7 @@
{pkgs, ...}: { {pkgs, lib, ...}: {
# i3 related options # i3 related options
environment.pathsToLink = ["/libexec"]; # links /libexec from derivations to /run/current-system/sw environment.pathsToLink = ["/libexec"]; # links /libexec from derivations to /run/current-system/sw
services.displayManager.defaultSession = "none+i3"; services.displayManager.defaultSession = lib.mkDefault "none+i3";
services.xserver = { services.xserver = {
enable = true; enable = true;

167
modules/lightdm-gtk.nix Normal file
View file

@ -0,0 +1,167 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
dmcfg = config.services.displayManager;
ldmcfg = xcfg.displayManager.lightdm;
xcfg = config.services.xserver;
cfg = ldmcfg.greeters.gtk-custom;
inherit (pkgs) writeText;
theme = cfg.theme.package;
icons = cfg.iconTheme.package;
cursors = cfg.cursorTheme.package;
gtkGreeterConf = writeText "lightdm-gtk-greeter.conf" ''
[greeter]
theme-name = ${cfg.theme.name}
icon-theme-name = ${cfg.iconTheme.name}
cursor-theme-name = ${cfg.cursorTheme.name}
cursor-theme-size = ${toString cfg.cursorTheme.size}
background = ${ldmcfg.background}
${optionalString (dmcfg.defaultSession != null) "default-session = ${dmcfg.defaultSession}"}
${optionalString (cfg.clock-format != null) "clock-format = ${cfg.clock-format}"}
${optionalString (cfg.indicators != null) "indicators = ${concatStringsSep ";" cfg.indicators}"}
${optionalString (xcfg.dpi != null) "xft-dpi=${toString xcfg.dpi}"}
${cfg.extraConfig}
'';
in
{
options = {
services.xserver.displayManager.lightdm.greeters.gtk-custom = {
enable = mkOption {
type = types.bool;
default = true;
description = ''
Whether to enable lightdm-gtk-greeter as the lightdm greeter.
'';
};
theme = {
package = mkPackageOption pkgs "gnome-themes-extra" { };
name = mkOption {
type = types.str;
default = "Adwaita";
description = ''
Name of the theme to use for the lightdm-gtk-greeter.
'';
};
};
iconTheme = {
package = mkPackageOption pkgs "adwaita-icon-theme" { };
name = mkOption {
type = types.str;
default = "Adwaita";
description = ''
Name of the icon theme to use for the lightdm-gtk-greeter.
'';
};
};
cursorTheme = {
package = mkPackageOption pkgs "adwaita-icon-theme" { };
name = mkOption {
type = types.str;
default = "Adwaita";
description = ''
Name of the cursor theme to use for the lightdm-gtk-greeter.
'';
};
size = mkOption {
type = types.int;
default = 16;
description = ''
Size of the cursor theme to use for the lightdm-gtk-greeter.
'';
};
};
clock-format = mkOption {
type = types.nullOr types.str;
default = null;
example = "%F";
description = ''
Clock format string (as expected by strftime, e.g. "%H:%M")
to use with the lightdm gtk greeter panel.
If set to null the default clock format is used.
'';
};
indicators = mkOption {
type = types.nullOr (types.listOf types.str);
default = null;
example = [
"~host"
"~spacer"
"~clock"
"~spacer"
"~session"
"~language"
"~a11y"
"~power"
];
description = ''
List of allowed indicator modules to use for the lightdm gtk
greeter panel.
Built-in indicators include "~a11y", "~language", "~session",
"~power", "~clock", "~host", "~spacer". Unity indicators can be
represented by short name (e.g. "sound", "power"), service file name,
or absolute path.
If set to null the default indicators are used.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Extra configuration that should be put in the lightdm-gtk-greeter.conf
configuration file.
'';
};
};
};
config = mkIf (ldmcfg.enable && cfg.enable) {
services.xserver.displayManager.lightdm.greeter = mkDefault {
package = pkgs.lightdm-gtk-greeter.xgreeters;
name = "lightdm-gtk-greeter";
};
environment.systemPackages = [
cursors
icons
theme
];
environment.etc."lightdm/lightdm-gtk-greeter.conf".source = gtkGreeterConf;
};
}

33
modules/sway.nix Normal file
View file

@ -0,0 +1,33 @@
{
pkgs,
lib,
...
}: {
services.displayManager.defaultSession = lib.mkDefault "sway";
programs.sway = {
enable = true;
wrapperFeatures = {
base = true;
gtk = true;
};
};
xdg.portal = {
enable = true;
wlr = {
enable = true;
settings = {
screencast = {
chooser_type = "dmenu";
chooser_cmd = "${lib.getExe pkgs.rofi} -dmenu -p 'Select a source to share:'";
};
};
};
extraPortals = with pkgs; [
xdg-desktop-portal-wlr
xdg-desktop-portal-gtk
];
};
security.pam.services.swaylock.rules.auth.unix.order = 11200;
}

View file

@ -7,6 +7,8 @@
../../home/neovim ../../home/neovim
../../home/gtk ../../home/gtk
../../home/xdg ../../home/xdg
../../home/sway.nix
../../home/kanshi.nix
../../home/direnv ../../home/direnv
]; ];