diff --git a/modules/gnome/home.nix b/modules/gnome/home.nix new file mode 100644 index 0000000..87f3e07 --- /dev/null +++ b/modules/gnome/home.nix @@ -0,0 +1,254 @@ +{ config, pkgs, lib, ... }: + +let + cfg = config.gnome-home-custom; + # Import gvariant helpers for dconf types + mkTuple = lib.hm.gvariant.mkTuple; + mkUint32 = lib.hm.gvariant.mkUint32; +in + +{ + options.gnome-home-custom = { + alwaysShowTopBar = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Always show the GNOME top bar (status bar). When false, uses Hide Top Bar extension to auto-hide it."; + }; + }; + + config = { + # GNOME configuration via dconf + dconf.settings = { + # Interface settings + "org/gnome/desktop/interface" = { + color-scheme = "prefer-dark"; + gtk-theme = "Adwaita-dark"; + cursor-theme = "Adwaita"; + }; + + # Touchpad settings + "org/gnome/desktop/peripherals/touchpad" = { + tap-to-click = false; + natural-scroll = true; + }; + + # Input sources - US English, Chinese Pinyin, Japanese + "org/gnome/desktop/input-sources" = { + sources = [ + (mkTuple [ "xkb" "us" ]) + (mkTuple [ "ibus" "libpinyin" ]) + ]; + xkb-options = [ "" ]; + }; + + # GNOME Shell configuration + "org/gnome/shell" = { + disable-user-extensions = false; + enabled-extensions = + (lib.optionals (!cfg.alwaysShowTopBar) [ "hidetopbar@mathieu.bidon.ca" ]) + ++ [ + "pano@elhan.io" + ]; + favorite-apps = [ + "thunar.desktop" + "com.mitchellh.ghostty.desktop" + "cursor.desktop" + "firefox.desktop" + "obsidian.desktop" + "org.keepassxc.KeePassXC.desktop" + ]; + }; + + # Hide Top Bar extension configuration + # Always hide the top bar except in Activities Overview (Super key) + "org/gnome/shell/extensions/hidetopbar" = lib.mkIf (!cfg.alwaysShowTopBar) { + enable-intellihide = false; + enable-active-window = false; + mouse-sensitive = false; + mouse-sensitive-fullscreen-window = false; + }; + + # Pano clipboard manager extension configuration + "org/gnome/shell/extensions/pano" = { + # Keybinding to open clipboard panel + global-shortcut = [ "c" ]; + # Keep 100 items in clipboard history + history-length = mkUint32 100; + }; + + # Desktop background configuration + "org/gnome/desktop/background" = { + picture-uri = "file:///home/yanlin/Documents/app-state/nixos-nineish-dark@4k.png"; + picture-uri-dark = "file:///home/yanlin/Documents/app-state/nixos-nineish-dark@4k.png"; + picture-options = "zoom"; + }; + + # Disable GNOME Software auto-updates + "org/gnome/software" = { + download-updates = false; + download-updates-notify = false; + }; + + # Notification settings + "org/gnome/desktop/notifications" = { + show-banners = false; # Disable notification popups (still logged in notification center) + }; + + # Sound settings + "org/gnome/desktop/sound" = { + event-sounds = false; # Disable notification sounds + }; + + # Screen timeout settings + # Setup: ThinkPad laptop (lid closed) + 4K TV as external monitor + "org/gnome/desktop/session" = { + idle-delay = mkUint32 900; # Screen blank after 15 minutes (900 seconds) + }; + + "org/gnome/settings-daemon/plugins/power" = { + idle-dim = false; # Don't dim screen before blanking + }; + + # IBus libpinyin (Chinese Pinyin) configuration + "com/github/libpinyin/ibus-libpinyin/libpinyin" = { + lookup-table-page-size = 7; # Number of candidates displayed (default: 5) + }; + + }; + + # Configure cursor theme system-wide + home.pointerCursor = { + name = "Adwaita"; + package = pkgs.adwaita-icon-theme; + size = 24; + gtk.enable = true; + x11.enable = true; + }; + + # Configure GTK theme and icon theme + gtk = { + enable = true; + theme = { + name = "Adwaita-dark"; + package = pkgs.gnome-themes-extra; + }; + iconTheme = { + package = pkgs.papirus-icon-theme; + name = "Papirus-Dark"; + }; + gtk3.extraConfig = { + gtk-application-prefer-dark-theme = 1; + }; + gtk4.extraConfig = { + gtk-application-prefer-dark-theme = 1; + }; + }; + + # Configure XDG user directories + xdg.userDirs = { + enable = true; + createDirectories = true; + + # Keep these directories + desktop = "${config.home.homeDirectory}/Desktop"; + documents = "${config.home.homeDirectory}/Documents"; + download = "${config.home.homeDirectory}/Downloads"; + + # Disable unwanted directories + music = null; + videos = null; + publicShare = null; + templates = null; + }; + + # GNOME Shell extensions and Qt theming packages + home.packages = with pkgs; + (lib.optionals (!cfg.alwaysShowTopBar) [ gnomeExtensions.hide-top-bar ]) + ++ [ + gnomeExtensions.pano + xfce.thunar + ]; + + # Custom desktop file for opening text files with Neovim in Ghostty + home.file.".local/share/applications/nvim-ghostty.desktop".text = '' + [Desktop Entry] + Type=Application + Name=Neovim (Ghostty) + Comment=Edit text files with Neovim in Ghostty terminal + Exec=ghostty -e nvim %F + Terminal=false + Categories=TextEditor;Utility; + MimeType=text/plain;text/markdown;text/x-nix;text/x-shellscript;text/x-log;text/csv;text/html;text/css;text/xml;text/x-python;text/x-python3;text/x-c;text/x-c++src;text/x-chdr;text/x-c++hdr;text/x-java;text/x-tex;text/x-latex;application/x-yaml;application/json;application/xml;application/xhtml+xml;application/javascript;application/typescript;application/x-python;application/x-ipynb+json;application/toml;application/x-npy; + Icon=nvim + ''; + + # Configure default applications for file types + xdg.mimeApps = { + enable = true; + defaultApplications = { + # Directories + "inode/directory" = "Thunar.desktop"; + + # PDF documents + "application/pdf" = "org.gnome.Evince.desktop"; + + # Images + "image/png" = "org.gnome.Loupe.desktop"; + "image/jpeg" = "org.gnome.Loupe.desktop"; + "image/jpg" = "org.gnome.Loupe.desktop"; + "image/gif" = "org.gnome.Loupe.desktop"; + "image/webp" = "org.gnome.Loupe.desktop"; + "image/svg+xml" = "org.gnome.Loupe.desktop"; + "image/bmp" = "org.gnome.Loupe.desktop"; + "image/heic" = "org.gnome.Loupe.desktop"; + "image/heif" = "org.gnome.Loupe.desktop"; + "image/tiff" = "org.gnome.Loupe.desktop"; + + # Videos + "video/mp4" = "vlc.desktop"; + "video/mpeg" = "vlc.desktop"; + "video/quicktime" = "vlc.desktop"; + "video/x-msvideo" = "vlc.desktop"; + "video/x-matroska" = "vlc.desktop"; + "video/webm" = "vlc.desktop"; + "video/ogg" = "vlc.desktop"; + "video/x-flv" = "vlc.desktop"; + "video/3gpp" = "vlc.desktop"; + + # Text and code files + "text/plain" = "nvim-ghostty.desktop"; + "text/markdown" = "nvim-ghostty.desktop"; + "text/x-nix" = "nvim-ghostty.desktop"; + "text/x-shellscript" = "nvim-ghostty.desktop"; + "text/x-log" = "nvim-ghostty.desktop"; + "text/csv" = "nvim-ghostty.desktop"; + "text/html" = "nvim-ghostty.desktop"; + "text/css" = "nvim-ghostty.desktop"; + "text/xml" = "nvim-ghostty.desktop"; + "text/x-python" = "nvim-ghostty.desktop"; + "text/x-python3" = "nvim-ghostty.desktop"; + "text/x-c" = "nvim-ghostty.desktop"; + "text/x-c++src" = "nvim-ghostty.desktop"; + "text/x-chdr" = "nvim-ghostty.desktop"; + "text/x-c++hdr" = "nvim-ghostty.desktop"; + "text/x-java" = "nvim-ghostty.desktop"; + "text/x-tex" = "nvim-ghostty.desktop"; + "text/x-latex" = "nvim-ghostty.desktop"; + "application/x-yaml" = "nvim-ghostty.desktop"; + "application/json" = "nvim-ghostty.desktop"; + "application/xml" = "nvim-ghostty.desktop"; + "application/xhtml+xml" = "nvim-ghostty.desktop"; + "application/javascript" = "nvim-ghostty.desktop"; + "application/typescript" = "nvim-ghostty.desktop"; + "application/x-python" = "nvim-ghostty.desktop"; + "application/x-ipynb+json" = "nvim-ghostty.desktop"; + "application/toml" = "nvim-ghostty.desktop"; + "application/x-npy" = "nvim-ghostty.desktop"; + + # Terminal emulator + "x-scheme-handler/terminal" = "com.mitchellh.ghostty.desktop"; + }; + }; + + }; +} diff --git a/modules/gnome/system.nix b/modules/gnome/system.nix new file mode 100644 index 0000000..0a3e824 --- /dev/null +++ b/modules/gnome/system.nix @@ -0,0 +1,114 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.gnome-system-custom; + # Import gvariant for dconf types + mkTuple = lib.gvariant.mkTuple; + mkUint32 = lib.gvariant.mkUint32; + mkEmptyArray = lib.gvariant.mkEmptyArray; +in + +{ + options.gnome-system-custom = { + enableDisplayManager = mkOption { + type = types.bool; + default = true; + description = "Enable GDM display manager"; + }; + }; + + config = { + # GNOME Desktop Environment + services.xserver.enable = true; + services.displayManager.gdm.enable = mkIf cfg.enableDisplayManager true; + services.desktopManager.gnome.enable = true; + + # Keyboard layout + services.xserver.xkb = { + layout = "us"; + options = ""; + }; + + # Exclude unwanted GNOME default packages + environment.gnome.excludePackages = with pkgs; [ + gnome-tour + gnome-console # terminal (using Ghostty instead) + gnome-text-editor # text editor (using Neovim instead) + gnome-connections # remote desktop client + gnome-font-viewer # font viewer + seahorse # passwords and keys + baobab # disk usage analyzer + gnome-disk-utility # disks + gnome-logs # logs viewer + gnome-system-monitor # system monitor + decibels # audio player + epiphany # GNOME web browser + file-roller # archive manager + geary # GNOME email client + gnome-music + gnome-photos + gnome-maps + gnome-weather + gnome-contacts + gnome-clocks + gnome-calculator + gnome-calendar + gnome-characters + simple-scan + snapshot # camera + totem # video player + yelp # help viewer + nautilus # file manager (using Thunar instead) + ]; + + # XDG portal for proper desktop integration + xdg.portal = { + enable = true; + extraPortals = with pkgs; [ + xdg-desktop-portal-gnome + xdg-desktop-portal-gtk + ]; + }; + + # Touchpad configuration + services.libinput = { + enable = true; + touchpad = { + naturalScrolling = true; + tapping = false; + }; + }; + + # Input method configuration for GNOME + i18n.inputMethod = { + enable = true; + type = "ibus"; + ibus.engines = with pkgs.ibus-engines; [ + libpinyin + ]; + }; + + # GNOME dconf settings + programs.dconf.profiles.user.databases = [{ + settings = { + "org/gnome/settings-daemon/plugins/power" = { + sleep-inactive-ac-type = "nothing"; + }; + "org/gnome/desktop/a11y/applications" = { + screen-keyboard-enabled = false; + }; + "org/gnome/desktop/peripherals/mouse" = { + accel-profile = "flat"; + }; + }; + }]; + + # System packages for GNOME + environment.systemPackages = with pkgs; [ + hicolor-icon-theme # Fallback icon theme + ]; + + }; +} diff --git a/modules/hyprland/home.nix b/modules/hyprland/home.nix new file mode 100644 index 0000000..9c49659 --- /dev/null +++ b/modules/hyprland/home.nix @@ -0,0 +1,608 @@ +{ 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; + } + } + + ''; + }; +} diff --git a/modules/hyprland/system.nix b/modules/hyprland/system.nix new file mode 100644 index 0000000..300c656 --- /dev/null +++ b/modules/hyprland/system.nix @@ -0,0 +1,119 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.hyprland-system-custom; +in + +{ + options.hyprland-system-custom = { + enableDisplayManager = mkOption { + type = types.bool; + default = true; + description = "Enable greetd display manager"; + }; + }; + + config = { + # Enable Hyprland + programs.hyprland = { + enable = true; + xwayland.enable = true; + }; + + # Display manager: greetd + tuigreet + services.greetd = mkIf cfg.enableDisplayManager { + enable = true; + settings = { + default_session = { + command = "${pkgs.tuigreet}/bin/tuigreet --time --cmd Hyprland"; + user = "greeter"; + }; + }; + }; + + # XDG portals for screen sharing, file picker, etc. + xdg.portal = { + enable = true; + extraPortals = [ + pkgs.xdg-desktop-portal-hyprland + pkgs.xdg-desktop-portal-gtk + ]; + config = { + common = { + default = "hyprland;gtk"; + }; + hyprland = { + default = "hyprland;gtk"; + }; + }; + }; + + # Configure touchpad settings + services.libinput = { + enable = true; + touchpad = { + naturalScrolling = true; + tapping = false; + disableWhileTyping = true; + }; + }; + + # GNOME Keyring with PAM integration for WiFi password storage + services.gnome.gnome-keyring.enable = true; + security.pam.services.greetd.enableGnomeKeyring = mkIf cfg.enableDisplayManager true; + + # Input method configuration for Hyprland + i18n.inputMethod = { + enable = true; + type = "fcitx5"; + fcitx5.addons = with pkgs; [ + fcitx5-rime + fcitx5-gtk + ]; + }; + + # System packages for Hyprland + environment.systemPackages = with pkgs; [ + hyprland + hypridle + hyprlock + hyprpaper + tuigreet + waybar + wofi + networkmanagerapplet + pavucontrol + nwg-displays + swaynotificationcenter + qt5.qtwayland + qt6.qtwayland + iptables + ]; + + # Printing with Windows Samba printer support + services.printing = { + enable = true; + browsing = true; + drivers = with pkgs; [ + cups-filters + gutenprint + samba # SMB backend for Windows printers + ]; + }; + + # Samba for SMB printer protocol + services.samba.enable = true; + + # Avahi for network printer discovery + services.avahi = { + enable = true; + nssmdns4 = true; + openFirewall = true; + }; + + # Printer management GUI + programs.system-config-printer.enable = true; + }; +}