nixos-flake/home-manager/jwm.nix

499 lines
16 KiB
Nix

{ config, pkgs, lib, ... }:
with lib;
with builtins;
let cfg = config.jainawm;
in {
options.jainawm = {
enable = mkOption {
type = types.bool;
default = false;
};
terminal = {
name = mkOption {
type = types.str;
default = "kitty";
};
package = mkOption {
type = types.package;
default = pkgs.kitty;
};
binPath = mkOption {
type = types.str;
readOnly = true;
};
};
fonts = let fontOption = mkOption { type = lib.hm.types.fontType; };
in {
primary = fontOption;
serif = fontOption;
fixed = fontOption;
wmOverlay = fontOption;
};
catppuccin = mkOption {
#type = types.attrs;
default = import ./catppuccin/mocha.nix;
description = ''
Set of colors to use for theme configuration.
'';
};
accents = {
primary = mkOption { type = types.str; };
secondary = mkOption { type = types.str; };
};
wallpaper = mkOption { type = types.path; };
startup = mkOption {
type = types.listOf (type.submodule {
options = {
enable = mkEnableOption "Enable the given startup command";
command = mkOption { type = types.str; };
always = mkOption {
type = types.bool;
default = false;
descrioption =
"If true, the command will be ran when the window manager is reset";
};
};
});
};
};
imports = [
./jwm/sway.nix
./jwm/rofi.nix
./jwm/phelper.nix
./jwm/kanshi.nix
./jwm/waybar.nix
./jwm/ptray.nix
];
config = let
cat = cfg.catppuccin;
#front = getAttr cfg.selectedFront cfg.fronters;
fonts = cfg.fonts;
in mkIf cfg.enable {
jainawm.terminal.binPath =
"${cfg.terminal.package}/bin/${cfg.terminal.name}";
services.mako = {
enable = true;
anchor = "top-right";
height = 100;
width = 500;
padding = "10";
layer = "overlay";
font = "${fonts.primary.name} ${toString (fonts.primary.size + 1)}";
textColor = cat.text;
backgroundColor = "${cat.surface0}cc";
progressColor = "over ${cat.surface2}cc";
borderColor =
builtins.getAttr (lib.strings.toLower cfg.accents.primary) cat;
borderRadius = 10;
borderSize = 3;
defaultTimeout = null;
maxVisible = null;
# groupBy =
# iconPath =
extraConfig = ''
on-button-left=invoke-default-action
on-touch=invoke-default-action
on-button-right=dismiss
[app-name="discord"]
layer=overlay
on-button-left=exec /usr/bin/env dropwinctl show discord && makoctl invoke -n "$id" && makoctl dismiss -n "$id"
[app-name="JWM"]
layer=overlay
[app-name="JWM" category="audio" body~="1\([0-9][1-9]|[1-9][0-9]\)"]
background-color=${cat.surface2}f8
progress-color=over ${cat.red}cc
'';
};
#jainawm.wallpaper = front.wallpaper;
jainawm.rofi.accents =
mapAttrs (n: c: builtins.getAttr (lib.strings.toLower c) cat) cfg.accents;
jainawm.rofi.font = fonts.wmOverlay;
jainawm.ptray = {
enable = true;
items = {
discord = {
match_classes = [ "WebCord" "discord" ];
exec =
"${pkgs.webcord}/bin/webcord --enable-features=UseOzonePlatform --ozone-platform=wayland --disable-gpu";
};
keepass = {
match_classes = [ "org.keepassxc.KeePassXC" ];
exec = "${pkgs.keepassxc}/bin/keepassxc";
};
};
# drops = let
# fx = [
# "opacity 0.97"
# "floating enable"
# "resize set 80ppt 80ppt"
# "move position 10ppt -10"
# "sticky enable"
# ];
# in {
# discord = {
# match = [ "WebCord" "discord" ];
# start = "${pkgs.discord}/bin/discord";
# customization = fx;
# };
# keepass = {
# match = [ "org.keepassxc.KeePassXC" ];
# start = "${pkgs.keepassxc}/bin/keepassxc";
# customization = fx;
# };
# matrix = {
# match = [ "Element" ];
# start = "${element-desktop}/bin/element-desktop";
# customization = fx;
# };
# };
};
#jainawm.rofi.accent = "#ff0000";
#jainawm.rofi.enable = true;
#programs.waybar.style = builtins.readFile ./waybar/style.css;
jainawm.kanshi.enable = true;
jainawm.sway.enable = true;
# TODO
xdg.configFile."hypr/hyprpaper.conf".text = ''
preload = ${cfg.wallpaper}
wallpaper = ,${cfg.wallpaper}
'';
home.activation."switch-hyprpaper-wallpaper" =
lib.hm.dag.entryAfter [ "writeBoundary" ] ''
export PATH="$PATH:${config.wayland.windowManager.hyprland.package}/bin:${pkgs.jq}/bin"
for inst in $(ls ''${XDG_RUNTIME_DIR:-/run/user/$UID}/hypr); do
$DRY_RUN_CMD hyprctl -i $inst hyprpaper preload ${cfg.wallpaper} || true
(hyprctl monitors -j -i $inst | jq --raw-output '.[] | .name' || true) | \
xargs -I{} $DRY_RUN_CMD hyprctl -i $inst hyprpaper wallpaper '{},${cfg.wallpaper}'
$DRY_RUN_CMD hyprctl -i $inst hyprpaper unload all || true
done
'';
xdg.configFile."eww/theme_cat.scss".text = concatStringsSep "\n"
(mapAttrsToList (name: value: "$cat-${name}: ${value};") cfg.catppuccin);
xdg.configFile."eww/theme_jwm.scss".text = ''
@import "theme_cat"
$jwm-accent: $cat-${lib.strings.toLower cfg.accents.primary};
$jwm-accent2: $cat-${lib.strings.toLower cfg.accents.secondary};
$jwm-accent-contrast: $cat-crust;
'';
home.activation.reloadHyprland =
lib.hm.dag.entryAfter [ "writeBoundary" ] ''
export PATH="$PATH:${config.wayland.windowManager.hyprland.package}/bin"
ls ''${XDG_RUNTIME_DIR:-/run/user/$UID}/hypr || true | \
xargs -I{} $DRY_RUN_CMD hyprctl reload -i {}
'';
wayland.windowManager.hyprland.enable = true;
#wayland.windowManager.hyprland.settings = { };
wayland.windowManager.hyprland.extraConfig = let
removeHash = col: builtins.replaceStrings [ "#" ] [ "" ] col;
getColor = name:
removeHash (builtins.getAttr (lib.strings.toLower name) cfg.catppuccin);
mainMod = "SUPER";
playerctl = "${pkgs.playerctl}/bin/playerctl --player strawberry";
hide-special = pkgs.writeShellScript "jwm-hyprland-hide-special" ''
hyprctl monitors -j | jq -r '.[] | .specialWorkspace.name | select(. | length > 0) | .[8:]' \
| xargs -I{} hyprctl dispatcher togglespecialworkspace "{}" >/dev/null
'';
rofi-emoji = let
rofi-emoji-theme = ''
element selected {
background-color: rgba(0,0,0,0 %);
border-color: ${cfg.rofi.accents.primary}ff;
border: 2px;
}
element {
children: ["element-text"];
}
element-text {
horizontal-align: 0.5;
font: "${fonts.primary.name} 25";
margin: 0px;
}
listview {
flow: horizontal;
columns: 7;
}
'';
in pkgs.writeShellScript "rofi-emoji" ''
${config.programs.rofi.finalPackage}/bin/rofi \
-show emoji -modes emoji \
-emoji-format '{emoji}' \
-theme-str ${lib.strings.escapeShellArg rofi-emoji-theme} \
$@
'';
playerctlPrevOrScan = pkgs.writeScript "playerctlPrevOrScan" ''
if [ "$(${playerctl} metadata --format '{{position}}')" -lt 10000000 ]; then
${playerctl} previous
else
${playerctl} position 0
fi
'';
in ''
$mainMod = ${mainMod}
# For all categories, see https://wiki.hyprland.org/Configuring/Variables/
input {
kb_layout = us
kb_variant =
kb_model =
kb_options = altwin:swap_lalt_lwin,altwin:menu_win
kb_rules =
follow_mouse = 1
touchpad {
natural_scroll = yes
}
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
}
gestures {
workspace_swipe = true
workspace_swipe_fingers = 4
}
general {
col.active_border = rgba(${getColor cfg.accents.primary}ee)
col.inactive_border = rgba(${removeHash cfg.catppuccin.surface0}aa)
gaps_in = 10
gaps_out = 20
border_size = 2
layout = dwindle
}
decoration {
rounding = 10
drop_shadow = yes
shadow_range = 20
shadow_render_power = 2
col.shadow = rgba(000000ee)
col.shadow_inactive = rgba(00000000)
blur {
size = 5
passes = 2
special = true
}
}
layerrule = blur, rofi|notifications
layerrule = ignorealpha 0.4, rofi|notifications
animations {
enabled = yes
# Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
animation = windows, 1, 7, myBezier
animation = windowsOut, 1, 7, default, popin 80%
animation = border, 1, 10, default
animation = borderangle, 1, 8, default
animation = fade, 1, 7, default
animation = workspaces, 1, 6, default
animation = specialWorkspace, 1, 6, default, slidevert
}
dwindle {
preserve_split = yes
}
gestures {
workspace_swipe = on
}
bind = ${mainMod}, Return, exec, ${cfg.terminal.binPath}
bind = ${mainMod}, D, exec, rofi -show drun
bind = ${mainMod} SHIFT, S, exec, jwm screenshot-region
binde = ${mainMod} SHIFT, Q, killactive,
bind = ${mainMod} SHIFT, E, exit,
bind = ${mainMod}, F, fullscreen,
bind = ${mainMod}, Q, exec, ${hide-special}
bindle = , XF86MonBrightnessUp, exec, jwm bright 5
bindle = , XF86MonBrightnessDown, exec, jwm bright -5
bindle = , XF86AudioRaiseVolume, exec, jwm vol 5
bindle = , XF86AudioLowerVolume, exec, jwm vol -5
bindl = , XF86AudioMute, exec, jwm vol toggle-mute
bindl = , XF86AudioPlay, exec, ${playerctl} play-pause
bindl = , XF86AudioNext, exec, ${playerctl} next
bindl = , XF86AudioPrev, exec, ${playerctlPrevOrScan}
bindl = ${mainMod} CTRL, right, exec, ${playerctl} next
bindl = ${mainMod} CTRL, left, exec, ${playerctlPrevOrScan}
bindl = , XF86AudioStop, exec, ${playerctl} stop
# Move focus with mainMod + arrow keys
bind = ${mainMod}, left, movefocus, l
bind = ${mainMod}, down, movefocus, d
bind = ${mainMod}, up, movefocus, u
bind = ${mainMod}, right, movefocus, r
bind = ${mainMod}, h, movefocus, l
bind = ${mainMod}, j, movefocus, d
bind = ${mainMod}, k, movefocus, u
bind = ${mainMod}, l, movefocus, r
# Move focused window with mainMod + Shift + direction keys
bind = ${mainMod} SHIFT, left, moveWindowOrGroup, l
bind = ${mainMod} SHIFT, down, moveWindowOrGroup, d
bind = ${mainMod} SHIFT, up, moveWindowOrGroup, u
bind = ${mainMod} SHIFT, right, moveWindowOrGroup, r
bind = ${mainMod} SHIFT, h, moveWindowOrGroup, l
bind = ${mainMod} SHIFT, j, moveWindowOrGroup, d
bind = ${mainMod} SHIFT, k, moveWindowOrGroup, u
bind = ${mainMod} SHIFT, l, moveWindowOrGroup, r
# Switch workspaces with mainMod + [0-9]
bind = ${mainMod}, 1, workspace, 1
bind = ${mainMod}, 2, workspace, 2
bind = ${mainMod}, 3, workspace, 3
bind = ${mainMod}, 4, workspace, 4
bind = ${mainMod}, 5, workspace, 5
bind = ${mainMod}, 6, workspace, 6
bind = ${mainMod}, 7, workspace, 7
bind = ${mainMod}, 8, workspace, 8
bind = ${mainMod}, 9, workspace, 9
bind = ${mainMod}, 0, workspace, 10
# Move active window to a workspace with mainMod + SHIFT + [0-9]
bind = ${mainMod} SHIFT, 1, movetoworkspace, 1
bind = ${mainMod} SHIFT, 2, movetoworkspace, 2
bind = ${mainMod} SHIFT, 3, movetoworkspace, 3
bind = ${mainMod} SHIFT, 4, movetoworkspace, 4
bind = ${mainMod} SHIFT, 5, movetoworkspace, 5
bind = ${mainMod} SHIFT, 6, movetoworkspace, 6
bind = ${mainMod} SHIFT, 7, movetoworkspace, 7
bind = ${mainMod} SHIFT, 8, movetoworkspace, 8
bind = ${mainMod} SHIFT, 9, movetoworkspace, 9
bind = ${mainMod} SHIFT, 0, movetoworkspace, 10
# Scroll through existing workspaces with mainMod + scroll
bind = ${mainMod}, mouse_down, workspace, e+1
bind = ${mainMod}, mouse_up, workspace, e-1
bind = ${mainMod}, TAB, workspace, e+1
bind = ${mainMod}, GRAVE, workspace, e-1
bind = ${mainMod} SHIFT, TAB, movetoworkspace, e+1
bind = ${mainMod} SHIFT, GRAVE, movetoworkspace, e-1
# Move/resize windows with mainMod + LMB/RMB and dragging
bindm = ${mainMod}, mouse:272, movewindow
bindm = ${mainMod}, mouse:273, resizewindow
# Resize current window
bind = ${mainMod}, R, submap, resize
submap = resize
binde =, left, resizeActive, -10 0
binde =, down, resizeActive, 0 10
binde =, up, resizeActive, 0 -10
binde =, right, resizeActive, 10 0
binde =, h, resizeActive, -10 0
binde =, j, resizeActive, 0 10
binde =, k, resizeActive, 0 -10
binde =, l, resizeActive, 10 0
bind=,escape,submap,reset
bind=,return,submap,reset
submap = reset
# App Launcher
bind = ${mainMod}, I, submap, app
submap = app
bind = , D, togglespecialworkspace, discord
bind = , D, submap, reset
bind = SHIFT, D, movetoworkspace, special:discord
bind = SHIFT, D, submap, reset
bind = , K, togglespecialworkspace, keepass
bind = , K, submap, reset
bind = SHIFT, K, movetoworkspace, special:keepass
bind = SHIFT, K, submap, reset
bind = , W, exec, jwm web-launcher
bind = , W, submap, reset
bind = , Return, submap, reset
bind = , Escape, submap, reset
submap = reset
# OS commands
bind = ${mainMod}, P, submap, command
submap = command
bind = , M, exec, jwm mic toggle-mute
bind = , M, submap, reset
bind = , S, exec, jwm switch-launcher
bind = , S, submap, reset
bind = , D, exec, jwm toggle-dwt
bind = , D, submap, reset
bind = , Return, submap, reset
bind = , Escape, submap, reset
submap = reset
# Emoji
bind = ${mainMod}, PERIOD, exec, ${rofi-emoji} -emoji-mode stdout | xargs wtype
windowrule = noborder,^(steam_app_)(.*)$
windowrule = noblur,^(steam_app_)(.*)$
windowrulev2 = workspace special:discord,class:(WebCord)
windowrulev2 = workspace special:keepass,class:(org.keepassxc.KeePassXC)
source=~/.config/hypr/hyprland.conf.backup
'';
#wayland.windowManager.hyprland = {
# extraConfig = ''
# source=~/.config/hypr/hyprland.conf.backup
# '';
#enable = true;
#};
#jainawm.sway.useFx = true;
home.packages = with pkgs; [ playerctl hyprpaper ];
qt = {
#enable = true;
enable = false;
platformTheme.name = "gtk";
};
gtk.enable = true;
gtk.theme = {
name = "Catppuccin-Mocha-Standard-${cfg.accents.primary}-Dark";
package = pkgs.catppuccin-gtk.override {
accents = [ (lib.strings.toLower cfg.accents.primary) ];
variant = "mocha";
};
};
programs.swaylock.settings.image = "${cfg.wallpaper}";
#wayland.windowManager.sway.config.output."*".bg = "${front.wallpaper} fill";
# programs.rofi.theme = import ./rofi-theme.nix {
# cat = cat;
# front = front;
# fonts = cfg.fonts;
# lib = lib;
# config = config;
# };
};
}