2023-08-04 13:08:58 +02:00
|
|
|
{ home-manager, lib, pkgs, ... }: {
|
2023-08-01 15:35:09 +02:00
|
|
|
# https://nixos.wiki/wiki/Sway
|
|
|
|
|
2023-08-16 02:31:35 +02:00
|
|
|
# Polkit is required to configure sway with home-manager
|
2023-08-04 13:08:58 +02:00
|
|
|
security.polkit.enable = true;
|
|
|
|
|
2023-08-01 15:35:09 +02:00
|
|
|
home-manager.users.caspervk = {
|
|
|
|
wayland.windowManager.sway = {
|
|
|
|
enable = true;
|
|
|
|
config = {
|
|
|
|
input = {
|
2023-08-12 15:49:21 +02:00
|
|
|
"type:keyboard" = {
|
2023-08-01 15:35:09 +02:00
|
|
|
xkb_layout = "us";
|
|
|
|
xkb_variant = "altgr-intl";
|
2023-08-04 13:08:58 +02:00
|
|
|
repeat_delay = "250";
|
2023-08-12 15:49:21 +02:00
|
|
|
};
|
|
|
|
"type:touchpad" = {
|
2023-08-01 15:35:09 +02:00
|
|
|
tap = "enabled";
|
|
|
|
natural_scroll = "enable";
|
2023-08-01 16:55:53 +02:00
|
|
|
dwt = "disabled"; # don't disable-while-typing
|
2023-08-01 15:35:09 +02:00
|
|
|
};
|
2023-08-12 18:44:46 +02:00
|
|
|
"type:pointer" = {
|
2023-08-16 02:31:35 +02:00
|
|
|
accel_profile = "flat";
|
2023-08-20 21:06:33 +02:00
|
|
|
pointer_accel = "0.4"; # pointer SPEED, not acceleration
|
2023-08-14 01:46:41 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
output = {
|
|
|
|
"*" = {
|
2023-08-26 19:04:17 +02:00
|
|
|
background = "${./img/background.png} fill";
|
2023-08-12 18:44:46 +02:00
|
|
|
};
|
2023-08-01 15:35:09 +02:00
|
|
|
};
|
2023-08-01 16:55:53 +02:00
|
|
|
modifier = "Mod4"; # super
|
2023-08-04 13:08:58 +02:00
|
|
|
keybindings = lib.mkOptionDefault {
|
2023-08-17 01:51:37 +02:00
|
|
|
# Menu
|
2023-08-23 23:22:12 +02:00
|
|
|
"Mod4+backspace" = "exec wofi";
|
|
|
|
"Mod4+p" = "exec clipman pick -t wofi";
|
2023-08-17 01:51:37 +02:00
|
|
|
|
|
|
|
# Lock
|
2023-08-04 13:08:58 +02:00
|
|
|
"Mod4+Escape" = "exec loginctl lock-session";
|
|
|
|
|
2023-08-26 16:01:21 +02:00
|
|
|
# Screenshot
|
|
|
|
"Print" = "exec grimshot copy output";
|
|
|
|
"Print+Shift" = "exec grimshot copy area";
|
|
|
|
"Print+Control" = "exec grimshot copy window";
|
|
|
|
"Print+Alt" = "exec grimshot copy active";
|
|
|
|
|
2023-08-17 01:51:37 +02:00
|
|
|
# Mod+a focuses parent, but there is no way (by default) to focus child
|
|
|
|
"Mod4+x" = "focus child";
|
|
|
|
|
2023-08-12 18:44:46 +02:00
|
|
|
# Move workspace between outputs
|
|
|
|
"Mod4+Control+Shift+h" = "move workspace to output left";
|
|
|
|
"Mod4+Control+Shift+l" = "move workspace to output right";
|
|
|
|
|
2023-08-04 13:08:58 +02:00
|
|
|
# Brightness
|
2023-08-27 04:21:25 +02:00
|
|
|
"XF86MonBrightnessUp" = "exec brightnessctl set 5%+";
|
|
|
|
"XF86MonBrightnessDown" = "exec brightnessctl set 5%-";
|
2023-08-04 13:08:58 +02:00
|
|
|
|
|
|
|
# Volume
|
2023-08-20 16:22:36 +02:00
|
|
|
"XF86AudioRaiseVolume" = "exec 'wpctl set-volume --limit=1.5 @DEFAULT_AUDIO_SINK@ 2%+'";
|
|
|
|
"XF86AudioLowerVolume" = "exec 'wpctl set-volume --limit=1.5 @DEFAULT_AUDIO_SINK@ 2%-'";
|
|
|
|
"XF86AudioMute" = "exec 'wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle'";
|
2023-08-13 19:29:18 +02:00
|
|
|
|
|
|
|
# Media
|
|
|
|
"XF86AudioPlay" = "exec 'playerctl play-pause'";
|
|
|
|
"XF86AudioNext" = "exec 'playerctl next'";
|
|
|
|
"XF86AudioPrev" = "exec 'playerctl previous'";
|
2023-08-04 13:08:58 +02:00
|
|
|
};
|
2023-08-26 19:04:17 +02:00
|
|
|
assigns = {
|
2023-08-26 19:28:04 +02:00
|
|
|
"8" = [{ class = "WebCord"; }];
|
2023-08-26 19:04:17 +02:00
|
|
|
"9" = [{ class = "Spotify"; }];
|
|
|
|
};
|
2023-08-26 19:28:04 +02:00
|
|
|
floating = {
|
|
|
|
criteria = [
|
|
|
|
{ app_id = "org.keepassxc.KeePassXC"; }
|
2023-08-27 18:23:18 +02:00
|
|
|
{ app_id = "pavucontrol"; }
|
|
|
|
{ app_id = "wdisplays"; }
|
2023-08-26 19:28:04 +02:00
|
|
|
];
|
|
|
|
};
|
2023-08-14 01:46:41 +02:00
|
|
|
focus = {
|
2023-08-25 01:02:54 +02:00
|
|
|
# Don't automatically focus hovered windows
|
2023-10-10 12:53:26 +02:00
|
|
|
followMouse = false;
|
|
|
|
# Don't automatically move the mouse cursor when switching outputs
|
|
|
|
mouseWarping = false;
|
2023-08-14 01:46:41 +02:00
|
|
|
};
|
2023-08-21 00:30:10 +02:00
|
|
|
gaps = {
|
2023-08-27 18:23:18 +02:00
|
|
|
# Disable borders on workspaces with a single container
|
2023-08-21 00:30:10 +02:00
|
|
|
smartBorders = "no_gaps";
|
|
|
|
};
|
|
|
|
window = {
|
2023-08-25 01:02:54 +02:00
|
|
|
# Don't show unnecessary window titlebars, e.g. when there is only
|
|
|
|
# one window on screen. The titlebars will still be shown if tabbing
|
|
|
|
# or stacking windows.
|
2023-08-21 00:30:10 +02:00
|
|
|
titlebar = false;
|
|
|
|
};
|
|
|
|
colors = {
|
|
|
|
focused = {
|
|
|
|
background = "#31447f";
|
|
|
|
border = "#31447f";
|
|
|
|
childBorder = "#31447f";
|
|
|
|
indicator = "#3bacf0";
|
|
|
|
text = "#ffffff";
|
|
|
|
};
|
|
|
|
};
|
2023-08-01 15:35:09 +02:00
|
|
|
terminal = "alacritty";
|
2023-08-04 13:08:58 +02:00
|
|
|
bars = [{ command = "${pkgs.waybar}/bin/waybar"; }];
|
2023-08-01 15:35:09 +02:00
|
|
|
};
|
2023-08-25 01:02:54 +02:00
|
|
|
|
|
|
|
# Execute sway with required environment variables for GTK applications
|
|
|
|
wrapperFeatures = {
|
|
|
|
gtk = true;
|
|
|
|
};
|
2023-08-01 15:35:09 +02:00
|
|
|
};
|
2023-08-04 13:08:58 +02:00
|
|
|
|
2023-08-16 02:31:35 +02:00
|
|
|
# https://github.com/Alexays/Waybar/wiki/Configuration
|
|
|
|
# https://github.com/Alexays/Waybar/blob/master/resources/config
|
2023-08-04 13:08:58 +02:00
|
|
|
programs.waybar =
|
|
|
|
let
|
2023-08-25 01:02:54 +02:00
|
|
|
# It isn't possible to extend the default Waybar config in Home
|
|
|
|
# Manager; as soon as any setting is defined it overwrites the entire
|
|
|
|
# default configuration. To combat this, we parse the default config
|
|
|
|
# into Nix and merge it with our changes.
|
2023-08-04 13:08:58 +02:00
|
|
|
mkDefaultConfig = pkgs.stdenv.mkDerivation {
|
|
|
|
name = "waybarDefaultConfig";
|
|
|
|
src = "${pkgs.waybar}/etc/xdg/waybar";
|
|
|
|
installPhase = ''
|
2023-08-16 02:31:35 +02:00
|
|
|
# JSON isn't valid if it contains comments
|
2023-08-04 13:08:58 +02:00
|
|
|
sed 's#//.*##' config | ${pkgs.jq}/bin/jq > $out
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
defaultConfig = builtins.fromJSON (lib.readFile "${mkDefaultConfig}");
|
|
|
|
in
|
|
|
|
{
|
|
|
|
enable = true;
|
|
|
|
settings = {
|
|
|
|
bar = lib.mkMerge [
|
|
|
|
defaultConfig
|
|
|
|
{
|
2023-08-26 22:00:40 +02:00
|
|
|
modules-right = lib.mkForce [ "tray" "pulseaudio" "backlight" "network" "battery" "clock" ];
|
2023-08-04 13:38:13 +02:00
|
|
|
battery = {
|
|
|
|
states = lib.mkForce {
|
|
|
|
warning = 15;
|
|
|
|
critical = 5;
|
|
|
|
};
|
|
|
|
};
|
2023-08-04 13:08:58 +02:00
|
|
|
clock = {
|
|
|
|
interval = 5;
|
|
|
|
locale = "da_DK.UTF-8";
|
|
|
|
format = "{:%a %e. %b %H:%M}";
|
|
|
|
calendar = {
|
|
|
|
mode = "year";
|
|
|
|
mode-mon-col = 6;
|
|
|
|
weeks-pos = "left";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
];
|
|
|
|
};
|
2023-08-20 21:06:33 +02:00
|
|
|
# https://github.com/Alexays/Waybar/wiki/Styling
|
|
|
|
# https://github.com/Alexays/Waybar/blob/master/resources/style.css
|
|
|
|
style = ''
|
|
|
|
window#waybar {
|
|
|
|
color: white;
|
|
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
|
|
border-bottom: 1px solid rgba(0, 0, 0, 0.5);
|
|
|
|
transition-duration: 0s;
|
|
|
|
}
|
|
|
|
#workspaces button {
|
|
|
|
color: white;
|
|
|
|
box-shadow: inset 0 3px transparent;
|
|
|
|
border: none;
|
|
|
|
border-radius: 0;
|
|
|
|
}
|
|
|
|
#workspaces button.focused {
|
2023-08-26 22:00:40 +02:00
|
|
|
box-shadow: inset 0 3px #FF9E3B; /* kanagawa roninYellow */
|
2023-08-20 21:06:33 +02:00
|
|
|
background-color: transparent;
|
|
|
|
}
|
|
|
|
#workspaces button:hover {
|
|
|
|
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
|
|
|
|
background: rgba(0, 0, 0, 0.25);
|
|
|
|
text-shadow: inherit;
|
|
|
|
}
|
|
|
|
#mode {
|
|
|
|
background-color: rgba(255, 255, 255, 0.4);
|
|
|
|
border: none;
|
|
|
|
}
|
2023-08-26 22:00:40 +02:00
|
|
|
#tray, #pulseaudio, #backlight, #network, #battery, #clock {
|
2023-08-20 21:06:33 +02:00
|
|
|
background-color: transparent;
|
|
|
|
padding: 0 10px;
|
|
|
|
}
|
2023-08-26 22:00:40 +02:00
|
|
|
#battery.warning:not(.charging) {
|
|
|
|
color: #FF9E3B; /* kanagawa roninYellow */
|
|
|
|
}
|
|
|
|
#battery.critical:not(.charging) {
|
|
|
|
color: #E82424; /* kanagawa samuraiRed */
|
|
|
|
}
|
|
|
|
#network.disconnected {
|
|
|
|
color: #E82424; /* kanagawa samuraiRed */
|
|
|
|
}
|
2023-08-20 21:06:33 +02:00
|
|
|
'';
|
2023-08-04 13:08:58 +02:00
|
|
|
};
|
|
|
|
|
2023-08-16 02:31:35 +02:00
|
|
|
# https://github.com/swaywm/swaylock
|
2023-08-14 01:46:41 +02:00
|
|
|
programs.swaylock = {
|
|
|
|
enable = true;
|
|
|
|
settings = {
|
|
|
|
image = "${./img/lockscreen.png}";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2023-08-16 02:31:35 +02:00
|
|
|
# https://github.com/swaywm/swayidle
|
2023-08-04 13:08:58 +02:00
|
|
|
services.swayidle =
|
|
|
|
let
|
2023-08-14 01:46:41 +02:00
|
|
|
lock = "${pkgs.swaylock}/bin/swaylock --daemonize";
|
2023-08-26 21:25:38 +02:00
|
|
|
outputOff = "${pkgs.sway}/bin/swaymsg 'output * power off'";
|
|
|
|
outputOn = "${pkgs.sway}/bin/swaymsg 'output * power on'";
|
|
|
|
suspend = "${pkgs.systemd}/bin/systemctl suspend";
|
2023-08-04 13:08:58 +02:00
|
|
|
in
|
|
|
|
{
|
|
|
|
enable = true;
|
|
|
|
events = [
|
|
|
|
{ event = "lock"; command = lock; }
|
|
|
|
{ event = "before-sleep"; command = lock; }
|
|
|
|
];
|
|
|
|
timeouts = [
|
2023-08-26 21:25:38 +02:00
|
|
|
{ timeout = 900; command = outputOff; resumeCommand = outputOn; }
|
|
|
|
{ timeout = 3600; command = suspend; }
|
2023-08-04 13:08:58 +02:00
|
|
|
];
|
|
|
|
};
|
2023-08-01 15:35:09 +02:00
|
|
|
};
|
|
|
|
|
2023-08-25 01:02:54 +02:00
|
|
|
# Don't shut down the system when the power key is pressed
|
|
|
|
services.logind.extraConfig = ''
|
|
|
|
HandlePowerKey=ignore
|
|
|
|
'';
|
|
|
|
|
2023-08-16 02:31:35 +02:00
|
|
|
# Connect swaylock to PAM. If this isn't done, swaylock needs the suid flag
|
|
|
|
security.pam.services.swaylock.text = ''
|
|
|
|
auth include login
|
|
|
|
'';
|
|
|
|
|
|
|
|
# https://nixos.wiki/wiki/Fonts
|
|
|
|
fonts = {
|
|
|
|
fonts = with pkgs; [
|
|
|
|
# Nerd Fonts patches glyph icons, such as from Font Awesome, into existing fonts
|
|
|
|
(nerdfonts.override { fonts = [ "JetBrainsMono" ]; })
|
|
|
|
font-awesome # waybar uses Font Awesome icons directly
|
|
|
|
];
|
|
|
|
fontDir.enable = true; # TODO?
|
|
|
|
enableDefaultFonts = true;
|
|
|
|
fontconfig.defaultFonts = {
|
|
|
|
monospace = [ "JetBrainsMonoNL Nerd Font" ]; # NL = NoLigatures
|
|
|
|
};
|
|
|
|
};
|
2023-08-01 15:35:09 +02:00
|
|
|
|
2023-08-16 02:31:35 +02:00
|
|
|
environment.systemPackages = with pkgs; [
|
2023-08-20 16:22:08 +02:00
|
|
|
brightnessctl
|
2023-08-16 02:31:35 +02:00
|
|
|
gnome3.adwaita-icon-theme # cursor TODO
|
|
|
|
pavucontrol # PulseAudio Volume Control gui
|
|
|
|
playerctl # media control cli for keybinds
|
2023-08-26 16:01:21 +02:00
|
|
|
slurp # wayland region selector
|
|
|
|
sway-contrib.grimshot # screenshot
|
2023-08-16 02:31:35 +02:00
|
|
|
wdisplays # gui for ad-hoc display configuration
|
|
|
|
wl-clipboard # wl-copy/wl-paste commands
|
|
|
|
wl-mirror # screen mirroing; wl-mirror (slurp -f%o -o)
|
2023-08-17 01:51:37 +02:00
|
|
|
wtype # xdotool for wayland
|
2023-08-16 02:31:35 +02:00
|
|
|
];
|
2023-08-01 15:35:09 +02:00
|
|
|
|
2023-08-25 01:02:54 +02:00
|
|
|
# xdg portal allows applications secure access to resources outside their
|
|
|
|
# sandbox. In particular, this allows screen sharing on Wayland via PipeWire
|
|
|
|
# and file open/save dialogues in Firefox.
|
2023-08-21 22:18:07 +02:00
|
|
|
# https://wiki.archlinux.org/title/XDG_Desktop_Portal
|
|
|
|
# https://mozilla.github.io/webrtc-landing/gum_test.html
|
|
|
|
xdg.portal = {
|
|
|
|
enable = true;
|
|
|
|
wlr.enable = true;
|
|
|
|
};
|
2023-08-01 16:49:22 +02:00
|
|
|
|
2023-08-25 01:02:54 +02:00
|
|
|
# TODO
|
2023-08-01 16:49:22 +02:00
|
|
|
hardware.opengl = {
|
|
|
|
enable = true;
|
2023-08-01 16:55:53 +02:00
|
|
|
extraPackages = with pkgs; [ intel-media-driver ];
|
2023-08-01 16:49:22 +02:00
|
|
|
};
|
2023-08-01 15:35:09 +02:00
|
|
|
}
|