nix/modules/hyprland/home.nix
2025-11-03 22:53:55 +01:00

508 lines
12 KiB
Nix

{ config, pkgs, ... }:
{
# Fcitx5 input method configuration
xdg.configFile."fcitx5/profile" = {
force = true;
text = ''
[Groups/0]
Name=Default
Default Layout=us
DefaultIMName=keyboard-us
[Groups/0/Items/0]
Name=keyboard-us
Layout=
[Groups/0/Items/1]
Name=rime
Layout=
[Groups/0/Items/2]
Name=mozc
Layout=
[GroupOrder]
0=Default
'';
};
xdg.configFile."fcitx5/config" = {
force = true;
text = ''
[Hotkey]
TriggerKeys=
EnumerateWithTriggerKeys=True
AltTriggerKeys=
EnumerateForwardKeys=
EnumerateBackwardKeys=
EnumerateSkipFirst=False
[Behavior]
ActiveByDefault=False
ShareInputState=No
'';
};
# Rime configuration for Simplified Chinese
xdg.configFile."fcitx5/rime/default.custom.yaml" = {
force = true;
text = ''
patch:
"schema_list":
- schema: luna_pinyin_simp
"menu/page_size": 7
'';
};
# Rime addon configuration - 7 candidates per page
xdg.configFile."fcitx5/conf/rime.conf" = {
force = true;
text = ''
[InputMethod]
PageSize=7
'';
};
# Mozc addon configuration - 7 candidates per page
xdg.configFile."fcitx5/conf/mozc.conf" = {
force = true;
text = ''
[InputMethod]
PageSize=7
'';
};
# GNOME Keyring for storing WiFi passwords and other secrets
services.gnome-keyring = {
enable = true;
components = [ "secrets" "ssh" ];
};
wayland.windowManager.hyprland = {
enable = true;
xwayland.enable = true;
settings = {
# Monitor configuration
monitor = ",preferred,auto,1";
# Environment variables for input methods
env = [
"GTK_IM_MODULE,fcitx"
"QT_IM_MODULE,fcitx"
"XMODIFIERS,@im=fcitx"
];
# Execute apps at launch
exec-once = [
"gnome-keyring-daemon --start --components=secrets,ssh"
"fcitx5 -d"
"hypridle"
"waybar"
"nm-applet --indicator"
];
# Input configuration
input = {
kb_layout = "us";
follow_mouse = 1;
touchpad = {
natural_scroll = true;
tap-to-click = false;
disable_while_typing = true;
};
};
# General window and workspace settings
general = {
gaps_in = 5;
gaps_out = 10;
border_size = 2;
"col.active_border" = "rgba(33ccffee) rgba(00ff99ee) 45deg";
"col.inactive_border" = "rgba(595959aa)";
layout = "dwindle";
};
# Decoration settings
decoration = {
rounding = 8;
blur = {
enabled = true;
size = 3;
passes = 1;
};
shadow = {
enabled = true;
range = 4;
render_power = 3;
color = "rgba(1a1a1aee)";
};
};
# Animation settings
animations = {
enabled = true;
bezier = "myBezier, 0.05, 0.9, 0.1, 1.05";
animation = [
"windows, 1, 3, myBezier"
"windowsOut, 1, 3, default, popin 80%"
"border, 1, 5, default"
"borderangle, 1, 4, default"
"fade, 1, 3, default"
"workspaces, 1, 3, default"
];
};
# Dwindle layout settings
dwindle = {
pseudotile = true;
preserve_split = true;
};
# Master layout settings
master = {
new_status = "master";
};
# Misc settings
misc = {
force_default_wallpaper = 0;
disable_hyprland_logo = false;
};
# Keybindings
bind = [
# Core window management
"SUPER, Q, killactive,"
"SUPER, F, fullscreen,"
"SUPER, V, togglefloating,"
# Application launchers
"SUPER, Return, exec, ghostty"
"SUPER, Space, exec, wofi --show drun"
# Input method switching (cycles through configured IMs)
"ALT, Space, exec, ${pkgs.writeShellScript "fcitx5-cycle" ''
current=$(${pkgs.fcitx5}/bin/fcitx5-remote -n)
case "$current" in
keyboard-us)
${pkgs.fcitx5}/bin/fcitx5-remote -s rime
;;
rime)
${pkgs.fcitx5}/bin/fcitx5-remote -s mozc
;;
mozc|*)
${pkgs.fcitx5}/bin/fcitx5-remote -s keyboard-us
;;
esac
''}"
# Window focus navigation (vim-style)
"SUPER, h, movefocus, l"
"SUPER, j, movefocus, d"
"SUPER, k, movefocus, u"
"SUPER, l, movefocus, r"
# Window resizing
"SUPER SHIFT, h, resizeactive, -50 0"
"SUPER SHIFT, j, resizeactive, 0 50"
"SUPER SHIFT, k, resizeactive, 0 -50"
"SUPER SHIFT, l, resizeactive, 50 0"
# Window swapping/moving
"SUPER CTRL, h, movewindow, l"
"SUPER CTRL, j, movewindow, d"
"SUPER CTRL, k, movewindow, u"
"SUPER CTRL, l, movewindow, r"
# Workspace navigation (1-9)
"SUPER, 1, workspace, 1"
"SUPER, 2, workspace, 2"
"SUPER, 3, workspace, 3"
"SUPER, 4, workspace, 4"
"SUPER, 5, workspace, 5"
"SUPER, 6, workspace, 6"
"SUPER, 7, workspace, 7"
"SUPER, 8, workspace, 8"
"SUPER, 9, workspace, 9"
# Move window to workspace (1-9)
"SUPER SHIFT, 1, movetoworkspace, 1"
"SUPER SHIFT, 2, movetoworkspace, 2"
"SUPER SHIFT, 3, movetoworkspace, 3"
"SUPER SHIFT, 4, movetoworkspace, 4"
"SUPER SHIFT, 5, movetoworkspace, 5"
"SUPER SHIFT, 6, movetoworkspace, 6"
"SUPER SHIFT, 7, movetoworkspace, 7"
"SUPER SHIFT, 8, movetoworkspace, 8"
"SUPER SHIFT, 9, movetoworkspace, 9"
# Brightness control
", XF86MonBrightnessUp, exec, brightnessctl set +5%"
", XF86MonBrightnessDown, exec, brightnessctl set 5%-"
# Volume control
", XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"
", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"
", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
];
# Mouse bindings
bindm = [
"SUPER, mouse:272, movewindow"
"SUPER, mouse:273, resizewindow"
];
};
};
# Hyprpaper wallpaper service
services.hyprpaper = {
enable = true;
settings = {
preload = [
"/home/yanlin/Downloads/nixos-nineish-dark@4k.png"
];
wallpaper = [
"eDP-1,/home/yanlin/Downloads/nixos-nineish-dark@4k.png"
];
};
};
# Blueman applet for Bluetooth management
services.blueman-applet.enable = true;
# Hypridle configuration (screen timeout and lock)
services.hypridle = {
enable = true;
settings = {
general = {
lock_cmd = "pidof hyprlock || hyprlock";
before_sleep_cmd = "loginctl lock-session";
after_sleep_cmd = "hyprctl dispatch dpms on";
};
listener = [
{
timeout = 600; # 10 minutes
on-timeout = "loginctl lock-session";
}
{
timeout = 900; # 15 minutes
on-timeout = "hyprctl dispatch dpms off";
on-resume = "hyprctl dispatch dpms on";
}
];
};
};
# Hyprlock configuration (screen locker)
programs.hyprlock = {
enable = true;
settings = {
general = {
disable_loading_bar = false;
hide_cursor = true;
grace = 0;
no_fade_in = false;
};
background = [
{
path = "screenshot";
blur_passes = 3;
blur_size = 8;
}
];
input-field = [
{
size = "200, 50";
position = "0, -20";
monitor = "";
dots_center = true;
fade_on_empty = false;
font_color = "rgb(202, 211, 245)";
inner_color = "rgb(91, 96, 120)";
outer_color = "rgb(24, 25, 38)";
outline_thickness = 5;
placeholder_text = ''<span foreground="##cad3f5">Password...</span>'';
shadow_passes = 2;
}
];
};
};
# GTK theme settings (optional, for consistent theming)
gtk = {
enable = true;
theme = {
name = "Adwaita-dark";
package = pkgs.gnome-themes-extra;
};
iconTheme = {
name = "Papirus-Dark";
package = pkgs.papirus-icon-theme;
};
};
# Wofi application launcher configuration
programs.wofi = {
enable = true;
settings = {
# Vim-style navigation with Ctrl+j/k
key_up = "Ctrl-k";
key_down = "Ctrl-j";
};
};
# Waybar configuration for Hyprland
programs.waybar = {
enable = true;
settings = {
mainBar = {
layer = "top";
position = "top";
height = 30;
spacing = 4;
modules-left = [ "hyprland/workspaces" "hyprland/window" ];
modules-center = [ "clock" ];
modules-right = [ "pulseaudio" "backlight" "battery" "tray" ];
"hyprland/workspaces" = {
format = "{name}";
on-click = "activate";
};
"hyprland/window" = {
format = "{}";
max-length = 50;
};
"clock" = {
format = "{:%H:%M %a %d %b}";
tooltip-format = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>";
};
"battery" = {
bat = "BAT0";
states = {
warning = 30;
critical = 15;
};
format = "{capacity}% {icon}";
format-charging = "{capacity}% ";
format-plugged = "{capacity}% ";
format-icons = ["" "" "" "" ""];
tooltip-format = "{capacity}% {timeTo}";
};
"pulseaudio" = {
format = "{volume}% {icon}";
format-bluetooth = "{volume}% {icon}";
format-muted = "";
format-icons = {
headphone = "";
hands-free = "";
headset = "";
phone = "";
portable = "";
car = "";
default = ["" "" ""];
};
on-click = "pavucontrol";
tooltip-format = "Volume: {volume}%";
};
"backlight" = {
device = "intel_backlight";
format = "{percent}% {icon}";
format-icons = ["" ""];
on-click = "nwg-displays";
tooltip-format = "Brightness: {percent}%";
};
"tray" = {
spacing = 10;
};
};
};
style = ''
* {
border: none;
border-radius: 0;
font-family: monospace;
font-size: 13px;
}
window#waybar {
background-color: rgba(43, 48, 59, 0.9);
color: #ffffff;
}
#workspaces button {
padding: 0 5px;
background-color: transparent;
color: #ffffff;
}
#workspaces button.active {
background-color: #64727D;
}
#workspaces button:hover {
background-color: rgba(0, 0, 0, 0.2);
}
#window,
#clock,
#tray {
padding: 0 10px;
color: #ffffff;
}
/* Color-coded modules for easy distinction */
#pulseaudio {
padding: 0 10px;
color: #a6e3a1; /* Green - Volume */
}
#backlight {
padding: 0 10px;
color: #f9e2af; /* Yellow - Brightness */
}
#battery {
padding: 0 10px;
color: #89b4fa; /* Blue - Battery */
}
/* Battery state colors override base color */
#battery.charging {
color: #a6e3a1; /* Bright green when charging */
}
#battery.warning:not(.charging) {
color: #fab387; /* Orange for warning */
}
#battery.critical:not(.charging) {
color: #f38ba8; /* Red for critical */
animation: blink 1s linear infinite;
}
@keyframes blink {
to {
opacity: 0.5;
}
}
/* Muted audio */
#pulseaudio.muted {
color: #6c7086; /* Gray when muted */
}
'';
};
}