dotfiles

My PC Dotfiles & Website
commit 4de45008a6915753834aa7e1cbafbacfff8b7adc
parent 3e07880ac23c6a37353b74116b2d694b3b167c9b
Author: maydayv7 <maydayv7@gmail.com>
Date:   Tue, 10 Dec 2024 21:38:59 +0530

refactor(Hyprland): App Configuration Overhaul

+ Use `nemo` as file manager
+ Remove plymouth theme
+ Fix Document Templates

Diffstat:

MREADME.md | 1+
Mfiles/hyprland/greeter.conf | 1+
Mmodules/apps/office.nix | 9+++++++--
Mmodules/gui/default.nix | 3+--
Mmodules/gui/desktop/gnome/default.nix | 1-
Dmodules/gui/desktop/hyprland/apps/bar.nix | 366-------------------------------------------------------------------------------
Amodules/gui/desktop/hyprland/apps/browser.nix | 21+++++++++++++++++++++
Dmodules/gui/desktop/hyprland/apps/default.nix | 385-------------------------------------------------------------------------------
Amodules/gui/desktop/hyprland/apps/files.nix | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amodules/gui/desktop/hyprland/apps/media.nix | 46++++++++++++++++++++++++++++++++++++++++++++++
Amodules/gui/desktop/hyprland/apps/misc.nix | 44++++++++++++++++++++++++++++++++++++++++++++
Amodules/gui/desktop/hyprland/apps/notify.nix | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amodules/gui/desktop/hyprland/apps/panel.nix | 356+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dmodules/gui/desktop/hyprland/apps/rules.nix | 61-------------------------------------------------------------
Mmodules/gui/desktop/hyprland/apps/security.nix | 161++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Amodules/gui/desktop/hyprland/apps/settings.nix | 148+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amodules/gui/desktop/hyprland/apps/terminal.nix | 43+++++++++++++++++++++++++++++++++++++++++++
Amodules/gui/desktop/hyprland/apps/text.nix | 25+++++++++++++++++++++++++
Amodules/gui/desktop/hyprland/apps/utilities.nix | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmodules/gui/desktop/hyprland/default.nix | 198++++++++++++++++++++++++++++++-------------------------------------------------
20 files changed, 1103 insertions(+), 1016 deletions(-)

diff --git a/README.md b/README.md @@ -519,6 +519,7 @@ You can navigate to the `README`s present in the various directories to know mor - Hyprland Improvements - Transition to UWSM - Use `nixpkgs` version + - Use [`nemo`](https://community.linuxmint.com/software/view/nemo) File Manager ### v24.5 diff --git a/files/hyprland/greeter.conf b/files/hyprland/greeter.conf @@ -1,3 +1,4 @@ +env = GTK_USE_PORTAL, 0 exec-once = @greeter; hyprctl dispatch exit windowrule = fullscreen, .* windowrule = stayfocused, .* diff --git a/modules/apps/office.nix b/modules/apps/office.nix @@ -93,9 +93,14 @@ in { homeConfig.home.file = { # Document Templates - "Templates" = { + "Templates" = rec { source = files.templates; - recursive = true; + target = ".init-templates"; + onChange = '' + rm -rf ~/Templates + cp -rL ~/${target} ~/Templates + chmod -R 0777 ~/Templates + ''; }; # Font Rendering diff --git a/modules/gui/default.nix b/modules/gui/default.nix @@ -36,8 +36,7 @@ in { ## Desktop Environment (mkIf (desktop != "" && !(hasSuffix "-iso" desktop)) { - # Autostart Apps - user.persist.directories = [".config/autostart"]; + user.persist.directories = [".config/autostart" ".local/share/gvfs-metadata"]; # Utilities programs.seahorse.enable = true; diff --git a/modules/gui/desktop/gnome/default.nix b/modules/gui/desktop/gnome/default.nix @@ -167,7 +167,6 @@ in { fragments gnome-podcasts gnome-secrets - gradience gthumb lollypop mission-center diff --git a/modules/gui/desktop/hyprland/apps/bar.nix b/modules/gui/desktop/hyprland/apps/bar.nix @@ -1,366 +0,0 @@ -{ - sys, - lib, - pkgs, - files, - ... -}: let - theme = import ../theme.nix pkgs; -in rec { - ## Bar Configuration - stylix.targets.waybar = { - enable = true; - enableCenterBackColors = true; - enableLeftBackColors = true; - enableRightBackColors = true; - }; - - # Environment Setup - home.packages = [pkgs.wttrbar]; - systemd.user = { - services.waybar = { - # nix-community/home-manager/pull/5785 - Unit.After = lib.mkForce ["graphical-session.target"]; - - # nix-community/home-manager/4099 - Service.ExecStart = lib.mkForce (pkgs.writeShellScript "waybar-wrapper.sh" '' - ${files.path.systemd} - ${lib.getExe programs.waybar.package} - ''); - }; - - # nix-community/home-manager/2064 - targets.tray = { - Unit = { - Description = "Home Manager System Tray"; - Requires = ["graphical-session.target"]; - }; - }; - }; - - programs.waybar = { - enable = true; - systemd.enable = true; - package = pkgs.waybar; - style = files.hyprland.waybar; - - # Panel - settings = [ - { - layer = "top"; - position = "top"; - - height = 30; - spacing = 3; - margin-top = 3; - margin-right = 5; - margin-bottom = 5; - margin-left = 5; - - modules-left = [ - "custom/logo" - "group/users" - "hyprland/workspaces" - "hyprland/submap" - "hyprland/window" - ]; - - modules-center = ["wlr/taskbar"]; - modules-right = [ - "group/menu" - "bluetooth" - "network" - "group/media" - "backlight" - "group/power" - "custom/weather" - "clock" - "group/notify" - ]; - - "custom/logo" = { - format = ""; - tooltip = false; - on-click = "nwg-drawer"; - on-click-right = "hyprctl dispatch hycov:toggleoverview"; - }; - - "group/users" = { - orientation = "horizontal"; - modules = ["user" "custom/power"]; - drawer.transition-left-to-right = true; - }; - - user = { - format = "{user}"; - icon = true; - height = 30; - width = 30; - open-on-click = true; - }; - - "custom/power" = { - format = ""; - tooltip = false; - on-click = "wlogout -p layer-shell"; - }; - - "hyprland/workspaces" = { - all-outputs = true; - show-special = true; - format = "<small>{name}</small> {icon}"; - on-scroll-up = "hyprctl dispatch workspace m+1"; - on-scroll-down = "hyprctl dispatch workspace m-1"; - persistent-workspaces."${sys.gui.display}" = 3; - ignore-workspaces = ["special:scratch_.*"]; - format-icons = { - default = ""; - "1" = ""; - "2" = ""; - "3" = ""; - "4" = ""; - "5" = ""; - "6" = ""; - "7" = ""; - "8" = ""; - "9" = ""; - OVERVIEW = ""; - special = ""; - "special:minimized" = ""; - }; - }; - - "hyprland/submap" = { - always-on = false; - tooltip = false; - format = " {}"; - on-click = "hyprctl dispatch submap reset"; - }; - - "hyprland/window" = { - format = "{initialTitle}"; - max-length = 40; - separate-outputs = true; - rewrite = { - "bash" = "Terminal"; - "zsh" = "Terminal"; - "kitty" = "Terminal"; - "(.*) - kitty" = "Terminal"; - "clipse" = "Clipboard"; - "Kebihelp" = "Shortcuts"; - "nwg-displays" = "Displays"; - "Ulauncher(.*)" = "Launcher"; - "(.*) - Geany" = "Text Editor"; - "(.*) - Thunar" = "File Manager"; - }; - }; - - "wlr/taskbar" = { - format = "{icon}"; - icon-size = 20; - all-outputs = false; - active-first = false; - icon-theme = theme.icons.name; - markup = true; - tooltip-format = "Name: <big><b>{name}</b></big> <i>{short_state}</i>\nTitle: <b>{title}</b>"; - on-click = "activate"; - on-click-middle = "fullscreen"; - on-click-right = "close"; - ignore-list = [ - "kitty-clip" - "kitty-dropterm" - "ulauncher" - ]; - }; - - "group/menu" = { - orientation = "horizontal"; - modules = ["custom/dropdown" "keyboard-state" "tray"]; - drawer.transition-left-to-right = true; - }; - - "custom/dropdown" = { - format = ""; - tooltip = false; - }; - - tray.icon-size = 14; - keyboard-state = { - numlock = true; - capslock = true; - format = { - numlock = " N {icon}"; - capslock = "󰪛 {icon}"; - }; - format-icons = { - locked = ""; - unlocked = ""; - }; - }; - - bluetooth = { - format = ""; - format-disabled = "󰂳"; - format-connected = "󰂱 {num_connections}"; - tooltip-format = " {status}"; - tooltip-format-connected = "{device_enumerate}"; - tooltip-format-enumerate-connected = " {device_alias} 󰂄 {device_battery_percentage}%"; - on-click = "pypr show bluetooth"; - }; - - network = { - format = "{ifname}"; - format-disconnected = "󰌙"; - format-ethernet = "󰌘"; - format-wifi = "{icon}"; - format-icons = ["󰤯" "󰤟" "󰤢" "󰤥" "󰤨"]; - format-linked = "󰈁 {ifname}"; - tooltip-format = "Network: <big><b>{essid}</b></big>\nStrength: <b>{signaldBm}dBm ({signalStrength}%)</b>\nFrequency: <b>{frequency}MHz</b>\nInterface: <b>{ifname}</b>\nIP: <b>{ipaddr}/{cidr}</b>\nGateway: <b>{gwaddr}</b>\nNetmask: <b>{netmask}</b>"; - tooltip-format-disconnected = "󰌙 Disconnected"; - on-click = "pypr show network"; - }; - - "group/media" = { - orientation = "horizontal"; - modules = ["wireplumber" "mpris"]; - drawer.transition-left-to-right = true; - }; - - wireplumber = { - max-volume = 150; - scroll-step = 1; - reverse-scrolling = 1; - format = "{icon}"; - tooltip-format = "Volume: {volume}%\nDevice: {node_name}"; - format-muted = ""; - format-icons = ["" "" "󰕾" ""]; - on-click = "pypr show volume"; - }; - - mpris = { - dynamic-len = 20; - dynamic-importance-order = ["title" "position" "length" "artist"]; - dynamic-separator = ""; - format = " {player} {dynamic}"; - format-paused = "󰏤 <i>{player}</i>"; - format-stopped = ""; - tooltip-format-stopped = "Not Playing"; - }; - - backlight = { - format = "{icon}"; - tooltip-format = "Backlight: {percent}%"; - format-icons = ["" "" "" "" "" "" "" "" ""]; - on-scroll-down = "brillo -u 300000 -A 5"; - on-scroll-up = "brillo -u 300000 -U 5"; - on-click = "pypr show displays"; - }; - - "group/power" = { - orientation = "horizontal"; - modules = ["battery" "power-profiles-daemon"]; - drawer.transition-left-to-right = true; - }; - - battery = { - interval = 5; - align = 0; - rotate = 0; - format = "{icon}"; - tooltip-format = "Battery: {capacity}%"; - format-charging = ""; - format-icons = ["" "" "" "" ""]; - on-click-right = "hyprutils toggle fancy"; - states = { - good = 80; - warning = 20; - critical = 10; - }; - }; - - power-profiles-daemon = { - format = "{icon}"; - tooltip = true; - tooltip-format = "Power Profile: {profile}"; - format-icons = { - default = ""; - performance = ""; - balanced = ""; - power-saver = ""; - }; - }; - - "custom/weather" = { - format = "{}°"; - tooltip = true; - interval = 3600; - exec = "wttrbar"; - return-type = "json"; - }; - - clock = { - interval = 1; - format = " {:%H:%M:%S}"; - format-alt = " {:%I:%M  %Y, %d %B, %A}"; - tooltip-format = "<tt><small>{calendar}</small></tt>"; - calendar = { - mode = "year"; - mode-mon-col = 3; - weeks-pos = "left"; - on-scroll = 1; - format = with sys.lib.stylix.colors; { - months = "<span color='#${base06}'><b>{}</b></span>"; - days = "<span color='#${base05}'><b>{}</b></span>"; - weeks = "<span color='#${base0C}'><b>W{}</b></span>"; - weekdays = "<span color='#${base0A}'><b>{}</b></span>"; - today = "<span color='#${base08}'><b><u>{}</u></b></span>"; - }; - }; - - actions = { - on-click-right = "mode"; - on-click-forward = "tz_up"; - on-click-backward = "tz_down"; - on-scroll-up = "shift_down"; - on-scroll-down = "shift_up"; - }; - }; - - "group/notify" = { - orientation = "horizontal"; - modules = ["custom/dunst" "idle_inhibitor"]; - drawer.transition-left-to-right = true; - }; - - "custom/dunst" = { - tooltip = false; - on-click = "dunstctl history-pop"; - on-click-right = "dunstctl set-paused toggle"; - restart-interval = 1; - exec = with pkgs; "${writeShellApplication { - name = "notify"; - runtimeInputs = [coreutils dunst]; - text = '' - COUNT=$(dunstctl count waiting) - ENABLED="" - DISABLED="" - if [ "$COUNT" != 0 ]; then DISABLED=" $COUNT"; fi - if dunstctl is-paused | grep -q "false" ; then echo "$ENABLED"; else echo "$DISABLED"; fi - ''; - }}/bin/notify"; - }; - - idle_inhibitor = { - format = "{icon}"; - on-click = "hyprutils toggle idle"; - tooltip-format-activated = "Idle Inhibitor: On"; - tooltip-format-deactivated = "Idle Inhibitor: Off"; - format-icons = { - activated = ""; - deactivated = ""; - }; - }; - } - ]; - }; -} diff --git a/modules/gui/desktop/hyprland/apps/browser.nix b/modules/gui/desktop/hyprland/apps/browser.nix @@ -0,0 +1,21 @@ +{theme, ...}: { + ## Browser Configuration + apps.list = ["firefox"]; + user.homeConfig = { + programs.firefox = { + policies.ExtensionSettings = { + name = with theme; "${name}-${variant}-${accent}"; + value = { + installation_mode = "normal_installed"; + install_url = "https://addons.mozilla.org/en-US/firefox/downloads/latest/{d49033ac-8969-488c-afb0-5cdb73957f41}/latest.xpi"; + }; + }; + }; + + home.file.".mozilla/firefox/default/chrome/userChrome.css".text = '' + #TabsToolbar { + -moz-window-dragging: no-drag; + } + ''; + }; +} diff --git a/modules/gui/desktop/hyprland/apps/default.nix b/modules/gui/desktop/hyprland/apps/default.nix @@ -1,385 +0,0 @@ -{ - config, - lib, - util, - pkgs, - files, - ... -}: -with files; let - inherit (config.lib.stylix) colors; - exists = app: builtins.elem app config.apps.list; - theme = import ../theme.nix pkgs; -in { - apps.list = ["firefox"]; - gui.launcher.terminal = "kitty"; - xdg.portal.extraPortals = [pkgs.xdg-desktop-portal-gtk]; - - # File Manager - services.gnome.sushi.enable = true; - programs.nautilus-open-any-terminal = { - enable = true; - terminal = "kitty"; - }; - - environment.systemPackages = with pkgs; [ - # Apps - celluloid - clipse - custom.desktop-icons - evince - font-manager - geany - file-roller - gnome-disk-utility - hyprpicker - custom.kebihelp - lollypop - mission-center - nautilus - nwg-displays - nwg-drawer - overskride - playerctl - qalculate-gtk - remmina - shotwell - transmission_4-gtk - - # Utilities - custom.hyprutils - grim - grimblast - hyprkeys - hyprshade - pavucontrol - pyprland - slurp - wev - wl-clipboard - wl-screenrec - wlr-randr - xfce.exo - - # Network Settings - (gnome-control-center.overrideAttrs (old: { - postInstall = - old.postInstall - + '' - dir=$out/share/applications - for panel in $dir/* - do - [ "$panel" = "$dir/gnome-network-panel.desktop" ] && continue - [ "$panel" = "$dir/gnome-wifi-panel.desktop" ] && continue - [ "$panel" = "$dir/gnome-wwan-panel.desktop" ] && continue - [ "$panel" = "$dir/gnome-sharing-panel.desktop" ] && continue - [ "$panel" = "$dir/gnome-wacom-panel.desktop" ] && continue - rm "$panel" - done - ''; - })) - ]; - - user = { - # Persisted Files - persist.directories = [ - ".config/geany" - ".config/mpv" - ".config/nwg-displays" - ".config/shotwell" - ".local/share/clipboard" - ".local/share/lollypop" - ".local/share/nautilus" - ".local/share/shotwell" - ".cache/shotwell" - ]; - - homeConfig = { - imports = util.map.modules.list ./.; - - # Default Applications - xdg.mimeApps.defaultApplications = util.build.mime files.xdg.mime { - audio = ["org.gnome.Lollypop.desktop"]; - directory = ["org.gnome.Nautilus.desktop"]; - image = ["org.gnome.Shotwell-Viewer.desktop"]; - magnet = ["transmission-gtk.desktop"]; - markdown = ["geany.desktop"]; - pdf = ["org.gnome.Evince.desktop"]; - text = ["geany.desktop"]; - video = ["io.github.celluloid_player.Celluloid.desktop"]; - }; - - # App Environment - wayland.windowManager.hyprland.settings.env = [ - # Screengrab - "SLURP_ARGS, -dc ${colors.base0D}" - - # QT Apps - "QT_WAYLAND_DISABLE_WINDOWDECORATION, 1" - ]; - - # GTK Apps - dconf.settings."org/gnome/desktop/wm/preferences" = { - action-double-click-titlebar = "none"; - button-layout = "appmenu"; - }; - - # Shortcuts - wayland.windowManager.hyprland.settings.bind = let - toggle = app: "pkill ${app} || uwsm app -u ${app}.scope -- ${app}"; - runOnce = app: "pgrep ${app} || uwsm app -u ${app}.scope -- ${app}"; - in [ - "$mod SHIFT, slash, exec, ${toggle "kebihelp"} show -a" - "$mod, slash, exec, ulauncher-toggle" - "$mod, A, exec, nwg-drawer" - "$mod SHIFT, A, exec, hyprutils toggle panel" - "$mod SHIFT, C, exec, ${runOnce "hyprpicker"} -arf hex" - "$mod, D, exec, pypr toggle displays" - "$mod, F, exec, nautilus" - "$mod, N, exec, dunstctl history-pop" - "$mod, T, exec, kitty" - "$mod SHIFT, T, exec, pypr toggle term" - ''$mod, V, exec, sh -c "hyprctl clients | grep 'class: clipse' || pypr show clip"'' - "$mod, W, exec, firefox" - "$mod, Return, exec, ${runOnce "missioncenter"}" - ", XF86Calculator, exec, qalculate-gtk" - "$mod, Escape, exec, ${toggle "wlogout"} -p layer-shell" - ]; - - # Autostart - wayland.windowManager.hyprland.settings.exec-once = - ["uwsm finalize"] - ++ (builtins.map (app: "uwsm app -t service -u ${util.build.until " " app}.service -- " + app) [ - "hyprutils daemon" - - # Application Drawer - "nwg-drawer -r" - - # Clipboard Manager - "clipse -listen" - - # Desktop Icons - "dicons" - - # Pyprland - "pypr" - ]); - - # Utilities - services.playerctld.enable = true; - services.poweralertd.enable = true; - - # nix-community/home-manager/pull/5785 - systemd.user.services = { - poweralertd.Unit.After = lib.mkForce ["graphical-session.target"]; - dunst.Unit.After = lib.mkForce ["graphical-session.target"]; - }; - - # Wallpaper Daemon - services.hyprpaper = { - enable = true; - settings = { - ipc = false; - splash = true; - }; - }; - - # Terminal - programs.kitty = { - enable = true; - themeFile = with theme; "${name-alt}-${variant-alt}"; - keybindings = { - "ctrl+c" = "copy_or_interrupt"; - "kitty_mod+f" = "launch --allow-remote-control kitty +kitten search/search.py @active-kitty-window-id"; - }; - - settings = { - kitty_mod = "ctrl+shift"; - placement_strategy = "center"; - - copy_on_select = "clipboard"; - scrollback_lines = 10000; - - enable_audio_bell = "no"; - visual_bell_duration = "0.1"; - }; - }; - - wayland.windowManager.hyprland.settings.misc.swallow_regex = "^(kitty)$"; - stylix.targets.kitty = { - enable = true; - variant256Colors = true; - }; - - # Web Browser - programs.firefox = { - policies.ExtensionSettings = { - name = with theme; "${name}-${variant}-${accent}"; - value = { - installation_mode = "normal_installed"; - install_url = "https://addons.mozilla.org/en-US/firefox/downloads/latest/{d49033ac-8969-488c-afb0-5cdb73957f41}/latest.xpi"; - }; - }; - }; - - # Media - programs.mpv = { - enable = true; - defaultProfiles = ["gpu-hq"]; - scripts = [pkgs.mpvScripts.mpris]; - }; - - # Notifications - stylix.targets.dunst.enable = true; - services.dunst = let - ignore = { - history_ignore = "yes"; - fullscreen = "show"; - highlight = "#${colors.base07}"; - }; - in { - enable = true; - iconTheme = theme.icons; - settings = { - global = { - alignment = "center"; - corner_radius = 10; - follow = "mouse"; - format = "<b>%s</b>\\n%b"; - frame_width = 1; - horizontal_padding = 8; - icon_corner_radius = 10; - icon_position = "left"; - icon_theme = theme.icons.name; - indicate_hidden = "yes"; - markup = "yes"; - max_icon_size = 64; - mouse_left_click = "do_action"; - mouse_middle_click = "close_all"; - mouse_right_click = "close_current"; - offset = "5x5"; - padding = 8; - plain_text = "no"; - progress_bar_corner_radius = 10; - separator_height = 1; - show_indicators = false; - shrink = "no"; - transparency = 10; - word_wrap = "yes"; - }; - - fullscreen_delay.fullscreen = "delay"; - power = {appname = "poweralertd";} // ignore; - utility = {appname = "utility";} // ignore; - }; - }; - - # Display Temperature - services.gammastep = { - enable = true; - provider = "geoclue2"; - tray = true; - }; - - # File Manager - dconf.settings = { - "org/gtk/gtk4/settings/file-chooser".sort-directories-first = true; - "org/gnome/nautilus/icon-view" = { - captions = ["size" "date_modified" "none"]; - default-zoom-level = "medium"; - }; - - "org/gnome/nautilus/preferences" = { - click-policy = "single"; - default-folder-viewer = "icon-view"; - fts-enabled = true; - search-filter-time-type = "last_modified"; - search-view = "list-view"; - show-create-link = true; - show-delete-permanently = true; - }; - }; - - # Configuration Files - home.file = - { - # Application Drawer - ".config/nwg-drawer/drawer.css".text = hyprland.drawer; - - # Pyprland - ".config/hypr/pyprland.toml".text = hyprland.pypr; - - # Shaders - ".config/hypr/shaders" = { - source = "${pkgs.custom.hyprshaders}/share/hypr/shaders"; - recursive = true; - }; - - # Keybinds Viewer - ".config/kebihelp.json".text = util.build.theme { - inherit colors; - inherit (config.stylix) fonts; - file = hyprland.kebihelp; - }; - - # Browser - ".mozilla/firefox/default/chrome/userChrome.css".text = '' - #TabsToolbar { - -moz-window-dragging: no-drag; - } - ''; - - # Clipboard Manager - ".config/clipse/config.json".text = hyprland.clipse.config; - ".config/clipse/theme.json".text = util.build.theme { - inherit colors; - file = hyprland.clipse.theme; - }; - - # Text Editor - ".config/geany/geany.conf".text = geany.settings; - ".config/geany/keybindings.conf".text = geany.keybindings; - ".config/geany/colorschemes/theme.conf".source = with theme; "${pkgs.custom.geany-catppuccin}/share/geany/colorschemes/${name}-${variant}.conf"; - - # Terminal - ".config/kitty/search".source = pkgs.custom.kitty-search; - ".config/xfce4/helpers.rc".text = '' - TerminalEmulator=kitty - TerminalEmulatorDismissed=true - ''; - } - ## 3rd Party Apps Configuration - // { - # Discord Chat - ".config/vesktop/settings/quickCss.css" = with theme; - lib.mkIf (exists "discord") {text = ''@import url("https://${name}.github.io/discord/dist/${name}-${variant}-${accent}.theme.css");'';}; - - # Logseq Notes - ".logseq/config.edn" = with theme; - lib.mkIf (exists "notes") {text = ''{:custom-css-url "@import url('https://logseq.${name}.com/ctp-${variant}.css');"}'';}; - }; - - # Code Editor - programs.vscode = lib.mkIf (exists "vscode") { - extensions = with pkgs; [ - vscode-extensions.catppuccin.catppuccin-vsc-icons - (catppuccin-vsc.override { - inherit (theme) accent; - boldKeywords = true; - italicComments = true; - italicKeywords = true; - extraBordersEnabled = false; - workbenchMode = "default"; - bracketMode = "rainbow"; - }) - ]; - - userSettings = with theme; { - "workbench.colorTheme" = "${name-alt} ${variant-alt}"; - "workbench.iconTheme" = "${name}-${variant}"; - "terminal.external.linuxExec" = "kitty"; - }; - }; - }; - }; -} diff --git a/modules/gui/desktop/hyprland/apps/files.nix b/modules/gui/desktop/hyprland/apps/files.nix @@ -0,0 +1,57 @@ +{ + config, + util, + pkgs, + files, + ... +}: let + inherit (config.gui.launcher) terminal; + nemo = pkgs.nemo-with-extensions; +in { + ## File Manager Configuration + services.dbus.packages = [nemo]; + environment.systemPackages = [nemo] ++ (with pkgs; [cinnamon-desktop file-roller]); + + user = { + persist.directories = [".config/nemo" ".local/share/nemo"]; + homeConfig = { + xdg.mimeApps.defaultApplications = util.build.mime files.xdg.mime { + directory = ["nemo.desktop"]; + }; + + dconf.settings = { + "org/gtk/gtk4/settings/file-chooser".sort-directories-first = true; + "org/nemo/search".search-reverse-sort = false; + "org/nemo/desktop".show-desktop-icons = false; + "org/nemo/plugins".disabled-actions = ["change-background.nemo_action"]; + + "org/nemo/icon-view".captions = [ + "size" + "date_modified" + "none" + ]; + + "org/nemo/preferences" = { + click-policy = "double"; + quick-renames-with-pause-in-between = true; + }; + + "org/nemo/preferences/menu-config" = { + background-menu-open-in-terminal = false; + selection-menu-open-in-terminal = false; + }; + }; + + home.file.".local/share/nemo/actions/terminal.nemo_action".text = '' + [Nemo Action] + Name=Open in Terminal + Comment=Opens ${terminal} in the selected folder + Exec=${terminal} --working-directory=%F + Icon-Name=${terminal} + Selection=any + Extensions=dir; + EscapeSpaces=true + ''; + }; + }; +} diff --git a/modules/gui/desktop/hyprland/apps/media.nix b/modules/gui/desktop/hyprland/apps/media.nix @@ -0,0 +1,46 @@ +{ + util, + pkgs, + files, + ... +}: { + ## Media Configuration + environment.systemPackages = with pkgs; [ + celluloid + evince + lollypop + playerctl + shotwell + transmission_4-gtk + ]; + + user = { + # Persisted Files + persist.directories = [ + ".config/mpv" + ".config/shotwell" + ".local/share/lollypop" + ".local/share/shotwell" + ".cache/shotwell" + ]; + + homeConfig = { + # Default Applications + xdg.mimeApps.defaultApplications = util.build.mime files.xdg.mime { + audio = ["org.gnome.Lollypop.desktop"]; + image = ["org.gnome.Shotwell-Viewer.desktop"]; + magnet = ["transmission-gtk.desktop"]; + pdf = ["org.gnome.Evince.desktop"]; + video = ["io.github.celluloid_player.Celluloid.desktop"]; + }; + + # Media Player + services.playerctld.enable = true; + programs.mpv = { + enable = true; + defaultProfiles = ["gpu-hq"]; + scripts = [pkgs.mpvScripts.mpris]; + }; + }; + }; +} diff --git a/modules/gui/desktop/hyprland/apps/misc.nix b/modules/gui/desktop/hyprland/apps/misc.nix @@ -0,0 +1,44 @@ +{ + config, + lib, + pkgs, + theme, + ... +}: let + exists = app: builtins.elem app config.apps.list; +in { + ## 3rd Party Apps Configuration + user.homeConfig = { + # Code Editor + programs.vscode = lib.mkIf (exists "vscode") { + extensions = with pkgs; [ + vscode-extensions.catppuccin.catppuccin-vsc-icons + (catppuccin-vsc.override { + inherit (theme) accent; + boldKeywords = true; + italicComments = true; + italicKeywords = true; + extraBordersEnabled = false; + workbenchMode = "default"; + bracketMode = "rainbow"; + }) + ]; + + userSettings = with theme; { + "workbench.colorTheme" = "${name-alt} ${variant-alt}"; + "workbench.iconTheme" = "${name}-${variant}"; + "terminal.external.linuxExec" = config.gui.launcher.terminal; + }; + }; + + home.file = { + # Discord Chat + ".config/vesktop/settings/quickCss.css" = with theme; + lib.mkIf (exists "discord") {text = ''@import url("https://${name}.github.io/discord/dist/${name}-${variant}-${accent}.theme.css");'';}; + + # Logseq Notes + ".logseq/config.edn" = with theme; + lib.mkIf (exists "notes") {text = ''{:custom-css-url "@import url('https://logseq.${name}.com/ctp-${variant}.css');"}'';}; + }; + }; +} diff --git a/modules/gui/desktop/hyprland/apps/notify.nix b/modules/gui/desktop/hyprland/apps/notify.nix @@ -0,0 +1,63 @@ +{ + config, + lib, + theme, + ... +}: { + ## Notifications Configuration + user.homeConfig = { + # Alerts + services.poweralertd.enable = true; + + # Notifications Daemon + stylix.targets.dunst.enable = true; + services.dunst = let + ignore = { + history_ignore = "yes"; + fullscreen = "show"; + highlight = "#${config.lib.stylix.colors.base07}"; + }; + in { + enable = true; + iconTheme = theme.icons; + settings = { + global = { + alignment = "center"; + corner_radius = 10; + follow = "mouse"; + format = "<b>%s</b>\\n%b"; + frame_width = 1; + horizontal_padding = 8; + icon_corner_radius = 10; + icon_position = "left"; + icon_theme = theme.icons.name; + indicate_hidden = "yes"; + markup = "yes"; + max_icon_size = 64; + mouse_left_click = "do_action"; + mouse_middle_click = "close_all"; + mouse_right_click = "close_current"; + offset = "5x5"; + padding = 8; + plain_text = "no"; + progress_bar_corner_radius = 10; + separator_height = 1; + show_indicators = false; + shrink = "no"; + transparency = 10; + word_wrap = "yes"; + }; + + fullscreen_delay.fullscreen = "delay"; + power = {appname = "poweralertd";} // ignore; + utility = {appname = "utility";} // ignore; + }; + }; + + # nix-community/home-manager/pull/5785 + systemd.user.services = { + poweralertd.Unit.After = lib.mkForce ["graphical-session.target"]; + dunst.Unit.After = lib.mkForce ["graphical-session.target"]; + }; + }; +} diff --git a/modules/gui/desktop/hyprland/apps/panel.nix b/modules/gui/desktop/hyprland/apps/panel.nix @@ -0,0 +1,356 @@ +{ + config, + lib, + pkgs, + files, + ... +}: let + theme = import ../theme.nix pkgs; +in { + ## Panel Configuration + user.homeConfig = rec { + stylix.targets.waybar = { + enable = true; + enableCenterBackColors = true; + enableLeftBackColors = true; + enableRightBackColors = true; + }; + + # Environment Setup + home.packages = [pkgs.wttrbar]; + systemd.user = { + services.waybar = { + # nix-community/home-manager/pull/5785 + Unit.After = lib.mkForce ["graphical-session.target"]; + + # nix-community/home-manager/4099 + Service.ExecStart = lib.mkForce (pkgs.writeShellScript "waybar-wrapper.sh" '' + ${files.path.systemd} + ${lib.getExe programs.waybar.package} + ''); + }; + + # nix-community/home-manager/2064 + targets.tray = { + Unit = { + Description = "Home Manager System Tray"; + Requires = ["graphical-session.target"]; + }; + }; + }; + + programs.waybar = { + enable = true; + systemd.enable = true; + package = pkgs.waybar; + style = files.hyprland.waybar; + + # Panel + settings = [ + { + layer = "top"; + position = "top"; + + height = 30; + spacing = 3; + margin-top = 3; + margin-right = 5; + margin-bottom = 5; + margin-left = 5; + + modules-left = [ + "custom/logo" + "group/users" + "hyprland/workspaces" + "hyprland/submap" + "hyprland/window" + ]; + + modules-center = ["wlr/taskbar"]; + modules-right = [ + "group/menu" + "bluetooth" + "network" + "group/media" + "backlight" + "group/power" + "custom/weather" + "clock" + "group/notify" + ]; + + "custom/logo" = { + format = ""; + tooltip = false; + on-click = "nwg-drawer"; + on-click-right = "hyprctl dispatch hycov:toggleoverview"; + }; + + "group/users" = { + orientation = "horizontal"; + modules = ["user" "custom/power"]; + drawer.transition-left-to-right = true; + }; + + user = { + format = "{user}"; + icon = true; + height = 30; + width = 30; + open-on-click = true; + }; + + "custom/power" = { + format = ""; + tooltip = false; + on-click = "wlogout -p layer-shell"; + }; + + "hyprland/workspaces" = { + all-outputs = true; + show-special = true; + format = "<small>{name}</small> {icon}"; + on-scroll-up = "hyprctl dispatch workspace m+1"; + on-scroll-down = "hyprctl dispatch workspace m-1"; + persistent-workspaces."${config.gui.display}" = 3; + ignore-workspaces = ["special:scratch_.*"]; + format-icons = { + default = ""; + "1" = ""; + "2" = ""; + "3" = ""; + "4" = ""; + "5" = ""; + "6" = ""; + "7" = ""; + "8" = ""; + "9" = ""; + OVERVIEW = ""; + special = ""; + "special:minimized" = ""; + }; + }; + + "hyprland/submap" = { + always-on = false; + tooltip = false; + format = " {}"; + on-click = "hyprctl dispatch submap reset"; + }; + + "hyprland/window" = { + format = "{class}"; + max-length = 40; + separate-outputs = true; + }; + + "wlr/taskbar" = { + format = "{icon}"; + icon-size = 20; + all-outputs = false; + active-first = false; + icon-theme = theme.icons.name; + markup = true; + tooltip-format = "Name: <big><b>{name}</b></big> <i>{short_state}</i>\nTitle: <b>{title}</b>"; + on-click = "activate"; + on-click-middle = "fullscreen"; + on-click-right = "close"; + ignore-list = [ + "kitty-clip" + "kitty-dropterm" + "ulauncher" + ]; + }; + + "group/menu" = { + orientation = "horizontal"; + modules = ["custom/dropdown" "keyboard-state" "tray"]; + drawer.transition-left-to-right = true; + }; + + "custom/dropdown" = { + format = ""; + tooltip = false; + }; + + tray.icon-size = 14; + keyboard-state = { + numlock = true; + capslock = true; + format = { + numlock = " N {icon}"; + capslock = "󰪛 {icon}"; + }; + format-icons = { + locked = ""; + unlocked = ""; + }; + }; + + bluetooth = { + format = ""; + format-disabled = "󰂳"; + format-connected = "󰂱 {num_connections}"; + tooltip-format = " {status}"; + tooltip-format-connected = "{device_enumerate}"; + tooltip-format-enumerate-connected = " {device_alias} 󰂄 {device_battery_percentage}%"; + on-click = "pypr show bluetooth"; + }; + + network = { + format = "{ifname}"; + format-disconnected = "󰌙"; + format-ethernet = "󰌘"; + format-wifi = "{icon}"; + format-icons = ["󰤯" "󰤟" "󰤢" "󰤥" "󰤨"]; + format-linked = "󰈁 {ifname}"; + tooltip-format = "Network: <big><b>{essid}</b></big>\nStrength: <b>{signaldBm}dBm ({signalStrength}%)</b>\nFrequency: <b>{frequency}MHz</b>\nInterface: <b>{ifname}</b>\nIP: <b>{ipaddr}/{cidr}</b>\nGateway: <b>{gwaddr}</b>\nNetmask: <b>{netmask}</b>"; + tooltip-format-disconnected = "󰌙 Disconnected"; + on-click = "pypr show network"; + }; + + "group/media" = { + orientation = "horizontal"; + modules = ["wireplumber" "mpris"]; + drawer.transition-left-to-right = true; + }; + + wireplumber = { + max-volume = 150; + scroll-step = 1; + reverse-scrolling = 1; + format = "{icon}"; + tooltip-format = "Volume: {volume}%\nDevice: {node_name}"; + format-muted = ""; + format-icons = ["" "" "󰕾" ""]; + on-click = "pypr show volume"; + }; + + mpris = { + dynamic-len = 20; + dynamic-importance-order = ["title" "position" "length" "artist"]; + dynamic-separator = ""; + format = " {player} {dynamic}"; + format-paused = "󰏤 <i>{player}</i>"; + format-stopped = ""; + tooltip-format-stopped = "Not Playing"; + }; + + backlight = { + format = "{icon}"; + tooltip-format = "Backlight: {percent}%"; + format-icons = ["" "" "" "" "" "" "" "" ""]; + on-scroll-down = "brillo -u 300000 -A 5"; + on-scroll-up = "brillo -u 300000 -U 5"; + on-click = "pypr show displays"; + }; + + "group/power" = { + orientation = "horizontal"; + modules = ["battery" "power-profiles-daemon"]; + drawer.transition-left-to-right = true; + }; + + battery = { + interval = 5; + align = 0; + rotate = 0; + format = "{icon}"; + tooltip-format = "Battery: {capacity}%"; + format-charging = ""; + format-icons = ["" "" "" "" ""]; + on-click-right = "hyprutils toggle fancy"; + states = { + good = 80; + warning = 20; + critical = 10; + }; + }; + + power-profiles-daemon = { + format = "{icon}"; + tooltip = true; + tooltip-format = "Power Profile: {profile}"; + format-icons = { + default = ""; + performance = ""; + balanced = ""; + power-saver = ""; + }; + }; + + "custom/weather" = { + format = "{}°"; + tooltip = true; + interval = 3600; + exec = "wttrbar"; + return-type = "json"; + }; + + clock = { + interval = 1; + format = " {:%H:%M:%S}"; + format-alt = " {:%I:%M  %Y, %d %B, %A}"; + tooltip-format = "<tt><small>{calendar}</small></tt>"; + calendar = { + mode = "year"; + mode-mon-col = 3; + weeks-pos = "left"; + on-scroll = 1; + format = with config.lib.stylix.colors; { + months = "<span color='#${base06}'><b>{}</b></span>"; + days = "<span color='#${base05}'><b>{}</b></span>"; + weeks = "<span color='#${base0C}'><b>W{}</b></span>"; + weekdays = "<span color='#${base0A}'><b>{}</b></span>"; + today = "<span color='#${base08}'><b><u>{}</u></b></span>"; + }; + }; + + actions = { + on-click-right = "mode"; + on-click-forward = "tz_up"; + on-click-backward = "tz_down"; + on-scroll-up = "shift_down"; + on-scroll-down = "shift_up"; + }; + }; + + "group/notify" = { + orientation = "horizontal"; + modules = ["custom/dunst" "idle_inhibitor"]; + drawer.transition-left-to-right = true; + }; + + "custom/dunst" = { + tooltip = false; + on-click = "dunstctl history-pop"; + on-click-right = "dunstctl set-paused toggle"; + restart-interval = 1; + exec = with pkgs; "${writeShellApplication { + name = "notify"; + runtimeInputs = [coreutils dunst]; + text = '' + COUNT=$(dunstctl count waiting) + ENABLED="" + DISABLED="" + if [ "$COUNT" != 0 ]; then DISABLED=" $COUNT"; fi + if dunstctl is-paused | grep -q "false" ; then echo "$ENABLED"; else echo "$DISABLED"; fi + ''; + }}/bin/notify"; + }; + + idle_inhibitor = { + format = "{icon}"; + on-click = "hyprutils toggle idle"; + tooltip-format-activated = "Idle Inhibitor: On"; + tooltip-format-deactivated = "Idle Inhibitor: Off"; + format-icons = { + activated = ""; + deactivated = ""; + }; + }; + } + ]; + }; + }; +} diff --git a/modules/gui/desktop/hyprland/apps/rules.nix b/modules/gui/desktop/hyprland/apps/rules.nix @@ -1,61 +0,0 @@ -{lib, ...}: { - wayland.windowManager.hyprland.settings = { - ## Layer Rules - layerrule = [ - "blur, ^(logout_dialog)$" - "blur, ^(nwg-drawer)$" - "blur, ^(waybar)$" - ]; - - ## Window Rules - windowrulev2 = lib.flatten ([ - # Clipboard Manager - "float, class:^(clipse)$" - - # Application Launcher - "opacity 0.9 override, class:^(ulauncher)$" - "move cursor -50% -50%, class:^(ulauncher)$" - - # Keybinds Viewer - "pin, title:^(Kebihelp)$" - "float, title:^(Kebihelp)$" - "stayfocused, title:^(Kebihelp)$" - "opacity 0.9 override, title:^(Kebihelp)" - - # Browser Windows - "float, title:^(Picture-in-Picture)$" - "workspace special silent, title:^(Sharing Indicator)$" - "workspace special silent, title:^(.*is sharing (your screen|a window)\.)$" - - # Media Consumption - "idleinhibit focus, class:^(mpv|.*celluloid.*|.+exe)$" - "idleinhibit focus, class:^(firefox|google-chrome)$, title:^(.*YouTube.*)$" - "idleinhibit fullscreen, class:^(firefox|google-chrome)$" - - # Screen Tearing - "immediate, class:^(.+exe)$" - - # Prompt Windows - "dimaround, class:^(xdg-desktop-portal-gtk)" - ] - ++ (builtins.map (class: [ - "pin, class:^(${class})" - "dimaround, class:^(${class})" - "stayfocused, class:^(${class})" - ]) [ - "pinentry-" - "gay.vaskel.Soteria" - ]) - ++ (builtins.map (title: [ - # Dialogs - "float, title:^(${title})(.*)$" - ]) [ - "Library" - "Open File" - "Open Folder" - "Save As" - "Save File" - "Select a File" - ])); - }; -} diff --git a/modules/gui/desktop/hyprland/apps/security.nix b/modules/gui/desktop/hyprland/apps/security.nix @@ -1,5 +1,5 @@ { - sys, + config, lib, pkgs, files, @@ -8,86 +8,95 @@ inherit (lib) concatMapStringsSep getExe getExe'; locker = pkgs.swaylock-effects; in { - # Locker - stylix.targets.swaylock = { - enable = true; - useImage = true; + ## Security Configuration + # User Authentication + security = { + soteria.enable = true; + pam.services.swaylock.text = "auth include login"; }; - programs.swaylock = { - enable = true; - package = locker; - settings = { - clock = true; - indicator = true; - font = sys.stylix.fonts.sansSerif.name; - effect-vignette = "0.3:1"; + user.homeConfig = { + # Locker + stylix.targets.swaylock = { + enable = true; + useImage = true; }; - }; - # Idle Daemon - services.swayidle = let - pause = "${getExe pkgs.playerctl} pause -a"; - lock = pre: flag: "sh -c 'if ! ${getExe' pkgs.procps "pgrep"} -x swaylock; then ${pre}; ${getExe locker} -f ${flag}; fi'"; - in { - enable = true; - extraArgs = ["-w"]; - events = [ - { - event = "before-sleep"; - command = lock pause ""; - } - { - event = "lock"; - command = lock pause "--fade-in 0.2 --grace 15 --grace-no-mouse"; - } - ]; + programs.swaylock = { + enable = true; + package = locker; + settings = { + clock = true; + indicator = true; + font = config.stylix.fonts.sansSerif.name; + effect-vignette = "0.3:1"; + }; + }; - timeouts = let - audio = command: "${pkgs.writeShellScript "audio" '' - ${getExe' pkgs.pipewire "pw-cli"} info all | ${getExe pkgs.gnugrep} running - if [ $? == 1 ]; then ${command}; fi - ''}"; # Check if audio is playing - shader = getExe pkgs.hyprshade; - dpms = "${getExe' sys.programs.hyprland.package "hyprctl"} dispatch dpms"; - in [ - { - timeout = 240; # Dim display - command = audio "${shader} on dim"; - resumeCommand = "${shader} off"; - } - { - timeout = 300; # Turn off display - command = audio "${dpms} off"; - resumeCommand = "${dpms} on"; - } - { - timeout = 500; # Suspend then Hibernate device - command = audio "${dpms} on && ${lock "" ""} && ${getExe' pkgs.systemd "systemctl"} suspend-then-hibernate "; - } - ]; - }; + # Idle Daemon + services.swayidle = let + pause = "${getExe pkgs.playerctl} pause -a"; + lock = pre: flag: "sh -c 'if ! ${getExe' pkgs.procps "pgrep"} -x swaylock; then ${pre}; ${getExe locker} -f ${flag}; fi'"; + in { + enable = true; + extraArgs = ["-w"]; + events = [ + { + event = "before-sleep"; + command = lock pause ""; + } + { + event = "lock"; + command = lock pause "--fade-in 0.2 --grace 15 --grace-no-mouse"; + } + ]; - # Logout - programs.wlogout = { - enable = true; - style = - files.hyprland.wlogout - + '' - ${concatMapStringsSep "\n" ( - name: '' - #${name} { - background-image: image(url("${pkgs.wlogout}/share/wlogout/icons/${name}.png")); - } - '' - ) [ - "lock" - "logout" - "suspend" - "hibernate" - "shutdown" - "reboot" - ]} - ''; + timeouts = let + audio = command: "${pkgs.writeShellScript "audio" '' + ${getExe' pkgs.pipewire "pw-cli"} info all | ${getExe pkgs.gnugrep} running + if [ $? == 1 ]; then ${command}; fi + ''}"; # Check if audio is playing + shader = getExe pkgs.hyprshade; + dpms = "${getExe' config.programs.hyprland.package "hyprctl"} dispatch dpms"; + in [ + { + timeout = 240; # Dim display + command = audio "${shader} on dim"; + resumeCommand = "${shader} off"; + } + { + timeout = 300; # Turn off display + command = audio "${dpms} off"; + resumeCommand = "${dpms} on"; + } + { + timeout = 500; # Suspend then Hibernate device + command = audio "${dpms} on && ${lock "" ""} && ${getExe' pkgs.systemd "systemctl"} suspend-then-hibernate "; + } + ]; + }; + + # Logout + programs.wlogout = { + enable = true; + style = + files.hyprland.wlogout + + '' + ${concatMapStringsSep "\n" ( + name: '' + #${name} { + background-image: image(url("${pkgs.wlogout}/share/wlogout/icons/${name}.png")); + } + '' + ) [ + "lock" + "logout" + "suspend" + "hibernate" + "shutdown" + "reboot" + ]} + ''; + }; }; } diff --git a/modules/gui/desktop/hyprland/apps/settings.nix b/modules/gui/desktop/hyprland/apps/settings.nix @@ -0,0 +1,148 @@ +{ + config, + lib, + util, + pkgs, + files, + theme, + ... +}: { + ## App Environment + xdg.portal.extraPortals = [pkgs.xdg-desktop-portal-gtk]; + + # Desktop Integration + stylix.base16Scheme = files.colors.catppuccin; + gui = with theme; { + fonts.enable = true; + inherit (theme) icons; + launcher.theme = theme.name; + + gtk = { + enable = true; + theme = gtk; + }; + + qt = { + enable = true; + theme = qt; + }; + }; + + user.homeConfig = { + # GTK Apps + dconf.settings."org/gnome/desktop/wm/preferences" = { + action-double-click-titlebar = "none"; + button-layout = "appmenu"; + }; + + wayland.windowManager.hyprland.settings = { + env = [ + # QT Apps + "QT_WAYLAND_DISABLE_WINDOWDECORATION, 1" + + # Screengrab + "SLURP_ARGS, -dc ${config.lib.stylix.colors.base0D}" + ]; + + ## Shortcuts + bind = let + toggle = app: "pkill ${app} || uwsm app -u ${app}.scope -- ${app}"; + runOnce = app: "pgrep ${app} || uwsm app -u ${app}.scope -- ${app}"; + in [ + "$mod SHIFT, slash, exec, ${toggle "kebihelp"} show -a" + "$mod, slash, exec, ulauncher-toggle" + "$mod, A, exec, nwg-drawer" + "$mod SHIFT, A, exec, hyprutils toggle panel" + "$mod SHIFT, C, exec, ${runOnce "hyprpicker"} -arf hex" + "$mod, D, exec, pypr toggle displays" + "$mod, F, exec, nemo" + "$mod, N, exec, dunstctl history-pop" + "$mod, T, exec, kitty" + "$mod SHIFT, T, exec, pypr toggle term" + ''$mod, V, exec, sh -c "hyprctl clients | grep 'class: clipse' || pypr show clip"'' + "$mod, W, exec, firefox" + "$mod, Return, exec, ${runOnce "missioncenter"}" + ", XF86Calculator, exec, qalculate-gtk" + "$mod, Escape, exec, ${toggle "wlogout"} -p layer-shell" + ]; + + ## Autostart + exec-once = + ["uwsm finalize"] + ++ (builtins.map (app: "uwsm app -t service -u ${util.build.until " " app}.service -- " + app) [ + "hyprutils daemon" + + # Application Drawer + "nwg-drawer -r" + + # Clipboard Manager + "clipse -listen" + + # Desktop Icons + "dicons" + + # Pyprland + "pypr" + ]); + + ## Layer Rules + layerrule = [ + "blur, ^(logout_dialog)$" + "blur, ^(nwg-drawer)$" + "blur, ^(waybar)$" + ]; + + ## Window Rules + windowrulev2 = lib.flatten ([ + # Clipboard Manager + "float, class:^(clipse)$" + + # Application Launcher + "opacity 0.9 override, class:^(ulauncher)$" + "move cursor -50% -50%, class:^(ulauncher)$" + + # Keybinds Viewer + "pin, title:^(Kebihelp)$" + "float, title:^(Kebihelp)$" + "stayfocused, title:^(Kebihelp)$" + "opacity 0.9 override, title:^(Kebihelp)" + + # Browser Windows + "float, title:^(Picture-in-Picture)$" + "workspace special silent, title:^(Sharing Indicator)$" + "workspace special silent, title:^(.*is sharing (your screen|a window)\.)$" + + # Media Consumption + "idleinhibit focus, class:^(mpv|.*celluloid.*|.+exe)$" + "idleinhibit focus, class:^(firefox|google-chrome)$, title:^(.*YouTube.*)$" + "idleinhibit fullscreen, class:^(firefox|google-chrome)$" + + # Screen Tearing + "immediate, class:^(.+exe)$" + + # Prompt Windows + "dimaround, class:^(xdg-desktop-portal-gtk)" + ] + ++ (builtins.map (class: [ + "pin, class:^(${class})" + "dimaround, class:^(${class})" + "stayfocused, class:^(${class})" + ]) [ + "pinentry-" + "gay.vaskel.Soteria" + ]) + ++ (builtins.map (title: [ + # Dialogs + "float, title:^(${title})(.*)$" + ]) [ + "Library" + "Open File" + "Open Folder" + "Save As" + "Save File" + "Select a File" + ".*Properties" + ])); + }; + }; +} diff --git a/modules/gui/desktop/hyprland/apps/terminal.nix b/modules/gui/desktop/hyprland/apps/terminal.nix @@ -0,0 +1,43 @@ +{ + pkgs, + theme, + ... +}: { + ## Terminal Configuration + gui.launcher.terminal = "kitty"; + user.homeConfig = { + programs.kitty = { + enable = true; + themeFile = with theme; "${name-alt}-${variant-alt}"; + keybindings = { + "ctrl+c" = "copy_or_interrupt"; + "kitty_mod+f" = "launch --allow-remote-control kitty +kitten search/search.py @active-kitty-window-id"; + }; + + settings = { + kitty_mod = "ctrl+shift"; + placement_strategy = "center"; + + copy_on_select = "clipboard"; + scrollback_lines = 10000; + + enable_audio_bell = "no"; + visual_bell_duration = "0.1"; + }; + }; + + wayland.windowManager.hyprland.settings.misc.swallow_regex = "^(kitty)$"; + stylix.targets.kitty = { + enable = true; + variant256Colors = true; + }; + + home.file = { + ".config/kitty/search".source = pkgs.custom.kitty-search; + ".config/xfce4/helpers.rc".text = '' + TerminalEmulator=kitty + TerminalEmulatorDismissed=true + ''; + }; + }; +} diff --git a/modules/gui/desktop/hyprland/apps/text.nix b/modules/gui/desktop/hyprland/apps/text.nix @@ -0,0 +1,25 @@ +{ + pkgs, + util, + files, + theme, + ... +}: { + ## Text Editor Configuration + environment.systemPackages = [pkgs.geany]; + user = { + persist.directories = [".config/geany"]; + homeConfig = { + xdg.mimeApps.defaultApplications = util.build.mime files.xdg.mime { + markdown = ["geany.desktop"]; + text = ["geany.desktop"]; + }; + + home.file = with files.geany; { + ".config/geany/geany.conf".text = settings; + ".config/geany/keybindings.conf".text = keybindings; + ".config/geany/colorschemes/theme.conf".source = with theme; "${pkgs.custom.geany-catppuccin}/share/geany/colorschemes/${name}-${variant}.conf"; + }; + }; + }; +} diff --git a/modules/gui/desktop/hyprland/apps/utilities.nix b/modules/gui/desktop/hyprland/apps/utilities.nix @@ -0,0 +1,130 @@ +{ + config, + util, + pkgs, + files, + ... +}: let + inherit (util.build) theme; + inherit (config.lib.stylix) colors; +in { + environment.systemPackages = with pkgs; [ + # Apps + clipse + custom.desktop-icons + custom.kebihelp + font-manager + gnome-disk-utility + hyprpicker + mission-center + nwg-displays + nwg-drawer + overskride + qalculate-gtk + remmina + + # Utilities + custom.hyprutils + grim + grimblast + hyprkeys + hyprshade + pavucontrol + pyprland + slurp + wev + wl-clipboard + wl-screenrec + wlr-randr + xfce.exo + + # Network Settings + (gnome-control-center.overrideAttrs (old: { + postInstall = + old.postInstall + + '' + dir=$out/share/applications + for panel in $dir/* + do + [ "$panel" = "$dir/gnome-network-panel.desktop" ] && continue + [ "$panel" = "$dir/gnome-wifi-panel.desktop" ] && continue + [ "$panel" = "$dir/gnome-wwan-panel.desktop" ] && continue + [ "$panel" = "$dir/gnome-sharing-panel.desktop" ] && continue + [ "$panel" = "$dir/gnome-wacom-panel.desktop" ] && continue + rm "$panel" + done + ''; + })) + ]; + + ## Essential Utilities + services = { + # Power + power-profiles-daemon.enable = true; + upower.enable = true; + + # Location + geoclue2 = { + enable = true; + geoProviderUrl = "https://beacondb.net/v1/geolocate"; + }; + }; + location.provider = "geoclue2"; + + # Backlight + user.groups = ["input" "video"]; + hardware.brillo.enable = true; + + user = { + persist.directories = [ + ".config/nwg-displays" + ".local/share/clipboard" + ]; + + homeConfig = { + # Wallpaper Daemon + services.hyprpaper = { + enable = true; + settings = { + ipc = false; + splash = true; + }; + }; + + # Display Temperature + services.gammastep = { + enable = true; + provider = "geoclue2"; + tray = true; + }; + + home.file = with files.hyprland; { + # Application Drawer + ".config/nwg-drawer/drawer.css".text = drawer; + + # Pyprland + ".config/hypr/pyprland.toml".text = pypr; + + # Shaders + ".config/hypr/shaders" = { + source = "${pkgs.custom.hyprshaders}/share/hypr/shaders"; + recursive = true; + }; + + # Keybinds Viewer + ".config/kebihelp.json".text = theme { + inherit colors; + inherit (config.stylix) fonts; + file = kebihelp; + }; + + # Clipboard Manager + ".config/clipse/config.json".text = clipse.config; + ".config/clipse/theme.json".text = theme { + inherit colors; + file = clipse.theme; + }; + }; + }; + }; +} diff --git a/modules/gui/desktop/hyprland/default.nix b/modules/gui/desktop/hyprland/default.nix @@ -11,133 +11,85 @@ theme = import ./theme.nix pkgs; in { ## Hyprland Configuration ## - config = mkIf (desktop == "hyprland") (mkMerge [ - ## Environment Setup - rec { - gui = { - xorg.enable = false; - wayland.enable = true; - launcher = { - enable = true; - shadow = false; - }; - }; - - programs = { - # WM - hyprland = { - enable = true; - withUWSM = true; - xwayland.enable = true; - package = pkgs.hyprland; - }; - - # Login - regreet = { - enable = true; - package = pkgs.greetd.regreet; - settings.commands = { - reboot = ["systemctl" "reboot"]; - poweroff = ["systemctl" "poweroff"]; + config = mkIf (desktop == "hyprland") ( + mkMerge ( + # App Configuration + (builtins.map (path: import path (args // {inherit theme;})) + (util.map.modules.list ./apps)) + ++ [ + ## Environment Setup + rec { + gui = { + xorg.enable = false; + wayland.enable = true; + launcher = { + enable = true; + shadow = false; + }; }; - }; - }; - - services = { - # Session - displayManager.defaultSession = "Desktop"; - xserver = { - desktopManager.runXdgAutostartIfNone = true; - displayManager.session = [ - { - name = "Desktop"; - manage = "desktop"; - start = "uwsm start -S -F Hyprland &> /dev/null"; - } - ]; - }; - - # Greeter - greetd.settings.default_session.command = with programs; - mkForce "${getExe hyprland.package} --config ${ - pkgs.writeText "greeter.conf" - (replaceStrings ["@greeter"] [(getExe regreet.package)] - (util.build.theme { - inherit (config.lib.stylix) colors; - file = files.hyprland.greeter; - })) - } &> /dev/null"; - }; - } - - { - # Boot Splash - boot.plymouth = { - theme = with theme; "${name}-${variant}"; - themePackages = [(pkgs.catppuccin-plymouth.override {inherit (theme) variant;})]; - }; - - # Greeter - environment.persist.directories = ["/var/cache/regreet"]; - stylix.targets.regreet.enable = true; - programs.regreet = { - extraCss = mkForce ""; - theme = mkForce theme.gtk; - iconTheme = mkForce theme.icons; - }; - } - - { - # Settings - user.persist.directories = [".config/hypr"]; - user.homeConfig.imports = [./settings]; - # Desktop Integration - stylix.base16Scheme = files.colors.catppuccin; - gui = with theme; { - fonts.enable = true; - inherit (theme) icons; - launcher.theme = theme.name; + programs = { + # WM + hyprland = { + enable = true; + withUWSM = true; + xwayland.enable = true; + package = pkgs.hyprland; + }; - gtk = { - enable = true; - theme = gtk; - }; - - qt = { - enable = true; - theme = qt; - }; - }; - - ## Essential Utilities - xdg.portal.extraPortals = [pkgs.xdg-desktop-portal-gtk]; - services = { - # Battery - power-profiles-daemon.enable = true; - upower.enable = true; - - # Location - geoclue2 = { - enable = true; - geoProviderUrl = "https://beacondb.net/v1/geolocate"; - }; - }; - location.provider = "geoclue2"; + # Login + regreet = { + enable = true; + package = pkgs.greetd.regreet; + settings.commands = { + reboot = ["systemctl" "reboot"]; + poweroff = ["systemctl" "poweroff"]; + }; + }; + }; - # Backlight - user.groups = ["input" "video"]; - hardware.brillo.enable = true; + services = { + # Session + displayManager.defaultSession = "Desktop"; + xserver = { + desktopManager.runXdgAutostartIfNone = true; + displayManager.session = [ + { + name = "Desktop"; + manage = "desktop"; + start = "uwsm start -S -F Hyprland &> /dev/null"; + } + ]; + }; - # Security - security.soteria.enable = true; - security.pam.services = { - greetd.enableGnomeKeyring = true; - swaylock.text = "auth include login"; - }; - } + # Greeter + greetd.settings.default_session.command = with programs; + mkForce "${getExe hyprland.package} --config ${ + pkgs.writeText "greeter.conf" + (replaceStrings ["@greeter"] [(getExe regreet.package)] + (util.build.theme { + inherit (config.lib.stylix) colors; + file = files.hyprland.greeter; + })) + } &> /dev/null"; + }; + } + { + environment.persist.directories = ["/var/cache/regreet"]; + stylix.targets.regreet.enable = true; + programs.regreet = { + extraCss = mkForce ""; + theme = mkForce theme.gtk; + iconTheme = mkForce theme.icons; + }; - ## Application Configuration - (import ./apps args) - ]); + # Settings + user = { + persist.directories = [".config/hypr"]; + homeConfig.imports = [./settings]; + }; + } + ] + ) + ); }