{ 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= [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 (must be in .local/share not .config) xdg.dataFile."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 ''; }; # 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; # Source nwg-displays generated monitor configuration extraConfig = '' source = ~/.config/hypr/monitors.conf ''; settings = { # Monitor configuration handled by nwg-displays (see extraConfig above) # Environment variables for input methods and theming env = [ "GTK_IM_MODULE,fcitx" "QT_IM_MODULE,fcitx" "XMODIFIERS,@im=fcitx" "GTK_THEME,Adwaita:dark" "XCURSOR_SIZE,24" "XCURSOR_THEME,Bibata-Modern-Ice" "MOZ_ENABLE_WAYLAND,1" "MOZ_DISABLE_RDD_SANDBOX,1" ]; # Execute apps at launch exec-once = [ "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE XDG_SESSION_TYPE" "gnome-keyring-daemon --start --components=secrets,ssh" "fcitx5 -d" "hypridle" "swaync" "waybar" "nm-applet --indicator" "mkdir -p ~/Pictures/Screenshots" "wl-paste --watch cliphist store" ]; # 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 = 0; gaps_out = 0; border_size = 2; "col.active_border" = "rgba(fabd2fee) rgba(fe8019ee) 45deg"; "col.inactive_border" = "rgba(928374aa)"; layout = "dwindle"; }; # Decoration settings decoration = { rounding = 0; blur = { enabled = false; size = 3; passes = 1; }; shadow = { enabled = false; 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" "SUPER, C, exec, cliphist list | wofi --dmenu | cliphist decode | wl-copy" # Input method switching (cycles through configured IMs) "CTRL, 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 ;; *) ${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" # Screenshots ", Print, exec, grimblast copysave area ~/Pictures/Screenshots/$(date +%Y-%m-%d_%H-%M-%S).png" "SHIFT, Print, exec, grimblast copysave screen ~/Pictures/Screenshots/$(date +%Y-%m-%d_%H-%M-%S).png" "CTRL, Print, exec, grimblast copysave active ~/Pictures/Screenshots/$(date +%Y-%m-%d_%H-%M-%S).png" ]; # Mouse bindings bindm = [ "SUPER, mouse:272, movewindow" "SUPER, mouse:273, resizewindow" ]; # Lid switch bindings - disable internal display when lid closes, reload config when lid opens bindl = [ ", switch:on:Lid Switch, exec, hyprctl keyword monitor \"eDP-1, disable\"" ", switch:off:Lid Switch, exec, hyprctl reload" ]; }; }; # Hyprpaper wallpaper service services.hyprpaper = { enable = true; settings = { preload = [ "/home/yanlin/Documents/app-state/nixos-nineish-dark@4k.png" ]; wallpaper = [ ",/home/yanlin/Documents/app-state/nixos-nineish-dark@4k.png" ]; }; }; # Blueman applet for Bluetooth management services.blueman-applet.enable = true; # Hypridle configuration (screen timeout and lock) services.hypridle = { enable = false; 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 = ''Password...''; 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; }; gtk3.extraConfig = { gtk-application-prefer-dark-theme = 1; }; gtk4.extraConfig = { gtk-application-prefer-dark-theme = 1; }; }; # Qt theme settings for consistent theming with GTK qt = { enable = true; platformTheme.name = "adwaita"; style.name = "adwaita-dark"; }; # dconf settings for GNOME apps to prefer dark theme dconf.settings = { "org/gnome/desktop/interface" = { color-scheme = "prefer-dark"; }; }; home.packages = with pkgs; [ adwaita-qt adwaita-qt6 grimblast xfce.thunar evince loupe wl-clipboard cliphist redsocks ]; # Redsocks configuration for transparent SOCKS proxy xdg.configFile."redsocks/redsocks.conf" = { text = '' base { log_debug = off; log_info = on; log = "file:/tmp/redsocks.log"; daemon = on; redirector = iptables; } redsocks { local_ip = 127.0.0.1; local_port = 12345; ip = 127.0.0.1; port = 1080; type = socks5; } ''; }; # Hyprland-specific shell configuration programs.zsh.initContent = '' # Quickly restart Hyprland session (graceful logout) alias hypr-restart='loginctl terminate-session' ''; # Cursor theme configuration home.pointerCursor = { name = "Bibata-Modern-Ice"; package = pkgs.bibata-cursors; size = 24; gtk.enable = true; x11.enable = true; }; # 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 = [ "custom/nixos-logo" "clock" ]; modules-right = [ "custom/notification" "pulseaudio" "backlight" "battery" "tray" ]; "custom/nixos-logo" = { format = ""; tooltip = true; tooltip-format = "NixOS"; }; "hyprland/workspaces" = { format = "{name}"; on-click = "activate"; }; "hyprland/window" = { format = "{}"; max-length = 50; }; "clock" = { format = "{:%H:%M %a %d %b}"; tooltip-format = "{:%Y %B}\n{calendar}"; }; "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 = "{volume}X {icon}"; 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; }; "custom/notification" = { tooltip = false; format = "{} {icon}"; format-icons = { notification = ""; none = ""; dnd-notification = " "; dnd-none = ""; inhibited-notification = " "; inhibited-none = ""; dnd-inhibited-notification = " "; dnd-inhibited-none = ""; }; return-type = "json"; exec-if = "which swaync-client"; exec = "swaync-client -swb"; on-click = "sleep 0.1 && swaync-client -t -sw"; on-click-right = "sleep 0.1 && swaync-client -d -sw"; escape = true; }; }; }; 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; } /* NixOS logo styling */ #custom-nixos-logo { padding: 0; margin: 0 5px; color: #5277C3; /* NixOS Blue */ font-size: 16px; } /* Notification module styling */ #custom-notification { padding: 0 10px; color: #f38ba8; /* Pink/Red - Notifications */ } /* 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 */ } @keyframes blink { to { opacity: 0.5; } } ''; }; }