2026-03-07 16:39:21 -05:00

426 lines
14 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
patchScriptBin =
{
filename,
contents,
path ? [ ],
}:
((pkgs.writeScriptBin filename contents).overrideAttrs (old: {
buildCommand = "${old.buildCommand}\n patchShebangs $out";
postBuild = ''
wrapProgram $out/bin/${filename} --prefix PATH : ${lib.makeBinPath path}
'';
}));
workspace_helper = (
patchScriptBin {
filename = "workspace_helper";
contents = (builtins.readFile ./files/workspace_helper.bash);
path = with pkgs; [ jq ];
}
);
sway-config = pkgs.writeTextFile {
name = "config";
text = ''
# Default config for sway
#
# Copy this to ~/.config/sway/config and edit it to your liking.
#
# Read `man 5 sway` for a complete reference.
### Variables
#
# Logo key. Use Mod1 for Alt.
set $mod Mod4
# set $mod Mod1
# Home row direction keys, like vim
set $left h
set $down j
set $up k
set $right l
# Your preferred terminal emulator
set $term ${pkgs.alacritty}/bin/alacritty
# Your preferred application launcher
# Note: it's recommended that you pass the final command to sway
# set $menu dmenu_path | dmenu | xargs swaymsg exec
set $menu ${pkgs.tofi}/bin/tofi-drun | xargs swaymsg exec --
#set $menu ${pkgs.wofi}/bin/wofi --show drun --gtk-dark
# Do not show a title bar on windows
default_border pixel 2
hide_edge_borders smart_no_gaps
bindsym $mod+grave exec $term
${lib.concatMapStringsSep "\n" (item: "include ${item}") config.me.swayIncludes}
'';
};
base-hotkeys = pkgs.writeTextFile {
name = "base-hotkeys.conf";
text = ''
### Key bindings
#
# Basics:
#
# kill focused window
bindsym $mod+Shift+q kill
# start your launcher
bindsym $mod+Return exec $menu
# Drag floating windows by holding down $mod and left mouse button.
# Resize them with right mouse button + $mod.
# Despite the name, also works for non-floating windows.
# Change normal to inverse to use left mouse button for resizing and right
# mouse button for dragging.
floating_modifier $mod normal
# reload the configuration file
bindsym $mod+Shift+c reload
# exit sway (logs you out of your Wayland session)
bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'
'';
};
display-configs = pkgs.writeTextFile {
name = "display-configs.conf";
text = ''
output 'Unknown 0x095F 0x00000000' scale 1.5
output 'BOE 0x095F Unknown' scale 1.5
output 'BOE 0x0BCA Unknown' scale 1.5
'';
};
window-management = pkgs.writeTextFile {
name = "window-management.conf";
text = ''
#
# Layout stuff:
#
# You can "split" the current object of your focus with
# $mod+b or $mod+v, for horizontal and vertical splits
# respectively.
bindsym $mod+h splith
bindsym $mod+v splitv
# Switch the current container between different layout styles
bindsym $mod+s layout stacking
bindsym $mod+w layout tabbed
bindsym $mod+e layout toggle split
# Make the current focus fullscreen
bindsym $mod+f fullscreen
# Toggle the current focus between tiling and floating mode
bindsym $mod+Shift+space floating toggle
# Swap focus between the tiling area and the floating area
bindsym $mod+space focus mode_toggle
# move focus to the parent container
bindsym $mod+a focus parent
#
# Scratchpad:
#
# Sway has a "scratchpad", which is a bag of holding for windows.
# You can send windows there and get them back later.
# Move the currently focused window to the scratchpad
bindsym $mod+Shift+minus move scratchpad
# Show the next scratchpad window or hide the focused scratchpad window.
# If there are multiple scratchpad windows, this command cycles through them.
bindsym $mod+minus scratchpad show
#
# Resizing containers:
#
mode "resize" {
# left will shrink the containers width
# right will grow the containers width
# up will shrink the containers height
# down will grow the containers height
bindsym $left resize shrink width 10px
bindsym $down resize grow height 10px
bindsym $up resize shrink height 10px
bindsym $right resize grow width 10px
# ditto, with arrow keys
bindsym Left resize shrink width 10px
bindsym Down resize grow height 10px
bindsym Up resize shrink height 10px
bindsym Right resize grow width 10px
# return to default mode
bindsym Return mode "default"
bindsym Escape mode "default"
}
bindsym $mod+r mode "resize"
'';
};
movement = pkgs.writeTextFile {
name = "movement.conf";
text = ''
#
# Moving around:
#
# Move your focus around
# bindsym $mod+$left focus left
# bindsym $mod+$down focus down
# bindsym $mod+$up focus up
# bindsym $mod+$right focus right
# or use $mod+[up|down|left|right]
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right
# _move_ the focused window with the same, but add Shift
bindsym $mod+Shift+$left move left
bindsym $mod+Shift+$down move down
bindsym $mod+Shift+$up move up
bindsym $mod+Shift+$right move right
# ditto, with arrow keys
bindsym $mod+Shift+Left move left
bindsym $mod+Shift+Down move down
bindsym $mod+Shift+Up move up
bindsym $mod+Shift+Right move right
#
# Workspaces:
#
# switch to workspace
bindsym $mod+1 exec ${workspace_helper}/bin/workspace_helper go_to_workspace 1
bindsym $mod+2 exec ${workspace_helper}/bin/workspace_helper go_to_workspace 2
bindsym $mod+3 exec ${workspace_helper}/bin/workspace_helper go_to_workspace 3
bindsym $mod+4 exec ${workspace_helper}/bin/workspace_helper go_to_workspace 4
bindsym $mod+5 exec ${workspace_helper}/bin/workspace_helper go_to_workspace 5
bindsym $mod+6 exec ${workspace_helper}/bin/workspace_helper go_to_workspace 6
bindsym $mod+7 exec ${workspace_helper}/bin/workspace_helper go_to_workspace 7
bindsym $mod+8 exec ${workspace_helper}/bin/workspace_helper go_to_workspace 8
bindsym $mod+9 exec ${workspace_helper}/bin/workspace_helper go_to_workspace 9
bindsym $mod+0 exec ${workspace_helper}/bin/workspace_helper go_to_workspace 10
# move focused container to workspace
bindsym $mod+Shift+1 exec ${workspace_helper}/bin/workspace_helper send_to_workspace 1
bindsym $mod+Shift+2 exec ${workspace_helper}/bin/workspace_helper send_to_workspace 2
bindsym $mod+Shift+3 exec ${workspace_helper}/bin/workspace_helper send_to_workspace 3
bindsym $mod+Shift+4 exec ${workspace_helper}/bin/workspace_helper send_to_workspace 4
bindsym $mod+Shift+5 exec ${workspace_helper}/bin/workspace_helper send_to_workspace 5
bindsym $mod+Shift+6 exec ${workspace_helper}/bin/workspace_helper send_to_workspace 6
bindsym $mod+Shift+7 exec ${workspace_helper}/bin/workspace_helper send_to_workspace 7
bindsym $mod+Shift+8 exec ${workspace_helper}/bin/workspace_helper send_to_workspace 8
bindsym $mod+Shift+9 exec ${workspace_helper}/bin/workspace_helper send_to_workspace 9
bindsym $mod+Shift+0 exec ${workspace_helper}/bin/workspace_helper send_to_workspace 10
# Note: workspaces can have any name you want, not just numbers.
# We just use 1-10 as the default.
bindsym $mod+Ctrl+Left exec ${workspace_helper}/bin/workspace_helper go_to_previous_monitor
bindsym $mod+Ctrl+Shift+Left exec ${workspace_helper}/bin/workspace_helper send_to_previous_monitor
bindsym $mod+Ctrl+Right exec ${workspace_helper}/bin/workspace_helper go_to_next_monitor
bindsym $mod+Ctrl+Shift+Right exec ${workspace_helper}/bin/workspace_helper send_to_next_monitor
'';
};
disable-focus-follows-mouse = pkgs.writeTextFile {
name = "disable-focus-follows-mouse.conf";
text = ''
# Disable focus following mouse
focus_follows_mouse no
'';
};
background = pkgs.writeTextFile {
name = "background.conf";
text = ''
output * bg ${./files/bliss.jpg} fill
'';
};
touchpad_input = pkgs.writeTextFile {
name = "touchpad_input.conf";
text = ''
input * xkb_rules "evdev"
# All touchpads
input type:touchpad {
dwt enabled
click_method clickfinger
tap enabled
}
'';
};
announce_sway_start = pkgs.writeTextFile {
name = "announce_sway_start.conf";
text = ''
# announce a running sway session to systemd
exec systemctl --user import-environment WAYLAND_DISPLAY DISPLAY XDG_CURRENT_DESKTOP SWAYSOCK I3SOCK XCURSOR_SIZE XCURSOR_THEME
exec dbus-update-activation-environment WAYLAND_DISPLAY DISPLAY XDG_CURRENT_DESKTOP SWAYSOCK I3SOCK XCURSOR_SIZE XCURSOR_THEME
'';
};
start_screen_share = pkgs.writeShellScriptBin "start_screen_share" ''
# Disable displaying notifications. This is useful for video conference screen sharing.
set -euo pipefail
IFS=$'\n\t'
DIR="$( cd "$( dirname "''${BASH_SOURCE[0]}" )" && pwd )"
${pkgs.mako}/bin/makoctl mode -s do-not-disturb
${pkgs.sway}/bin/swaymsg output "'Dell Inc. DELL U3014 P1V6N35M329L'" scale 2
'';
stop_screen_share = pkgs.writeShellScriptBin "stop_screen_share" ''
# Allow mako to show notifications again.
set -euo pipefail
IFS=$'\n\t'
DIR="$( cd "$( dirname "''${BASH_SOURCE[0]}" )" && pwd )"
${pkgs.mako}/bin/makoctl mode -s default
${pkgs.sway}/bin/swaymsg output "'Dell Inc. DELL U3014 P1V6N35M329L'" scale 1
'';
in
{
imports = [
./graphical_session_target.nix
./iso.nix
./rofimoji.nix
./lockscreen.nix
./screenshot.nix
./force_focus.nix
./notification.nix
];
options.me = {
sway.enable = lib.mkOption {
type = lib.types.bool;
default = false;
example = true;
description = "Whether we want to install sway.";
};
};
options.me.swayIncludes = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [ ];
example = lib.literalExpression ''
[ (pkgs.writeTextFile {
name = "launch-kanshi.conf";
text = "exec kanshi";
}) ]'';
description = "List of packages to import as sway configs.";
};
config = lib.mkIf (config.me.graphical && config.me.sway.enable) {
environment.systemPackages = with pkgs; [
alacritty
pcmanfm
start_screen_share
stop_screen_share
];
programs.sway.extraPackages = lib.mkForce [ ];
me.swayIncludes = [
base-hotkeys
display-configs
window-management
movement
disable-focus-follows-mouse
background
touchpad_input
announce_sway_start
];
services.seatd.enable = true;
# TODO: Maybe use `seatd-launch -- sway` instead of running the seatd daemon
users.users.talexander.extraGroups = [ "seat" ];
# Probably would be cleaner to use environment.sessionVariables but programs.sway.extraSessionCommands is sway-specific.
programs.sway.extraSessionCommands =
if config.me.buildingPortable then
''
export WLR_RENDERER_ALLOW_SOFTWARE=1
export NIXOS_OZONE_WL=1 # Wayland support for chromium and electron
export QT_QPA_PLATFORMTHEME=gtk3 # Use gtk theme in Qt applications
''
else
''
export WLR_RENDERER=vulkan
export NIXOS_OZONE_WL=1 # Wayland support for chromium and electron
export QT_QPA_PLATFORMTHEME=gtk3 # Use gtk theme in Qt applications
'';
programs.sway = {
enable = true;
wrapperFeatures.gtk = true;
extraOptions =
if config.me.buildingPortable then
[
"--config"
"${sway-config}"
"--unsupported-gpu"
]
else
[
"--config"
"${sway-config}"
];
};
environment.persistence."/state" = lib.mkIf (config.me.mountPersistence) {
hideMounts = true;
users.talexander = {
files = [
".local/state/tofi-drun-history" # A cache of the desktop files for tofi
".cache/tofi-drun" # Execution history for tofi to sort results
];
};
};
xdg = {
portal = {
enable = true;
extraPortals = with pkgs; [
xdg-desktop-portal-gtk
];
wlr = {
enable = true;
settings = {
# uninteresting for this problem, for completeness only
screencast = {
# output_name = "eDP-1";
max_fps = 30;
exec_before = "${start_screen_share}/bin/start_screen_share";
exec_after = "${stop_screen_share}/bin/stop_screen_share";
chooser_type = "simple";
chooser_cmd = "${pkgs.slurp}/bin/slurp -f 'Monitor: %o' -or";
};
};
};
};
};
me.install.user.talexander.file = {
".config/mimeapps.list" = {
# Configure default programs (for example, default browser)
source = ./files/mimeapps.list;
};
".config/gtk-3.0/settings.ini" = {
source = ./files/settings.ini;
};
".icons/default" = {
source = "${pkgs.adwaita-icon-theme}/share/icons/Adwaita";
};
};
# For mounting drives in pcmanfm
services.gvfs.enable = true;
# Auto-launch sway
# Run sway as the absolute last command in the login shell init. mkBefore = 500, plain = 1000, mkAfter = 1500
environment.loginShellInit = lib.mkOrder 2000 ''
[ -z "$WAYLAND_DISPLAY" ] && [ -n "$XDG_VTNR" ] && [ "$XDG_VTNR" -eq 1 ] && [ "$(tty)" = "/dev/tty1" ] && exec ${pkgs.systemd}/bin/systemd-cat --identifier=sway sway
'';
};
}