many improvements
This commit is contained in:
		| @@ -1,25 +0,0 @@ | ||||
| {pkgs, ...}: | ||||
| { | ||||
|   # Add a udev rule that launches a backup using restic when a specific USB device (the backup drive) is plugged in | ||||
|  | ||||
|   environment.systemPackages = with pkgs; [ | ||||
|       restic | ||||
|   ]; | ||||
|  | ||||
|   # the udev rule: | ||||
|   services.udev.extraRules = '' | ||||
|     ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="backup-restic", TAG+="systemd", ENV{SYSTEMD_WANTS}="backup-restic.service" | ||||
|   ''; | ||||
|  | ||||
|   # the systemd service: | ||||
|   systemd.services.backup-restic = { | ||||
|     description = "Backup using restic (triggered when USB drive is plugged in)"; | ||||
|     after = [ "local-fs.target" ]; | ||||
|     wantedBy = [ "multi-user.target" ]; | ||||
|     serviceConfig = { | ||||
|       Type = "oneshot"; | ||||
|       # TODO: adapt command | ||||
|       ExecStart = "${pkgs.restic}/bin/restic backup /home/username"; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
| @@ -28,9 +28,9 @@ | ||||
|     profiles.default = { | ||||
|       search = { | ||||
|         force = true; | ||||
|         default = "DuckDuckGo"; | ||||
|         privateDefault = "DuckDuckGo"; | ||||
|         order = ["DuckDuckGo" "Google"]; | ||||
|         default = "ddg"; | ||||
|         privateDefault = "ddg"; | ||||
|         order = ["ddg" "google"]; | ||||
|       }; | ||||
|       settings = { | ||||
|         "browser.startup.homepage" = "about:home"; | ||||
|   | ||||
| @@ -1,153 +1,192 @@ | ||||
| {pkgs, ...}: | ||||
| let | ||||
|   baseExtensions = with pkgs.vscode-extensions; [ | ||||
|     # QOL | ||||
|     mhutchie.git-graph | ||||
|     redhat.vscode-yaml | ||||
|     github.copilot | ||||
|     github.copilot-chat | ||||
|  | ||||
|     # Nix environment selector | ||||
|     arrterian.nix-env-selector | ||||
|   ]; | ||||
|   baseSettings = { | ||||
|     # visual | ||||
|     "window.menuBarVisibility" = "toggle"; | ||||
|  | ||||
|     "editor.fontFamily" = "'FiraCode Nerd Font Mono', 'monospace', monospace"; | ||||
|     "terminal.integrated.fontFamily" = "FiraCode Nerd Font Mono"; | ||||
|     "workbench.iconTheme" = "vs-seti"; | ||||
|  | ||||
|     # telemetry | ||||
|     "telemetry.enableCrashReporter" = false; | ||||
|     "telemetry.enableTelemetry" = false; | ||||
|     "redhat.telemetry.enabled" = false; | ||||
|  | ||||
|     # editor QOL | ||||
|     "security.workspace.trust.untrustedFiles" = "open"; | ||||
|     "editor.wordWrap" = "on"; | ||||
|     "editor.suggestSelection" = "first"; | ||||
|     "editor.renderWhitespace" = "none"; | ||||
|     "editor.acceptSuggestionOnEnter" = "off"; | ||||
|     "editor.fontLigatures" = true; | ||||
|     "editor.inlineSuggest.enabled" = true; | ||||
|     "editor.bracketPairColorization.enabled" = true; | ||||
|     "editor.unicodeHighlight.nonBasicASCII" = false; | ||||
|     "editor.unicodeHighlight.invisibleCharacters" = false; | ||||
|     "editor.unicodeHighlight.ambiguousCharacters" = false; | ||||
|  | ||||
|     "files.autoSave" = "onWindowChange"; | ||||
|     "files.autoSaveDelay" = 1000; | ||||
|     "files.insertFinalNewline" = true; | ||||
|     "files.trimTrailingWhitespace" = true; | ||||
|  | ||||
|     "explorer.confirmDelete" = false; | ||||
|     "explorer.confirmDragAndDrop" = false; | ||||
|     "terminal.integrated.enableMultiLinePasteWarning" = false; | ||||
|     "update.showReleaseNotes" = false; | ||||
|     "terminal.external.linuxExec" = "kitty"; | ||||
|     "workbench.startupEditor" = "newUntitledFile"; | ||||
|  | ||||
|     # Extension management | ||||
|     "extensions.autoCheckUpdates" = false; | ||||
|     "extensions.autoUpdate" = false; | ||||
|     "extensions.ignoreRecommendations" = true; | ||||
|  | ||||
|     # git | ||||
|     "git.ignoreMissingGitWarning" = true; | ||||
|     "git.confirmSync" = false; | ||||
|     "git.enableSmartCommit" = true; | ||||
|     "git.autofetch" = true; | ||||
|     "diffEditor.renderSideBySide" = false; | ||||
|     "diffEditor.hideUnchangedRegions.enabled" = true; | ||||
|     "diffEditor.ignoreTrimWhitespace" = false; | ||||
|  | ||||
|     # Copilot | ||||
|     "github.copilot.editor.enableAutoCompletions" = true; | ||||
|     "github.copilot.advanced" = {}; | ||||
|     "github.copilot.enable" = { | ||||
|         "*" = true; | ||||
|     }; | ||||
|  | ||||
|     # Python | ||||
|     "python.terminal.activateEnvironment" = false; # let nix-shell handle this | ||||
|   }; | ||||
|  | ||||
|   baseKeybindings = [ | ||||
|     # comment/uncomment line | ||||
|     { | ||||
|       key = "ctrl+[Backslash]"; # was ctrl+# but vscode reads the key differently apparently | ||||
|       command = "editor.action.commentLine"; | ||||
|       when = "editorTextFocus"; | ||||
|     } | ||||
|   ]; | ||||
|  | ||||
| in | ||||
| { | ||||
|   programs.vscode = { | ||||
|     enable = true; | ||||
|     # install vscode in a FHS environment to allow extensions with prebuilt binaries | ||||
|     # package = pkgs.vscode.fhs; | ||||
|  | ||||
|     # profiles = { | ||||
|     #   default = { | ||||
|     extensions = with pkgs.vscode-extensions; [ | ||||
|       # QOL | ||||
|       mhutchie.git-graph | ||||
|       redhat.vscode-yaml | ||||
|       github.copilot | ||||
|  | ||||
|       # python | ||||
|       ms-python.python | ||||
|       ms-python.isort | ||||
|       ms-python.debugpy | ||||
|       ms-python.vscode-pylance | ||||
|       # ms-toolsai.jupyter | ||||
|       # ms-toolsai.vscode-jupyter-slideshow | ||||
|       # ms-toolsai.jupyter-renderers | ||||
|  | ||||
|       # Nix language | ||||
|       jnoortheen.nix-ide | ||||
|  | ||||
|       # typst | ||||
|       myriad-dreamin.tinymist | ||||
|     ] ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [ | ||||
|       { | ||||
|         name = "jupyter"; | ||||
|         publisher = "ms-toolsai"; | ||||
|         version = "2025.3.2025032101"; | ||||
|         sha256 = "sha256-s2qEUl9J6EOije6MasZOnHErYs3NYXBqLSfMT03vEH0="; | ||||
|       } | ||||
|       { | ||||
|         name = "jupyter-hub"; | ||||
|         publisher = "ms-toolsai"; | ||||
|         version = "2024.10.1002831100"; | ||||
|         sha256 = "sha256-5IRczwXbYkDdYEOXvQnnH+HJNLvsRsrZ6fnoVCveqrs="; | ||||
|       } | ||||
|     ]; | ||||
|  | ||||
|     keybindings = [ | ||||
|       # comment/uncomment line | ||||
|       { | ||||
|         key = "ctrl+#"; | ||||
|         command = "editor.action.commentLine"; | ||||
|         when = "editorTextFocus"; | ||||
|       } | ||||
|       # run code cell in jupyter | ||||
|       { | ||||
|         key = "ctrl+enter"; | ||||
|         command = "jupyter.runCell"; | ||||
|         when = "editorTextFocus && editorHasSelection && jupyter.notebookEditorFocused"; | ||||
|       } | ||||
|     ]; | ||||
|  | ||||
|     userSettings = { | ||||
|       # visual | ||||
|       "window.menuBarVisibility" = "toggle"; | ||||
|  | ||||
|       "editor.fontFamily" = "'FiraCode Nerd Font Mono', 'monospace', monospace"; | ||||
|       "terminal.integrated.fontFamily" = "FiraCode Nerd Font Mono"; | ||||
|       "workbench.iconTheme" = "vs-seti"; | ||||
|  | ||||
|       # telemetry | ||||
|       "telemetry.enableCrashReporter" = false; | ||||
|       "telemetry.enableTelemetry" = false; | ||||
|       "redhat.telemetry.enabled" = false; | ||||
|  | ||||
|  | ||||
|       # editor QOL | ||||
|       "security.workspace.trust.untrustedFiles" = "open"; | ||||
|       "editor.wordWrap" = "on"; | ||||
|       "editor.suggestSelection" = "first"; | ||||
|       "editor.renderWhitespace" = "none"; | ||||
|       "editor.acceptSuggestionOnEnter" = "off"; | ||||
|       "editor.fontLigatures" = true; | ||||
|       "editor.inlineSuggest.enabled" = true; | ||||
|       "editor.bracketPairColorization.enabled" = true; | ||||
|       "editor.unicodeHighlight.nonBasicASCII" = false; | ||||
|       "editor.unicodeHighlight.invisibleCharacters" = false; | ||||
|       "editor.unicodeHighlight.ambiguousCharacters" = false; | ||||
|  | ||||
|       "files.autoSave" = "onWindowChange"; | ||||
|       "files.autoSaveDelay" = 1000; | ||||
|       "files.insertFinalNewline" = true; | ||||
|       "files.trimTrailingWhitespace" = true; | ||||
|  | ||||
|       "explorer.confirmDelete" = false; | ||||
|       "explorer.confirmDragAndDrop" = false; | ||||
|       "terminal.integrated.enableMultiLinePasteWarning" = false; | ||||
|       "update.showReleaseNotes" = false; | ||||
|       "terminal.external.linuxExec" = "kitty"; | ||||
|       "workbench.startupEditor" = "newUntitledFile"; | ||||
|       # "workbench.colorTheme" = "Default Light+"; | ||||
|  | ||||
|       # Extension management | ||||
|       "extensions.autoCheckUpdates" = false; | ||||
|       "extensions.autoUpdate" = false; | ||||
|       "extensions.ignoreRecommendations" = true; | ||||
|  | ||||
|  | ||||
|       # git | ||||
|       "git.ignoreMissingGitWarning" = true; | ||||
|       "git.confirmSync" = false; | ||||
|       "git.enableSmartCommit" = true; | ||||
|       "git.autofetch" = true; | ||||
|       "diffEditor.renderSideBySide" = false; | ||||
|       "diffEditor.hideUnchangedRegions.enabled" = true; | ||||
|       "diffEditor.ignoreTrimWhitespace" = false; | ||||
|  | ||||
|       # Copilot | ||||
|       "github.copilot.editor.enableAutoCompletions" = true; | ||||
|       "github.copilot.advanced" = {}; | ||||
|       "github.copilot.enable" = { | ||||
|           "*" = true; | ||||
|     profiles.default = { | ||||
|       userSettings = baseSettings // { | ||||
|         "window.newWindowProfile" = "development"; | ||||
|       }; | ||||
|  | ||||
|       # Python | ||||
|       "python.terminal.activateEnvironment" = false; # let nix-shell handle this | ||||
|       "jupyter.disableJupyterAutoStart" = true; | ||||
|       "jupyter.askForKernelRestart" = false; | ||||
|       "workbench.editorAssociations" = { | ||||
|           "*.ipynb" = "jupyter-notebook"; | ||||
|       }; | ||||
|       "notebook.cellToolbarLocation" = { | ||||
|           "default" = "right"; | ||||
|           "jupyter-notebook" = "left"; | ||||
|       }; | ||||
|       "jupyter.widgetScriptSources" = [ | ||||
|           "jsdelivr.com" | ||||
|           "unpkg.com" | ||||
|       ]; | ||||
|  | ||||
|  | ||||
|       # Typst | ||||
|       "[typst]" = { | ||||
|           "editor.wordSeparators" = "`~!@#$%^&*()=+[{]}\\|;:'\",.<>/?"; | ||||
|       }; | ||||
|       "[typst-code]" = { | ||||
|       "git.openRepositoryInParentFolders" = "never"; | ||||
|           "editor.wordSeparators" = "`~!@#$%^&*()=+[{]}\\|;:'\",.<>/?"; | ||||
|       }; | ||||
|       "tinymist.fontPaths" = [ | ||||
|           "./font" | ||||
|       ]; | ||||
|     }; | ||||
|  | ||||
|     profiles.development = { | ||||
|       extensions = baseExtensions ++ (with pkgs.vscode-extensions; [ | ||||
|         # python | ||||
|         ms-python.python | ||||
|         ms-python.isort | ||||
|         ms-python.debugpy | ||||
|         ms-python.vscode-pylance | ||||
|  | ||||
|         # nix language | ||||
|         jnoortheen.nix-ide | ||||
|  | ||||
|         # Flutter and co | ||||
|         dart-code.flutter | ||||
|         dart-code.dart-code | ||||
|  | ||||
|       ]); | ||||
|  | ||||
|       keybindings = baseKeybindings; | ||||
|  | ||||
|       userSettings = baseSettings; | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     profiles.science = { | ||||
|       extensions = baseExtensions ++ (with pkgs.vscode-extensions; [ | ||||
|         # python + jupyter | ||||
|         ms-python.python | ||||
|         ms-python.isort | ||||
|         ms-python.debugpy | ||||
|         ms-python.vscode-pylance | ||||
|         ms-toolsai.vscode-jupyter-slideshow | ||||
|         ms-toolsai.jupyter-renderers | ||||
|  | ||||
|         # Typst | ||||
|         myriad-dreamin.tinymist | ||||
|       ])  ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [ | ||||
|         { | ||||
|           name = "jupyter"; | ||||
|           publisher = "ms-toolsai"; | ||||
|           version = "2025.3.2025032101"; | ||||
|           sha256 = "sha256-s2qEUl9J6EOije6MasZOnHErYs3NYXBqLSfMT03vEH0="; | ||||
|         } | ||||
|         { | ||||
|           name = "jupyter-hub"; | ||||
|           publisher = "ms-toolsai"; | ||||
|           version = "2024.10.1002831100"; | ||||
|           sha256 = "sha256-5IRczwXbYkDdYEOXvQnnH+HJNLvsRsrZ6fnoVCveqrs="; | ||||
|         } | ||||
|       ]; | ||||
|  | ||||
|       keybindings = baseKeybindings ++ [ | ||||
|         # run code cell in jupyter | ||||
|         { | ||||
|           key = "ctrl+enter"; | ||||
|           command = "jupyter.runcurrentcell"; | ||||
|           when = "editorTextFocus && isWorkspaceTrusted && jupyter.hascodecells && !editorHasSelection && !isCompositeNotebook && !notebookEditorFocused"; | ||||
|         } | ||||
|       ]; | ||||
|  | ||||
|       userSettings = baseSettings // { | ||||
|         "jupyter.disableJupyterAutoStart" = true; | ||||
|         "jupyter.askForKernelRestart" = false; | ||||
|         "workbench.editorAssociations" = { | ||||
|             "*.ipynb" = "jupyter-notebook"; | ||||
|         }; | ||||
|         "notebook.cellToolbarLocation" = { | ||||
|             "default" = "right"; | ||||
|             "jupyter-notebook" = "left"; | ||||
|         }; | ||||
|         "jupyter.widgetScriptSources" = [ | ||||
|             "jsdelivr.com" | ||||
|             "unpkg.com" | ||||
|         ]; | ||||
|  | ||||
|         # Typst | ||||
|         "[typst]" = { | ||||
|             "editor.wordSeparators" = "`~!@#$%^&*()=+[{]}\\|;:'\",.<>/?"; | ||||
|         }; | ||||
|         "[typst-code]" = { | ||||
|         "git.openRepositoryInParentFolders" = "never"; | ||||
|             "editor.wordSeparators" = "`~!@#$%^&*()=+[{]}\\|;:'\",.<>/?"; | ||||
|         }; | ||||
|         "tinymist.fontPaths" = [ | ||||
|             "./font" | ||||
|         ]; | ||||
|         "workbench.colorCustomizations" = { | ||||
|           "statusBar.background" = "#003f9293"; | ||||
|         }; | ||||
|  | ||||
|       }; | ||||
|     }; | ||||
|  | ||||
|   }; | ||||
|  | ||||
| } | ||||
|   | ||||
							
								
								
									
										22
									
								
								modules/home-manager/directories.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								modules/home-manager/directories.nix
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| { config, pkgs, ... }: | ||||
| { | ||||
|   # Set up essential directories in the home directory | ||||
|   # TODO | ||||
|   # home.file."Dev".directory = true; | ||||
|   # home.file."owncloud".directory = true; | ||||
|  | ||||
|   # Set XDG user directories | ||||
|   xdg.userDirs = { | ||||
|     enable = true; | ||||
|     createDirectories = true; | ||||
|     documents = "${config.home.homeDirectory}/Documents"; | ||||
|     download = "${config.home.homeDirectory}/Downloads"; | ||||
|     pictures = "${config.home.homeDirectory}/Pictures";# | ||||
|     # do not create the following | ||||
|     desktop = null; | ||||
|     music = null; | ||||
|     publicShare = null; | ||||
|     templates = null; | ||||
|     videos = null; | ||||
|   }; | ||||
| } | ||||
| @@ -3,5 +3,9 @@ | ||||
|   home.packages = [ | ||||
|     # pdf viewer | ||||
|     pkgs.papers | ||||
|     # image viewer | ||||
|     pkgs.loupe | ||||
|     # video player | ||||
|     pkgs.showtime | ||||
|   ]; | ||||
| } | ||||
|   | ||||
| @@ -11,8 +11,6 @@ | ||||
|   ]; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|   programs.fish = { | ||||
|     enable = true; | ||||
|     # enableCompletion = true; | ||||
| @@ -28,6 +26,11 @@ | ||||
|       } | ||||
|       # add others here | ||||
|     ]; | ||||
|  | ||||
|     functions = { | ||||
|       # disable the fish greeting | ||||
|       fish_greeting = ""; | ||||
|     }; | ||||
|   }; | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -14,5 +14,7 @@ | ||||
|     "io.podman_desktop.PodmanDesktop" | ||||
|     "org.pipewire.Helvum" | ||||
|     "im.riot.Riot" | ||||
|     "com.valvesoftware.Steam" | ||||
|     "org.prismlauncher.PrismLauncher" | ||||
|   ]; | ||||
| } | ||||
|   | ||||
| @@ -1,7 +0,0 @@ | ||||
| {inputs, pkgs, ...}: | ||||
| { | ||||
|     # Put a cursor theme to the location expected by the hyprland window manager | ||||
|     # TODO | ||||
|  | ||||
|  | ||||
| } | ||||
| @@ -1,8 +1,6 @@ | ||||
| { | ||||
|   imports = [ | ||||
|     # ./better-control.nix | ||||
|     ./cursor.nix | ||||
|     ./hyprland-customization.nix | ||||
|     ./hyprland | ||||
|     ./hyprpaper.nix | ||||
|     ./hyprlock.nix | ||||
|     ./hypridle.nix | ||||
|   | ||||
| @@ -4,29 +4,37 @@ | ||||
|     enable = true; | ||||
|     settings = { | ||||
|       general = { | ||||
|         lock_cmd = "pidof hyprlock || hyprlock";     # avoid starting multiple hyprlock instances. | ||||
|         # avoid starting multiple hyprlock instances. | ||||
|         before_sleep_cmd = "pidof hyprlock || hyprlock --immediate-render --no-fade-in"; | ||||
|         lock_cmd = "pidof hyprlock || hyprlock --immediate-render --no-fade-in"; | ||||
|         after_sleep_cmd = "hyprctl dispatch dpms on"; | ||||
|         ignore_dbus_inhibit = false; | ||||
|       }; | ||||
|  | ||||
|       listener = [ | ||||
|         { | ||||
|           # dim screen after 4 minutes | ||||
|           timeout = 240; | ||||
|           on-timeout = "brightnessctl -s set 10"; | ||||
|           # set monitor backlight to minimum, avoid 0 on OLED monitor. | ||||
|           # turn off keyboard backlight after 20 seconds | ||||
|           timeout = 10; | ||||
|           on-timeout = "brightnessctl -d platform::kbd_backlight -s set 0"; | ||||
|           # restore keyboard backlight on resume to previous level. | ||||
|           on-resume = "brightnessctl -d platform::kbd_backlight -r"; | ||||
|         } | ||||
|         { | ||||
|           # dim screen after 2 minutes | ||||
|           timeout = 120; | ||||
|           on-timeout = "brightnessctl -s set 2"; | ||||
|           on-resume = "brightnessctl -r"; | ||||
|           # monitor backlight restore. | ||||
|         } | ||||
|         { | ||||
|           # lock screen after 5 minutes | ||||
|           timeout = 300; | ||||
|           # lock screen after 10 minutes | ||||
|           timeout = 600; | ||||
|           on-timeout = "loginctl lock-session && hyprctl dispatch dpms off"; | ||||
|           on-resume = "hyprctl dispatch dpms on"; | ||||
|         } | ||||
|         { | ||||
|           # suspend after 10 minutes | ||||
|           timeout = 600; | ||||
|           # suspend after 15 minutes | ||||
|           timeout = 900; | ||||
|           on-timeout = "systemctl suspend"; | ||||
|           on-resume = "hyprctl dispatch dpms on"; | ||||
|         } | ||||
|   | ||||
| @@ -1,251 +0,0 @@ | ||||
| {inputs, pkgs, lib, config, ...}: | ||||
| let | ||||
|   cfg = config.nix-config.hypr; | ||||
| in | ||||
| { | ||||
|  | ||||
|   options = { | ||||
|     nix-config.hypr.internal-screen.resolution = lib.mkOption { type = lib.types.str; }; | ||||
|     nix-config.hypr.internal-screen.scale = lib.mkOption { type = lib.types.str; }; | ||||
|     nix-config.hypr.browser = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       default = "firefox"; | ||||
|       description = "The browser to use in Hyprland."; | ||||
|     }; | ||||
|     nix-config.hypr.launcher-cmd = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       default = "wofi --show drun -n"; | ||||
|       description = "The command to launch the application launcher in Hyprland."; | ||||
|     }; | ||||
|     nix-config.hypr.ide = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       default = "code"; | ||||
|       description = "The IDE to use in Hyprland."; | ||||
|     }; | ||||
|   }; | ||||
|  | ||||
|   config = { | ||||
|     home.packages = [ | ||||
|       pkgs.hyprshot | ||||
|       pkgs.nautilus | ||||
|       pkgs.gnome-control-center | ||||
|       pkgs.gnome-bluetooth # needed by gnome-control-center to manage bluetooth | ||||
|       pkgs.brightnessctl | ||||
|       pkgs.cliphist | ||||
|       pkgs.wl-clipboard | ||||
|       pkgs.gcr # Provides org.gnome.keyring.SystemPrompter | ||||
|     ]; | ||||
|  | ||||
|  | ||||
|     # Also use gnome keyring | ||||
|     services.gnome-keyring.enable = true; | ||||
|  | ||||
|  | ||||
|     wayland.windowManager.hyprland = { | ||||
|       enable = true; | ||||
|       systemd.enable = true; | ||||
|       settings = { | ||||
|         "$mod" = "SUPER"; | ||||
|  | ||||
|         # Global bindings | ||||
|         bind = [ | ||||
|           # Launch applications | ||||
|           "$mod, space, exec, ${cfg.launcher-cmd}" | ||||
|           "$mod, return, exec, kitty" | ||||
|           "$mod, b, exec, ${cfg.browser}" | ||||
|           "$mod, s, exec, ${cfg.ide}" | ||||
|           "$mod, e, exec, nautilus" | ||||
|  | ||||
|           # Lock screen | ||||
|           "$mod, l, exec, hyprlock" | ||||
|  | ||||
|           # Clipboard management | ||||
|           "$mod, V, exec, cliphist list | wofi --dmenu | cliphist decode | wl-copy" | ||||
|  | ||||
|           # Close window | ||||
|           "$mod, Q, killactive," | ||||
|           "$mod+Shift, Q, exit," # this is the true kill | ||||
|  | ||||
|           # Toggle Floating and reduce size | ||||
|           "$mod, f, togglefloating," | ||||
|           "$mod, f, resizeactive, 50% 50%," | ||||
|           # Toggle fullscreen | ||||
|           "$mod+Shift, f, fullscreen," | ||||
|  | ||||
|           # Alt-tab alternative | ||||
|           "$mod, Tab, cyclenext," | ||||
|           "$mod, Tab, bringactivetotop," | ||||
|  | ||||
|           # Move the window | ||||
|           "$mod+Shift, left, movewindow, l" | ||||
|           "$mod+Shift, right, movewindow, r" | ||||
|           "$mod+Shift, up, movewindow, u" | ||||
|           "$mod+Shift, down, movewindow, d" | ||||
|  | ||||
|           "$mod+Ctrl, left, movetoworkspace, -1" | ||||
|           "$mod+Ctrl, right, movetoworkspace, +1" | ||||
|  | ||||
|           # Switch workspace | ||||
|           "$mod+Alt, left, workspace, -1" | ||||
|           "$mod+Alt, right, workspace, +1" | ||||
|  | ||||
|           # Screenshot | ||||
|           "$mod, Print, exec, hyprshot -m region -o ~/Pictures/Screenshots" | ||||
|           "$mod+Shift, Print, exec, hyprshot -m window -o ~/Pictures/Screenshots" | ||||
|  | ||||
|         ]; | ||||
|  | ||||
|         # repeatable bindings | ||||
|         binde = [ | ||||
|           # Fn keys | ||||
|           ", XF86MonBrightnessDown, exec, brightnessctl set 5%-" | ||||
|           ", XF86MonBrightnessUp, exec, brightnessctl set +5%" | ||||
|           ", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+" | ||||
|           ", XF86AudioLowerVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%-" | ||||
|           ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" | ||||
|  | ||||
|           # Reshape the window in focus | ||||
|           "$mod, MINUS, resizeactive, -2% -2%" | ||||
|           "$mod, KP_Subtract, resizeactive, -2% -2%" | ||||
|           "$mod, PLUS, resizeactive, 2% 2%" | ||||
|           "$mod, KP_Add, resizeactive, 2% 2%" | ||||
|         ]; | ||||
|  | ||||
|         # lock-screen bindings | ||||
|         bindl = [ | ||||
|           # on lid close, lock the screen | ||||
|           # if another monitor is connected, only turn the internal monitor off and don't lock the screen | ||||
|           ", switch:on:Lid Switch, exec, hyprctl dispatch dpms off eDP-1" | ||||
|           # if there is no active monitor, perform a screen lock | ||||
|           ", switch:on:Lid Switch, exec, hyprctl monitors | grep 'dpmsStatus: 1' || hyprlock" | ||||
|           ", switch:off:Lid Switch, exec, hyprctl dispatch dpms on eDP-1" | ||||
|         ]; | ||||
|  | ||||
|         # bindr = [ | ||||
|         #     # Overview | ||||
|         #   "$mod, , overview:toggle" | ||||
|         # ]; | ||||
|  | ||||
|         bindm = [ | ||||
|           # move the window | ||||
|           "$mod, mouse:272, movewindow" | ||||
|         ]; | ||||
|  | ||||
|         exec-once = [ | ||||
|           "gnome-keyring-daemon --start --components=secrets" | ||||
|           # "${pkgs.hyprpaper}/bin/hyprpaper" | ||||
|           # hyprpaper is handled as its own service | ||||
|           "${pkgs.waybar}/bin/waybar" | ||||
|           # listen to clipboard events and send them to cliphist | ||||
|           "wl-paste --watch cliphist store" | ||||
|           "${pkgs.waybar}/bin/hypridle" | ||||
|           "hyprpaper" | ||||
|           # # Fixes cursor themes in gnome apps under hyprland | ||||
|           # "gsettings set org.gnome.desktop.interface cursor-theme '${config.home.pointerCursor.name}'" | ||||
|           # "gsettings set org.gnome.desktop.interface cursor-size ${toString home.pointerCursor.size}" | ||||
|           "${pkgs.owncloud-client}" | ||||
|         ]; | ||||
|  | ||||
|         general = { | ||||
|           resize_on_border = true; | ||||
|           gaps_in = 5; | ||||
|           gaps_out = 5; | ||||
|           border_size = 1; | ||||
|           "col.active_border" = "rgb(98971A) rgb(CC241D) 45deg"; | ||||
|           layout = "master"; | ||||
|         }; | ||||
|  | ||||
|         misc = { | ||||
|           # disable refreshs when nothing is going on | ||||
|           vfr = false; | ||||
|           disable_hyprland_logo = true; | ||||
|         }; | ||||
|  | ||||
|         input = { | ||||
|           kb_layout = "de"; | ||||
|           # remap caps lock to ctrl | ||||
|           kb_options = "ctrl:nocaps"; | ||||
|           numlock_by_default = true; | ||||
|           # mouse input should be unchanged | ||||
|           natural_scroll = false; | ||||
|           sensitivity = 0.3; | ||||
|           touchpad = { | ||||
|             disable_while_typing = false; | ||||
|             natural_scroll = true; | ||||
|           }; | ||||
|         }; | ||||
|  | ||||
|         device = { | ||||
|           name = "syna329a:00-06cb:cd4f-touchpad"; | ||||
|           sensitivity = 0.5; | ||||
|         }; | ||||
|  | ||||
|         gestures = { | ||||
|           workspace_swipe = true; | ||||
|           workspace_swipe_fingers = 4; | ||||
|           workspace_swipe_touch = true; | ||||
|         }; | ||||
|  | ||||
|         decoration = { | ||||
|           rounding = 7; | ||||
|           # active_opacity = 0.95; | ||||
|           inactive_opacity = 0.9; | ||||
|  | ||||
|           shadow = { | ||||
|             enabled = false; | ||||
|           }; | ||||
|  | ||||
|           # blur is set on a per-program basis | ||||
|           windowrulev2 = [ | ||||
|             # kitty should behave like a floating window | ||||
|             "animation popin, class:kitty" | ||||
|             "move cursor -50% -50%, class:kitty" | ||||
|             "float, class:kitty" | ||||
|             "size 50% 50%, class:kitty" | ||||
|  | ||||
|             # some more floating windows | ||||
|             "float, class:org.gnome.Settings" | ||||
|             "float, class:desktopclient.owncloud.com" | ||||
|             "float, class:org.keepassxc.KeePassXC" | ||||
|  | ||||
|           ]; | ||||
|         }; | ||||
|  | ||||
|         monitor = [ | ||||
|           # the internal monitor, always at the "center" | ||||
|           "eDP-1, ${cfg.internal-screen.resolution}, 0x0, ${cfg.internal-screen.scale}" | ||||
|  | ||||
|           # Samsung monitors at irchel (matching the description) | ||||
|           # "desc:Samsung Electric Company LS27D80xU HK7X800803, 3840x2160, auto-up, 1.8" | ||||
|           "desc:Samsung Electric Company LS27D80xU HNAX600169, 2560x1440@59.95, auto-up, 1" | ||||
|  | ||||
|           ", preferred, auto-up, auto" # automatically add any newly detected monitor | ||||
|         ]; | ||||
|  | ||||
|         xwayland = { | ||||
|           enabled = false; | ||||
|         }; | ||||
|  | ||||
|         env = [ | ||||
|           # force apps to use wayland | ||||
|           "NIXOS_OZONE_WL, 1" | ||||
|           "ELECTRON_OZONE_PLATFORM_HINT, wayland" | ||||
|           # set the scale factor for GDK apps | ||||
|           "GDK_SCALE, 1.7" | ||||
|           # set the scale factor for QT apps | ||||
|           "QT_SCALE_FACTOR, 1.7" | ||||
|           # set the scale factor for GTK apps | ||||
|         ]; | ||||
|       }; | ||||
|  | ||||
|       plugins = [ | ||||
|         # Global overview | ||||
|         pkgs.hyprlandPlugins.hyprspace | ||||
|         # Touch gestures | ||||
|         pkgs.hyprlandPlugins.hyprgrass | ||||
|       ]; | ||||
|     }; | ||||
|  | ||||
|     services.swaync.enable = true; | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										30
									
								
								modules/home-manager/hypr/hyprland/autostart.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								modules/home-manager/hypr/hyprland/autostart.nix
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| {inputs, pkgs, lib, config, ...}: | ||||
| let | ||||
|   cfg = config.nix-config.hypr; | ||||
| in | ||||
| { | ||||
|   options = { | ||||
|     nix-config.hypr.autostartApps = lib.mkOption { | ||||
|       type = lib.types.listOf lib.types.str; | ||||
|       default = [ | ||||
|         "gnome-keyring-daemon --start --components=secrets" | ||||
|         "wl-paste --watch cliphist store" | ||||
|         "${lib.getExe pkgs.waybar}" | ||||
|         "${lib.getExe pkgs.hypridle}" | ||||
|         "${pkgs.owncloud-client}" | ||||
|         "${lib.getExe pkgs.keepassxc}" | ||||
|       ]; | ||||
|       description = "List of applications to start automatically in Hyprland."; | ||||
|     }; | ||||
|   }; | ||||
|  | ||||
|   config = { | ||||
|     wayland.windowManager.hyprland = { | ||||
|       enable = true; | ||||
|       systemd.enable = true; | ||||
|       settings = { | ||||
|         exec-once = cfg.autostartApps; | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										9
									
								
								modules/home-manager/hypr/hyprland/default.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								modules/home-manager/hypr/hyprland/default.nix
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   imports = [ | ||||
|     ./autostart.nix | ||||
|     ./general.nix | ||||
|     ./keybinds.nix | ||||
|     ./layouts.nix | ||||
|     ./packages.nix | ||||
|   ]; | ||||
| } | ||||
							
								
								
									
										133
									
								
								modules/home-manager/hypr/hyprland/general.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								modules/home-manager/hypr/hyprland/general.nix
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| {inputs, pkgs, lib, config, ...}: | ||||
| let | ||||
|   cfg = config.nix-config.hypr; | ||||
| in | ||||
| { | ||||
|   options = { | ||||
|     nix-config.hypr.internal-screen.resolution = lib.mkOption { type = lib.types.str; }; | ||||
|     nix-config.hypr.internal-screen.scale = lib.mkOption { type = lib.types.str; }; | ||||
|     nix-config.hypr.browser = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       default = "firefox"; | ||||
|       description = "The browser to use in Hyprland."; | ||||
|     }; | ||||
|     nix-config.hypr.ide = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       default = "code"; | ||||
|       description = "The IDE to use in Hyprland."; | ||||
|     }; | ||||
|   }; | ||||
|  | ||||
|   config = { | ||||
|     wayland.windowManager.hyprland = { | ||||
|       enable = true; | ||||
|       systemd.enable = true; | ||||
|       settings = { | ||||
|         general = { | ||||
|           resize_on_border = true; | ||||
|           gaps_in = 5; | ||||
|           gaps_out = 5; | ||||
|           border_size = 1; | ||||
|           "col.active_border" = "rgb(98971A) rgb(CC241D) 45deg"; | ||||
|           layout = "master"; | ||||
|         }; | ||||
|  | ||||
|       input = { | ||||
|         kb_layout = "de"; | ||||
|         # remap caps lock to ctrl | ||||
|         kb_options = "ctrl:nocaps"; | ||||
|         numlock_by_default = true; | ||||
|         # mouse input should be unchanged | ||||
|         natural_scroll = false; | ||||
|         sensitivity = 0.3; | ||||
|         touchpad = { | ||||
|           disable_while_typing = false; | ||||
|           natural_scroll = true; | ||||
|         }; | ||||
|       }; | ||||
|  | ||||
|       device = { | ||||
|         name = "syna329a:00-06cb:cd4f-touchpad"; | ||||
|         sensitivity = 0.5; | ||||
|       }; | ||||
|  | ||||
|       gestures = { | ||||
|         workspace_swipe = true; | ||||
|         workspace_swipe_fingers = 4; | ||||
|         workspace_swipe_touch = true; | ||||
|       }; | ||||
|  | ||||
|       decoration = { | ||||
|         rounding = 7; | ||||
|         # active_opacity = 0.95; | ||||
|         inactive_opacity = 0.9; | ||||
|  | ||||
|         shadow = { | ||||
|           enabled = false; | ||||
|         }; | ||||
|  | ||||
|         # blur = { | ||||
|         #   enabled = true; | ||||
|         #   size = 5; | ||||
|         #   passes = 2; | ||||
|         # }; | ||||
|  | ||||
|         # blur is set on a per-program basis | ||||
|         windowrulev2 = [ | ||||
|           # kitty should behave like a floating window | ||||
|           "animation popin, class:kitty" | ||||
|           "move cursor -50% -50%, class:kitty" | ||||
|           "float, class:kitty" | ||||
|           "size 50% 50%, class:kitty" | ||||
|  | ||||
|           # blur the launcher background | ||||
|           # "blur 10, class:${config.nix-config.launcher.name}" | ||||
|  | ||||
|           # some more floating windows | ||||
|           "float, class:org.gnome.Settings" | ||||
|           "float, class:desktopclient.owncloud.com" | ||||
|           "float, class:org.keepassxc.KeePassXC" | ||||
|           "float, title:^(Picture-in-Picture)$" | ||||
|           "float, class:org.gnome.Nautilus" | ||||
|           # when there is a single window, deactivate border and gaps | ||||
|           # "border_size 0, onworkspace:w[tv1], " | ||||
|         ]; | ||||
|       }; | ||||
|  | ||||
|       monitor = [ | ||||
|         # the internal monitor, always at the "center" | ||||
|         "eDP-1, ${cfg.internal-screen.resolution}, 0x0, ${cfg.internal-screen.scale}" | ||||
|  | ||||
|         # Samsung monitors at irchel (matching the description) | ||||
|         "desc:Samsung Electric Company LS27D80xU, 2560x1440@59.95, auto-up, 1" | ||||
|  | ||||
|         ", preferred, auto-up, auto" # automatically add any newly detected monitor | ||||
|       ]; | ||||
|  | ||||
|       xwayland = { | ||||
|         enabled = true; | ||||
|         force_zero_scaling = true; | ||||
|       }; | ||||
|  | ||||
|       env = [ | ||||
|         # force apps to use wayland | ||||
|         "NIXOS_OZONE_WL, 1" | ||||
|         "ELECTRON_OZONE_PLATFORM_HINT, wayland" | ||||
|         # set the scale factor for GDK apps | ||||
|         "GDK_SCALE, ${cfg.internal-screen.scale}" | ||||
|         # set the scale factor for QT apps | ||||
|         # "QT_SCALE_FACTOR, ${cfg.internal-screen.scale}" | ||||
|         "QT_SCALE_FACTOR, 1.1" | ||||
|         # set the scale factor for GTK apps | ||||
|       ]; | ||||
|     }; | ||||
|  | ||||
|       plugins = [ | ||||
|         # Global overview | ||||
|         pkgs.hyprlandPlugins.hyprspace | ||||
|         # Touch gestures | ||||
|         pkgs.hyprlandPlugins.hyprgrass | ||||
|       ]; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										135
									
								
								modules/home-manager/hypr/hyprland/keybinds.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								modules/home-manager/hypr/hyprland/keybinds.nix
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | ||||
| {inputs, pkgs, lib, config, ...}: | ||||
| let | ||||
|   cfg = config.nix-config.hypr; | ||||
| in | ||||
| { | ||||
|   config = { | ||||
|     wayland.windowManager.hyprland = { | ||||
|       enable = true; | ||||
|       systemd.enable = true; | ||||
|       settings = { | ||||
|         "$mod" = "SUPER"; | ||||
|  | ||||
|         # Global bindings | ||||
|         bind = [ | ||||
|           # Launch applications | ||||
|           "$mod, space, exec, ${lib.getExe config.nix-config.launcher}" | ||||
|           "$mod, return, exec, kitty" | ||||
|           "$mod, b, exec, ${cfg.browser}" | ||||
|           "$mod, s, exec, ${cfg.ide}" | ||||
|           "$mod, e, exec, nautilus" | ||||
|  | ||||
|           # Lock screen | ||||
|           "$mod, l, exec, loginctl lock-session" | ||||
|  | ||||
|           # Clipboard management | ||||
|           "$mod, V, exec, cliphist list | ${lib.getExe config.nix-config.launcher} --dmenu | cliphist decode | wl-copy" | ||||
|  | ||||
|           # Close window | ||||
|           "$mod, Q, killactive," | ||||
|           # Force close window | ||||
|           # "$mod+Shift, Q, forcekillactive," | ||||
|  | ||||
|           # Toggle Floating and reduce size | ||||
|           "$mod, f, togglefloating," | ||||
|           "$mod, f, resizeactive, 50% 50%," | ||||
|  | ||||
|           # "$mod, P, pseudo, " # dwindle | ||||
|           # "$mod, J, togglesplit, " # dwindle | ||||
|           # Toggle fullscreen | ||||
|           "$mod+Shift, f, fullscreen," | ||||
|  | ||||
|           # Alt-tab alternative | ||||
|           "$mod, Tab, cyclenext," | ||||
|           "$mod, Tab, bringactivetotop," | ||||
|  | ||||
|           # Move the window | ||||
|           "$mod+Shift, left, movewindow, l" | ||||
|           "$mod+Shift, right, movewindow, r" | ||||
|           "$mod+Shift, up, movewindow, u" | ||||
|           "$mod+Shift, down, movewindow, d" | ||||
|  | ||||
|           "$mod+Ctrl, left, movetoworkspace, -1" | ||||
|           "$mod+Ctrl, right, movetoworkspace, +1" | ||||
|  | ||||
|           # Switch workspace | ||||
|           "$mod+Alt, left, workspace, -1" | ||||
|           "$mod+Alt, right, workspace, +1" | ||||
|           "$mod, mouse_down, workspace, -1" | ||||
|           "$mod, mouse_up, workspace, +1" | ||||
|  | ||||
|           # move to scratch workspace | ||||
|           "$mod+Ctrl, up, movetoworkspace, special:magic" | ||||
|           "$mod+Ctrl, down, movetoworkspace, 1" | ||||
|           # toggle scratch workspace | ||||
|           "$mod+Alt, up, togglespecialworkspace, magic" | ||||
|           "$mod+Alt, down, togglespecialworkspace, magic" | ||||
|  | ||||
|           # Screenshot | ||||
|           "$mod, Print, exec, hyprshot -m region -o ~/Pictures/Screenshots" | ||||
|           "$mod+Shift, Print, exec, hyprshot -m window -o ~/Pictures/Screenshots" | ||||
|           # # somehow logitech calls this SUPER_L but we refer to it by its code | ||||
|           "SUPER_L&Shift_L, S, exec, hyprshot -m region -o ~/Pictures/Screenshots" | ||||
|           "Shift&SUPER_L&Shift_L, S, exec, hyprshot -m window -o ~/Pictures/Screenshots" | ||||
|           # when there is a dedicated screenshot button | ||||
|           ", XF86Cut, exec, hyprshot -m region -o ~/Pictures/Screenshots" | ||||
|           "Shift, XF86Cut, exec, hyprshot -m window -o ~/Pictures/Screenshots" | ||||
|  | ||||
|           # Power menu | ||||
|           ", XF86PowerOff, exec, ${lib.getExe config.nix-config.powerMenu}" | ||||
|  | ||||
|           # Other pickers using the same launcher | ||||
|           "$mod+Ctrl, space, exec, ${lib.getExe config.nix-config.filePicker}" | ||||
|  | ||||
|         ]; | ||||
|  | ||||
|         # repeatable bindings | ||||
|         binde = [ | ||||
|           # Fn keys | ||||
|           ", XF86MonBrightnessDown, exec, brightnessctl set 5%-" | ||||
|           ", XF86MonBrightnessUp, exec, brightnessctl set +5%" | ||||
|           ", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+" | ||||
|           ", XF86AudioLowerVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%-" | ||||
|           ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" | ||||
|  | ||||
|           # Reshape the window in focus | ||||
|           "$mod, MINUS, resizeactive, -2% -2%" | ||||
|           "$mod, KP_Subtract, resizeactive, -2% -2%" | ||||
|           "$mod, PLUS, resizeactive, 2% 2%" | ||||
|           "$mod, KP_Add, resizeactive, 2% 2%" | ||||
|         ]; | ||||
|  | ||||
|         # lock-screen bindings | ||||
|         bindl = [ | ||||
|           ## depending on the setup: lock screen or switch to clamshell mode | ||||
|           # in any case, the internal screen is turned off | ||||
|           # ", switch:on:Lid Switch, exec, loginctl lock-session" | ||||
|  | ||||
|  | ||||
|           # if an additional monitor is detected, simply deactivate the internal screen and continue working on the external monitor | ||||
|           ", switch:on:Lid Switch, exec, hyprctl dispatch dpms off eDP-1" | ||||
|           ", switch:on:Lid Switch, exec, sleep 0.5; hyprctl monitors | grep 'dpmsStatus: 1' && hyprctl keyword monitor 'eDP-1,disable'" | ||||
|           # # if no external monitor is detected, lock the screen | ||||
|           # ", switch:on:Lid Switch, exec, sleep 0.5; hyprctl monitors | grep 'dpmsStatus: 1' || loginctl lock-session" | ||||
|  | ||||
|           ## on reopening the lid, turn the internal screen back on | ||||
|           ", switch:off:Lid Switch, exec, hyprctl dispatch dpms on eDP-1" | ||||
|           # if an external monitor was connected, then we need to reload the monitor configuration | ||||
|           ", switch:off:Lid Switch, exec, hyprctl monitors | grep 'ID 1' && hyprctl reload" | ||||
|         ]; | ||||
|  | ||||
|         # bindr = [ | ||||
|         #     # Overview | ||||
|         #   "$mod, , overview:toggle" | ||||
|         # ]; | ||||
|  | ||||
|         bindm = [ | ||||
|           # move the window using left click | ||||
|           "$mod, mouse:272, movewindow" | ||||
|           # resize the window using right click | ||||
|           "$mod, mouse:273, resizewindow" | ||||
|         ]; | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										57
									
								
								modules/home-manager/hypr/hyprland/layouts.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								modules/home-manager/hypr/hyprland/layouts.nix
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| {inputs, pkgs, lib, config, ...}: | ||||
| let | ||||
|   cfg = config.nix-config.hypr; | ||||
| in | ||||
| { | ||||
|   config = { | ||||
|     wayland.windowManager.hyprland = { | ||||
|       settings = { | ||||
|  | ||||
|         master = { | ||||
|           # TODO - I am not yet happy about the layout + toggle keybinds | ||||
|           orientation = "center"; | ||||
|           # equivalent toalways_center_master = true; | ||||
|           slave_count_for_center_master = 0; | ||||
|           # new_is_master = false; | ||||
|           # allow_small_split = true; | ||||
|           # special_scale_factor = 0.80; | ||||
|           mfact = 0.34; | ||||
|           inherit_fullscreen = false; | ||||
|           # always_center_master = false; | ||||
|           # allow a maximum of 3 windows in the master area for 3-column layout | ||||
|         }; | ||||
|  | ||||
|         #create special workspaces with no gaps | ||||
|         workspace = [ | ||||
|           "w[t1], gapsout:0, gapsin:0" | ||||
|           "w[tg1], gapsout:0, gapsin:0" | ||||
|           "f[1], gapsout:0, gapsin:0" | ||||
|         ]; | ||||
|  | ||||
|         # automatically assign windows to workspaces when there is only one window | ||||
|         windowrulev2 = [ | ||||
|           "bordersize 0, floating:0, onworkspace:w[t1]" | ||||
|           "rounding 0, floating:0, onworkspace:w[t1]" | ||||
|           "bordersize 0, floating:0, onworkspace:w[tg1]" | ||||
|           "rounding 0, floating:0, onworkspace:w[tg1]" | ||||
|           "bordersize 0, floating:0, onworkspace:f[1]" | ||||
|           "rounding 0, floating:0, onworkspace:f[1]" | ||||
|         ]; | ||||
|  | ||||
|         misc = { | ||||
|           vfr = false; | ||||
|           disable_hyprland_logo = true; | ||||
|         }; | ||||
|  | ||||
|         # Keybind to toggle between 2 and 3 column master layout | ||||
|         bind = [ | ||||
|           # Toggle master layout between 2 and 3 columns | ||||
|           "$mod, m, exec, hyprctl dispatch layoutmsg orientationleft" | ||||
|           "$mod, m, exec, hyprctl dispatch layoutmsg mfact exact 0.5" | ||||
|           # "SUPER_SHIFT,C,exec,hyprctl dispatch layoutmsg swap_master_count 2 3" | ||||
|         ]; | ||||
|  | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										20
									
								
								modules/home-manager/hypr/hyprland/packages.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								modules/home-manager/hypr/hyprland/packages.nix
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| {inputs, pkgs, lib, config, ...}: | ||||
| let | ||||
|   cfg = config.nix-config.hypr; | ||||
| in | ||||
| { | ||||
|   # packages required by the current hyprland setup | ||||
|   home.packages = [ | ||||
|     pkgs.hyprshot | ||||
|     pkgs.nautilus | ||||
|     pkgs.gnome-control-center | ||||
|     pkgs.gnome-bluetooth # needed by gnome-control-center to manage bluetooth | ||||
|     pkgs.brightnessctl | ||||
|     pkgs.cliphist | ||||
|     pkgs.wl-clipboard | ||||
|     pkgs.gcr # Provides org.gnome.keyring.SystemPrompter | ||||
|   ]; | ||||
|  | ||||
|   # Also use gnome keyring | ||||
|   services.gnome-keyring.enable = true; | ||||
| } | ||||
| @@ -5,10 +5,10 @@ | ||||
|     settings = { | ||||
|  | ||||
|  | ||||
|       # prevent the screen being shown for a split second | ||||
|       animations = { | ||||
|         animation = "fadeIn, 0, 0, linear"; | ||||
|       }; | ||||
|       # # prevent the screen being shown for a split second | ||||
|       # animations = { | ||||
|       #   animation = "fadeIn, 0, 0, linear"; | ||||
|       # }; | ||||
|  | ||||
|       general = { | ||||
|         # immediately lock the screen | ||||
|   | ||||
| @@ -3,37 +3,40 @@ | ||||
|   lib, | ||||
|  ... | ||||
| }: | ||||
| with lib; let | ||||
|   # # load the wallpapers from the wallpapers directory - this gives a set with the folder content | ||||
|   # dirContent = builtins.readDir ../../../wallpapers; | ||||
|   # wallpaperString = lib.strings.concatMapStrings (x: " " + x) wallpapers; | ||||
|   # # # load each wallpaper and keep its path (now in the nix store) as an array | ||||
|   # # wallpapers = map (x: builtins.readDir "${../../../wallpapers}/${x.value}") dirContent; | ||||
|   # # wallpaperString = lib.strings.concatMapStrings (x: " " + x) wallpapers; | ||||
| let | ||||
|  | ||||
|   # # script that picks a random wallpaper from the array and sets it as the desktop background | ||||
|   # monitor = ""; # leave empty to set the wallpaper on all monitors | ||||
|   wallpapers = [ | ||||
|     ../../../wallpapers/codioful-formerly-gradienta-lweK7Wme_jo-unsplash.jpg | ||||
|     ../../../wallpapers/codioful-formerly-gradienta-n2XqPm7Bqhk-unsplash.jpg | ||||
|     ../../../wallpapers/luke-chesser-eICUFSeirc0-unsplash.jpg | ||||
|     ../../../wallpapers/luke-chesser-pJadQetzTkI-unsplash.jpg | ||||
|     ../../../wallpapers/magicpattern-87PP9Zd7MNo-unsplash.jpg | ||||
|   ]; | ||||
|  | ||||
|   # wallpaperRandomizer = pkgs.writeShellScriptBin "wallpaperRandomizer" '' | ||||
|   #   wallpaper=$(shuf -n 1 -e ${wallpaperString}) | ||||
|   #   hyprctl hyprpaper unload all | ||||
|   #   hyprctl hyprpaper preload $wallpaper | ||||
|   #   hyprctl hyprpaper wallpaper "${monitor},$wallpaper" | ||||
|   # ''; | ||||
|   monitor = ""; # leave empty to set the wallpaper on all monitors | ||||
|  | ||||
|   wallpaperPicker = pkgs.writeShellScriptBin "wallpaper-picker" '' | ||||
|     #!/usr/bin/env bash | ||||
|     # use an array of wallpapers to randomly select one | ||||
|     wallpapers=(${pkgs.lib.concatStringsSep " " (map (p: "${p}") wallpapers)}) | ||||
|     # select a random wallpaper from the array | ||||
|     index=$((RANDOM % ${toString (builtins.length wallpapers)})) | ||||
|     wallpaper="''${wallpapers[index]}" | ||||
|     echo "Setting wallpaper to: $wallpaper" | ||||
|  | ||||
|     hyprctl hyprpaper unload all | ||||
|     hyprctl hyprpaper reload "${monitor},$wallpaper" | ||||
|   ''; | ||||
|  | ||||
| in { | ||||
|   # home.packages = [wallpaperRandomizer]; | ||||
|  | ||||
|  | ||||
|   home.packages = [wallpaperPicker]; | ||||
|  | ||||
|   services.hyprpaper = { | ||||
|     enable = true; | ||||
|     settings = { | ||||
|       ipc = "on"; | ||||
|     }; | ||||
|   }; | ||||
|   #   settings = { | ||||
|   #     ipc = "off"; | ||||
|   #     splash = false; | ||||
|   #   }; | ||||
|   # }; | ||||
|  | ||||
|   # systemd.user = { | ||||
|   #   services.wallpaperRandomizer = { | ||||
|   | ||||
| @@ -3,252 +3,327 @@ let | ||||
|   cfg = config.nix-config.style; | ||||
| in | ||||
| { | ||||
|     # required to autoload fonts from packages installed via Home Manager | ||||
|     fonts.fontconfig.enable = true; | ||||
|     options.nix-config.waybar = { | ||||
|         burninPrevention = lib.mkOption { | ||||
|             type = lib.types.bool; | ||||
|             default = true; | ||||
|             description = "Enable burn-in prevention for Waybar"; | ||||
|             example = '' | ||||
|                 burninPrevention = true; | ||||
|             ''; | ||||
|  | ||||
|     # waybar requires font-awesome | ||||
|     home.packages = [ | ||||
|         pkgs.pavucontrol | ||||
|     ]; | ||||
|         }; | ||||
|     }; | ||||
|  | ||||
|     # enable waybar | ||||
|     programs.waybar.enable = true; | ||||
|     programs.waybar = { | ||||
|         settings = { | ||||
|  | ||||
|             mainBar = { | ||||
|                 layer = "top"; | ||||
|                 position = "top"; | ||||
|  | ||||
|                 margin-top = 5; | ||||
|                 # margin-bottom = 2; | ||||
|                 # margin-left = 5; | ||||
|                 # margin-right = 5; | ||||
|  | ||||
|                 # margin between the modules | ||||
|                 spacing = 2; | ||||
|  | ||||
|                 modules-left = [ | ||||
|                     "hyprland/workspaces" | ||||
|                     "hyprland/window" | ||||
|                 ]; | ||||
|  | ||||
|                 modules-center = [ | ||||
|                     "clock" | ||||
|                     "custom/notification" | ||||
|                 ]; | ||||
|  | ||||
|                 modules-right = [ | ||||
|                     "tray" | ||||
|                     "privacy" | ||||
|                     "network" | ||||
|                     "wireplumber" | ||||
|                     "battery" | ||||
|                     "backlight" | ||||
|                     "idle_inhibitor" | ||||
|                 ]; | ||||
|     config = { | ||||
|  | ||||
|  | ||||
|                 # module specific settings | ||||
|                 "hyprland/workspaces" = { | ||||
|                     format = "{icon}"; | ||||
|                     format-icons = { | ||||
|                         active = "●"; | ||||
|                         default = "○"; | ||||
|                     }; | ||||
|                 }; | ||||
|                 "hyprland/window"= { | ||||
|                     "icon" = true; | ||||
|                     "separate-outputs" = true; | ||||
|                     "format" = "{}"; | ||||
|                     "rewrite" = { | ||||
|                         "(.*) — Mozilla Firefox" = "$1"; | ||||
|                         "(.*) — Zen Browser" = "$1"; | ||||
|                         "(.*) - fish" = "> [$1]"; | ||||
|                         "(.*) - Visual Studio Code" = "$1"; | ||||
|                     }; | ||||
|                 }; | ||||
|                 "clock" = { | ||||
|                     format = "{:%H:%M}"; | ||||
|                     interval = 1; | ||||
|                     tooltip-format = "<tt>{calendar}</tt>"; | ||||
|                     calendar = { | ||||
|                         "format" = { | ||||
|                             "today" = "<span color='#fAfBfC'><b>{}</b></span>"; | ||||
|         # required to autoload fonts from packages installed via Home Manager | ||||
|         fonts.fontconfig.enable = true; | ||||
|  | ||||
|         # waybar requires font-awesome | ||||
|         home.packages = [ | ||||
|             pkgs.pavucontrol | ||||
|         ]; | ||||
|  | ||||
|         # enable waybar | ||||
|         programs.waybar.enable = true; | ||||
|         programs.waybar = { | ||||
|             settings = { | ||||
|  | ||||
|                 mainBar = { | ||||
|                     layer = "top"; | ||||
|                     position = "top"; | ||||
|  | ||||
|                     margin-top = 5; | ||||
|                     # margin-bottom = 2; | ||||
|                     # margin-left = 5; | ||||
|                     # margin-right = 5; | ||||
|  | ||||
|                     # margin between the modules | ||||
|                     spacing = 2; | ||||
|  | ||||
|                     modules-left = [ | ||||
|                         "hyprland/workspaces" | ||||
|                         "hyprland/window" | ||||
|                     ]; | ||||
|  | ||||
|                     modules-center = [ | ||||
|                         "clock" | ||||
|                         "custom/notification" | ||||
|                     ]; | ||||
|  | ||||
|                     modules-right = [ | ||||
|                         "tray" | ||||
|                         "privacy" | ||||
|                         "network" | ||||
|                         "bluetooth" | ||||
|                         "wireplumber" | ||||
|                         "battery" | ||||
|                         "backlight" | ||||
|                         "idle_inhibitor" | ||||
|                     ]; | ||||
|  | ||||
|  | ||||
|                     # module specific settings | ||||
|                     "hyprland/workspaces" = { | ||||
|                         format = "{icon}"; | ||||
|                         format-icons = { | ||||
|                             active = "●"; | ||||
|                             default = "○"; | ||||
|                         }; | ||||
|                     }; | ||||
|                 }; | ||||
|                 "idle_inhibitor" = { | ||||
|                     format = "{icon}"; | ||||
|                     format-icons = { | ||||
|                         activated = ""; | ||||
|                         deactivated = ""; | ||||
|                     "hyprland/window"= { | ||||
|                         "icon" = true; | ||||
|                         "separate-outputs" = true; | ||||
|                         "format" = "{}"; | ||||
|                         "rewrite" = { | ||||
|                             "(.*) — Mozilla Firefox" = "$1"; | ||||
|                             "(.*) — Zen Browser" = "$1"; | ||||
|                             "(.*) - fish" = "> [$1]"; | ||||
|                             "(.*) - Visual Studio Code" = "$1"; | ||||
|                         }; | ||||
|                     }; | ||||
|                     tooltip = "true"; | ||||
|                 }; | ||||
|                 "bluetooth" = { | ||||
|                     format-on = ""; | ||||
|                     format-off = "BT-off"; | ||||
|                     format-disabled = ""; | ||||
|                     format-connected-battery = "{device_battery_percentage}% "; | ||||
|                     format-alt = "{device_alias} "; | ||||
|                     tooltip-format = "{controller_alias}\t{controller_address}\n\n{num_connections} connected"; | ||||
|                     tooltip-format-connected = "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}"; | ||||
|                     tooltip-formaenumeratet-enumerate-connected = "{device_alias}\n{device_address}"; | ||||
|                     tooltip-format-enumerate-connected-battery = "{device_alias}\n{device_address}\n{device_battery_percentage}%"; | ||||
|                     on-click-right = "blueman-manager"; | ||||
|                 }; | ||||
|                 "battery" = { | ||||
|                     interval = 60; | ||||
|                     states = { | ||||
|                         good = 80; | ||||
|                         warning = 30; | ||||
|                         critical = 10; | ||||
|                     "clock" = { | ||||
|                         format = " {:%H:%M}"; | ||||
|                         interval = 1; | ||||
|                         tooltip-format = "{calendar}"; | ||||
|                         calendar = { | ||||
|                             "format" = { | ||||
|                                 "today" = "<span color='#fAfBfC'><b>{}</b></span>"; | ||||
|                             }; | ||||
|                         }; | ||||
|                     }; | ||||
|                     format = "{capacity}% {icon}"; | ||||
|                     format-charging = "{capacity}% "; | ||||
|                     format-plugged = "{capacity}%  "; | ||||
|                     format-icons = [ "" "" "" "" "" "" ]; | ||||
|                 }; | ||||
|                 "backlight" = { | ||||
|                     "format" = "{percent}% {icon}"; | ||||
|                     "format-icons" = ["" "" "" "" "" "" "" "" ""]; | ||||
|                 }; | ||||
|                 "wireplumber" = { | ||||
|                     scroll-step = 10; | ||||
|                     format = "{icon} {volume}%";# {format_source}"; | ||||
|                     format-bluetooth = "{volume}% {icon}";# {format_source}"; | ||||
|                     format-bluetooth-muted = " {icon}";# {format_source}"; | ||||
|                     format-muted = " Muted";# {format_source}"; | ||||
|                     # format-source = " {volume}%"; | ||||
|                     # format-source-muted = ""; | ||||
|                     format-icons = { | ||||
|                         headphone = ""; | ||||
|                         hands-free = ""; | ||||
|                         headset = ""; | ||||
|                         phone = ""; | ||||
|                         portable = ""; | ||||
|                         default = [ | ||||
|                             "" | ||||
|                             "" | ||||
|                             "" | ||||
|                     "idle_inhibitor" = { | ||||
|                         format = "{icon}"; | ||||
|                         format-icons = { | ||||
|                             activated = ""; | ||||
|                             deactivated = "☕"; | ||||
|                         }; | ||||
|                         tooltip = "true"; | ||||
|                     }; | ||||
|                     "bluetooth" = { | ||||
|                         format-on = ""; | ||||
|                         format-off = "BT-off"; | ||||
|                         format-disabled = ""; | ||||
|                         format-connected-battery = "{device_battery_percentage}% "; | ||||
|                         format-alt = "{device_alias} "; | ||||
|                         tooltip-format = "{controller_alias}\t{controller_address}\n\n{num_connections} connected"; | ||||
|                         tooltip-format-connected = "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}"; | ||||
|                         tooltip-format-enumerate-connected = "{device_alias}\n{device_address}"; | ||||
|                         tooltip-format-enumerate-connected-battery = "{device_alias}\n{device_address}\n{device_battery_percentage}%"; | ||||
|                         on-click-right = "XDG_CURRENT_DESKTOP=GNOME gnome-control-center bluetooth"; | ||||
|                     }; | ||||
|                     "battery" = { | ||||
|                         interval = 60; | ||||
|                         states = { | ||||
|                             good = 80; | ||||
|                             warning = 30; | ||||
|                             critical = 10; | ||||
|                         }; | ||||
|                         format = "{capacity}% {icon}"; | ||||
|                         format-charging = "{capacity}% "; | ||||
|                         format-plugged = "{capacity}% "; | ||||
|                         format-icons = [ "" "" "" "" "" "" ]; | ||||
|                     }; | ||||
|                     "backlight" = { | ||||
|                         # format = "{percent}% {icon}"; | ||||
|                         format = "{icon}"; | ||||
|                         tooltip-format = "{percent}%"; | ||||
|                         format-icons = [ "" "" "" "" "" "" "" "" "" ]; | ||||
|                     }; | ||||
|                     "wireplumber" = { | ||||
|                         scroll-step = 1; | ||||
|                         format = "{volume}% {icon}";# {format_source}"; | ||||
|                         format-bluetooth = "{volume}% {icon}";# {format_source}"; | ||||
|                         format-bluetooth-muted = " {icon}";# {format_source}"; | ||||
|                         format-muted = "🔇";# {format_source}"; | ||||
|                         format-alt = "{format_source} {icon}"; | ||||
|                         # format-source = " {volume}%"; | ||||
|                         # format-source-muted = ""; | ||||
|                         format-icons = { | ||||
|                             headphone = ""; | ||||
|                             hands-free = ""; | ||||
|                             headset = ""; | ||||
|                             phone = ""; | ||||
|                             portable = ""; | ||||
|                             default = [ | ||||
|                                 "" | ||||
|                                 "" | ||||
|                                 "" | ||||
|                             ]; | ||||
|                         }; | ||||
|                         on-click = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"; | ||||
|                         on-click-right = "XDG_CURRENT_DESKTOP=GNOME gnome-control-center sound"; | ||||
|                     }; | ||||
|                     "memory" = { | ||||
|                         interval = 5; | ||||
|                         format = " {}%"; | ||||
|                         max-length = 10; | ||||
|                     }; | ||||
|                     "tray" = { | ||||
|                         spacing = 5; | ||||
|                     }; | ||||
|                     "custom/notification" = { | ||||
|                         format = "{icon} {}"; | ||||
|                         format-icons = { | ||||
|                             notification = "<span foreground='red'><sup></sup></span>"; | ||||
|                             none = ""; | ||||
|                             dnd-notification = "<span foreground='red'><sup></sup></span>"; | ||||
|                             dnd-none = ""; | ||||
|                             inhibited-notification = "<span foreground='red'><sup></sup></span>"; | ||||
|                             inhibited-none = ""; | ||||
|                             dnd-inhibited-notification = "<span foreground='red'><sup></sup></span>"; | ||||
|                             dnd-inhibited-none = ""; | ||||
|                         }; | ||||
|                         return-type = "json"; | ||||
|                         exec-if = "which swaync-client"; | ||||
|                         exec = "swaync-client -swb"; | ||||
|                         on-click = "swaync-client -t -sw"; | ||||
|                         on-click-right = "swaync-client -d -sw"; | ||||
|                         escape = true; | ||||
|                     }; | ||||
|                     "network" = { | ||||
|                         format =  ""; | ||||
|                         format-ethernet = " {ipaddr}"; | ||||
|                         format-wifi = "{icon}"; | ||||
|                         format-icons = [ "" "" "" "" "" ]; | ||||
|                         format-disconnected = ""; | ||||
|                         tooltip-format = " {ifname} via {gwaddr}"; | ||||
|                         tooltip-format-wifi = '' | ||||
|                              {essid}({signalStrength}%), {frequency} GHz (Interface: {ifname}) | ||||
|                             IP: {ipaddr}    GW: {gwaddr} | ||||
|  | ||||
|                             <span color='#a6da95'>{bandwidthUpBits}</span>    <span color='#ee99a0'>{bandwidthDownBits}</span>    <span color='#c6a0f6'>{bandwidthTotalBits}</span> | ||||
|                         ''; | ||||
|                         tooltip-format-ethernet = '' | ||||
|                              {ifname} - {ipaddr}/{cidr} | ||||
|  | ||||
|                             <span color='#a6da95'>{bandwidthUpBits}</span>    <span color='#ee99a0'>{bandwidthDownBits}</span>    <span color='#c6a0f6'>{bandwidthTotalBits}</span> | ||||
|                         ''; | ||||
|                         tooltip-format-disconnected = "Disconnected"; | ||||
|                         on-click = "XDG_CURRENT_DESKTOP=GNOME gnome-control-center wifi"; | ||||
|                     }; | ||||
|                     "privacy" = { | ||||
|                         icon-spacing = 4; | ||||
|                         # icon-size" = 18; | ||||
|                         transition-duration = 250; | ||||
|                         modules = [ | ||||
|                             { | ||||
|                                 type = "screenshare"; | ||||
|                                 tooltip = true; | ||||
|                                 # tooltip-icon-size = 24 | ||||
|                             } | ||||
|                             { | ||||
|                                 type = "audio-out"; | ||||
|                                 tooltip = true; | ||||
|                                 # tooltip-icon-size = 24 | ||||
|                             } | ||||
|                             { | ||||
|                                 type = "audio-in"; | ||||
|                                 tooltip = true; | ||||
|                                 # tooltip-icon-size = 24 | ||||
|                             } | ||||
|                         ]; | ||||
|                     }; | ||||
|                     on-click = "XDG_CURRENT_DESKTOP=GNOME gnome-control-center sound"; | ||||
|                 }; | ||||
|                 "tray" = { | ||||
|                     spacing = 5; | ||||
|                 }; | ||||
|                 "custom/notification" = { | ||||
|                     tooltip = false; | ||||
|                     format = "{icon} {}"; | ||||
|                     format-icons = { | ||||
|                         notification = "<span foreground='red'><sup></sup></span>"; | ||||
|                         none = ""; | ||||
|                         dnd-notification = "<span foreground='red'><sup></sup></span>"; | ||||
|                         dnd-none = ""; | ||||
|                         inhibited-notification = "<span foreground='red'><sup></sup></span>"; | ||||
|                         inhibited-none = ""; | ||||
|                         dnd-inhibited-notification = "<span foreground='red'><sup></sup></span>"; | ||||
|                         dnd-inhibited-none = ""; | ||||
|                     }; | ||||
|                     return-type = "json"; | ||||
|                     exec-if = "which swaync-client"; | ||||
|                     exec = "swaync-client -swb"; | ||||
|                     on-click = "swaync-client -t -sw"; | ||||
|                     on-click-right = "swaync-client -d -sw"; | ||||
|                     escape = true; | ||||
|                 }; | ||||
|                 "network" = { | ||||
|                     format =  ""; | ||||
|                     format-ethernet = " {ipaddr}"; | ||||
|                     format-wifi = "{icon}"; | ||||
|                     format-icons = [ "" "" "" "" "" ]; | ||||
|                     format-disconnected = ""; | ||||
|                     tooltip-format = " {ifname} via {gwaddr}"; | ||||
|                     # TODO - don't escape the strings in the tooltip | ||||
|                     tooltip-format-wifi = '' | ||||
|                          {essid}({signalStrength}%), {frequency} GHz\nInterface: {ifname} | ||||
|                         IP: {ipaddr}    GW: {gwaddr} | ||||
|  | ||||
|                         <span color='#a6da95'>{bandwidthUpBits}</span> <span color='#ee99a0'>{bandwidthDownBits}</span>    <span color='#c6a0f6'>{bandwidthTotalBits}</span> | ||||
|                     ''; | ||||
|                     tooltip-format-ethernet = '' | ||||
|                          {ifname} - {ipaddr}/{cidr} | ||||
|  | ||||
|                         <span color='#a6da95'>{bandwidthUpBits}</span> <span color='#ee99a0'>{bandwidthDownBits}</span>    <span color='#c6a0f6'>{bandwidthTotalBits}</span> | ||||
|                     ''; | ||||
|                     tooltip-format-disconnected = "Disconnected"; | ||||
|                     on-click = "XDG_CURRENT_DESKTOP=GNOME gnome-control-center wifi"; | ||||
|                 }; | ||||
|                 "privacy" = { | ||||
|                     icon-spacing = 4; | ||||
|                     # icon-size" = 18; | ||||
|                     transition-duration = 250; | ||||
|                     modules = [ | ||||
|                         { | ||||
|                             type = "screenshare"; | ||||
|                             tooltip = true; | ||||
|                             # tooltip-icon-size = 24 | ||||
|                         } | ||||
|                         { | ||||
|                             type = "audio-out"; | ||||
|                             tooltip = true; | ||||
|                             # tooltip-icon-size = 24 | ||||
|                         } | ||||
|                         { | ||||
|                             type = "audio-in"; | ||||
|                             tooltip = true; | ||||
|                             # tooltip-icon-size = 24 | ||||
|                         } | ||||
|                     ]; | ||||
|                 }; | ||||
|             }; | ||||
|  | ||||
|             style = '' | ||||
|                 * { | ||||
|                     font-family: "${cfg.monospaceFont}"; | ||||
|                     font-weight: bold; | ||||
|                     font-size: ${builtins.toString (cfg.fontSizes.desktop + 5)}px; | ||||
|                 } | ||||
|  | ||||
|                 window#waybar { | ||||
|                     background-color: transparent; | ||||
|                 } | ||||
|  | ||||
|                 .module { | ||||
|                     background: rgba(0, 0, 0, 0.6); | ||||
|                     color: white; | ||||
|                     border-radius: 7px; | ||||
|                     margin: 1px 3px; | ||||
|                     padding: 1px 6px; | ||||
|                     animation: bgFade 3600s infinite alternate, textColorFade 3600s infinite alternate; | ||||
|                 } | ||||
|  | ||||
|                 box.module button:hover { | ||||
|                     box-shadow: inset 0 -3px #ffffff; | ||||
|                 } | ||||
|  | ||||
|                 /*.modules-left { | ||||
|                     padding: 3px; | ||||
|                 } | ||||
|  | ||||
|                 .modules-right { | ||||
|                     padding: 3px; | ||||
|                 } | ||||
|  | ||||
|                 .modules-center { | ||||
|                     padding: 3px; | ||||
|                 }*/ | ||||
|  | ||||
|                 #workspaces button { | ||||
|                     color: white; | ||||
|                     background: none; | ||||
|                     animation: textColorFade 3600s infinite alternate; | ||||
|                 } | ||||
|  | ||||
|                 #battery.warning { | ||||
|                     background:rgba(240, 165, 0, 0.6); | ||||
|                 } | ||||
|                 #battery.critical { | ||||
|                     background:rgba(255, 0, 0, 0.6); | ||||
|                 } | ||||
|                 #battery.charging { | ||||
|                     background-color:rgba(14, 173, 0, 0.6); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 #privacy { | ||||
|                     color: #ffffff; | ||||
|                     background:rgba(240, 165, 0, 0.6); | ||||
|                     border-radius: 7px; | ||||
|                     margin: 1px 3px; | ||||
|                     padding: 1px 6px; | ||||
|  | ||||
|                 } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|                 @keyframes bgFade { | ||||
|                     0% { | ||||
|                         background-color: white; | ||||
|                     } | ||||
|                     100% { | ||||
|                         background-color: black; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 @keyframes textColorFade { | ||||
|                     0% { | ||||
|                         color: black; | ||||
|                     } | ||||
|                     /* 45% { | ||||
|                         color: black; | ||||
|                     } */ | ||||
|                     60% { | ||||
|                         color: rgb(29, 38, 96); | ||||
|                     } | ||||
|                     /* 55% { | ||||
|                         color: white; | ||||
|                     } */ | ||||
|                     100% { | ||||
|                         color: white; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|             ''; | ||||
|         }; | ||||
|  | ||||
|         style = '' | ||||
|             * { | ||||
|                 font-family: "${cfg.monospaceFont}"; | ||||
|                 font-weight: bold; | ||||
|                 font-size: ${builtins.toString (cfg.fontSizes.desktop + 7)}px; | ||||
|             } | ||||
|  | ||||
|             window#waybar { | ||||
|                 background-color: transparent; | ||||
|             } | ||||
|  | ||||
|             .module { | ||||
|                 background: rgba(0, 0, 0, 0.6); | ||||
|                 color: white; | ||||
|                 border-radius: 7px; | ||||
|                 padding: 5px 5px 5px 5px; | ||||
|             } | ||||
|             box.module button:hover { | ||||
|                 box-shadow: inset 0 -3px #ffffff; | ||||
|             } | ||||
|  | ||||
|             .modules-left { | ||||
|                 padding: 3px; | ||||
|             } | ||||
|  | ||||
|             .modules-right { | ||||
|                 padding: 3px; | ||||
|             } | ||||
|  | ||||
|             .modules-center { | ||||
|                 padding: 3px; | ||||
|             } | ||||
|  | ||||
|             #workspaces button { | ||||
|                 color: #ffffff; | ||||
|             } | ||||
|  | ||||
|             #battery.warning { | ||||
|                 background:rgba(240, 165, 0, 0.6); | ||||
|             } | ||||
|             #battery.critical { | ||||
|                 background:rgba(255, 0, 0, 0.6); | ||||
|             } | ||||
|         ''; | ||||
|     }; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,13 @@ | ||||
| {pkgs, ...}:  | ||||
| {pkgs, ...}: | ||||
| { | ||||
|     home.packages = [ | ||||
|         pkgs.kubie | ||||
|         pkgs.kubectl | ||||
|     ]; | ||||
|      | ||||
|  | ||||
|     # Add the shell alias | ||||
|     programs.fish.shellAliases = { | ||||
|         k = "kubectl"; | ||||
|     }; | ||||
|  | ||||
| } | ||||
|   | ||||
							
								
								
									
										112
									
								
								modules/home-manager/launcher.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								modules/home-manager/launcher.nix
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | ||||
| { config, pkgs, lib, ... }: | ||||
| let | ||||
|   cfg = config.nix-config.style; | ||||
|  | ||||
|   powerMenu = pkgs.writeShellScriptBin "power-menu" '' | ||||
|     options=" Power Off\n Reboot\n Lock\n Suspend" | ||||
|     selected=$(echo -e "$options" | fuzzel --dmenu --prompt "Power Menu" --lines 4 --width 20) | ||||
|  | ||||
|     case "$selected" in | ||||
|       " Power Off") systemctl poweroff ;; | ||||
|       " Reboot") systemctl reboot ;; | ||||
|       " Lock") hyprlock ;; | ||||
|       " Suspend") systemctl suspend ;; | ||||
|       *) exit 1 ;; | ||||
|     esac | ||||
|   ''; | ||||
|  | ||||
|   filePicker = pkgs.writeShellScriptBin "file-picker" '' | ||||
|     files=$(${lib.getExe pkgs.fd} . $HOME --type f) | ||||
|     filesShortened=$(echo "$files" | sed "s|$HOME|~|g" | awk -F/ '{print $(NF)" ("$0")"}') | ||||
|  | ||||
|     selected=$(echo "$filesShortened" | fuzzel --dmenu --prompt "🔎 " --placeholder "File search" --index) | ||||
|  | ||||
|  | ||||
|     if [ -n "$selected" ]; then | ||||
|       # Since fuzzel was launched with the --index option the actual path is now files[selected] | ||||
|       selectedPlusOne=$((selected + 1)) | ||||
|       file=$(echo "$files" | sed -n "''${selectedPlusOne}p") | ||||
|       xdg-open "$file" | ||||
|       # plus one | ||||
|     else | ||||
|       echo "No file selected" | ||||
|       exit 1 | ||||
|     fi | ||||
|   ''; | ||||
| in | ||||
| { | ||||
|  | ||||
|   options.nix-config = { | ||||
|     powerMenu = lib.mkOption { | ||||
|       description = "Package to use as a power menu"; | ||||
|       type = lib.types.package; | ||||
|       default = powerMenu; | ||||
|     }; | ||||
|  | ||||
|     launcher = lib.mkOption { | ||||
|       description = "Configuration for the launcher"; | ||||
|       type = lib.types.package; | ||||
|       default = pkgs.fuzzel; | ||||
|     }; | ||||
|  | ||||
|     filePicker = lib.mkOption { | ||||
|       description = "Package to use as a file picker"; | ||||
|       type = lib.types.package; | ||||
|       default = filePicker; | ||||
|     }; | ||||
|   }; | ||||
|  | ||||
|   config = { | ||||
|     programs.fuzzel = { | ||||
|       enable = true; | ||||
|  | ||||
|       settings = { | ||||
|         main = { | ||||
|           font = "monospace:size=${builtins.toString (cfg.fontSizes.applications - 1)}"; | ||||
|           terminal = "${lib.getExe pkgs.kitty}"; | ||||
|           layer = "overlay"; #or top? | ||||
|           use-bold = true; | ||||
|           dpi-aware = true; | ||||
|           icons-enabled = true; | ||||
|           match-mode = "fzf"; | ||||
|           horizontal-pad = cfg.fontSizes.applications + 5; | ||||
|           vertical-pad = cfg.fontSizes.applications + 5; | ||||
|           inner-pad = cfg.fontSizes.applications; | ||||
|           show-actions = true; | ||||
|           lines = 12; | ||||
|           width = 50; | ||||
|         }; | ||||
|  | ||||
|         colors = { | ||||
|           background = "000000aa"; | ||||
|           text = "ffffffaa"; | ||||
|  | ||||
|           # prompt | ||||
|  | ||||
|           # placeholder | ||||
|  | ||||
|           # input | ||||
|  | ||||
|           match = "ffffffaa"; | ||||
|  | ||||
|           selection = "00000000"; | ||||
|  | ||||
|           selection-text = "ffffffbb"; | ||||
|  | ||||
|           selection-match = "ffffffaa"; | ||||
|         }; | ||||
|  | ||||
|         border = { | ||||
|           width = 0; | ||||
|           radius = 15; | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     home.packages = with pkgs; [ | ||||
|       powerMenu | ||||
|       filePicker | ||||
|     ]; | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										110
									
								
								modules/home-manager/notifications.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								modules/home-manager/notifications.nix
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| { config, pkgs, lib, ... }: | ||||
| let | ||||
|   cfg = config.nix-config.style; | ||||
| in | ||||
| { | ||||
|   services.swaync = { | ||||
|     enable = true; | ||||
|  | ||||
|     settings = { | ||||
|       control-center-margin-top = 13; | ||||
|       control-center-margin-bottom = 0; | ||||
|       control-center-margin-right = 14; | ||||
|       control-center-margin-left = 0; | ||||
|       notification-2fa-action = true; | ||||
|       notification-inline-replies = true; | ||||
|       notification-icon-size = 48; | ||||
|       notification-body-image-height = 160; | ||||
|       notification-body-image-width = 200; | ||||
|       notification-window-width = 400; | ||||
|       timeout = 6; | ||||
|       timeout-low = 3; | ||||
|       timeout-critical = 0; | ||||
|  | ||||
|       image-visibility = "when-available"; | ||||
|       transition-time = 200; | ||||
|       hide-on-clear = false; | ||||
|       hide-on-action = true; | ||||
|       script-fail-notify = true; | ||||
|       widgets = [ | ||||
|         "dnd" | ||||
|         "buttons-grid" | ||||
|         "mpris" | ||||
|         "volume" | ||||
|         "backlight" | ||||
|         "title" | ||||
|         "notifications" | ||||
|       ]; | ||||
|       widget-config = { | ||||
|         title = { | ||||
|           text = "Notifications"; | ||||
|           clear-all-button = true; | ||||
|           button-text = ""; | ||||
|         }; | ||||
|         dnd = { | ||||
|           text = "Do Not Disturb"; | ||||
|         }; | ||||
|         label = { | ||||
|           max-lines = 1; | ||||
|           text = "Notification"; | ||||
|         }; | ||||
|         mpris = { | ||||
|           image-size = 50; | ||||
|           image-radius = 0; | ||||
|         }; | ||||
|         volume = { | ||||
|           label = ""; | ||||
|         }; | ||||
|         backlight = { | ||||
|           label = ""; | ||||
|           device = "amdgpu_bl2"; | ||||
|         }; | ||||
|         buttons-grid = { | ||||
|           actions = [ | ||||
|             { | ||||
|               label = ""; | ||||
|               command = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"; | ||||
|               type = "toggle"; | ||||
|             } | ||||
|             { | ||||
|               label = ""; | ||||
|               command = "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"; | ||||
|               type = "toggle"; | ||||
|             } | ||||
|             { | ||||
|               label = ""; | ||||
|               command = "nm-connection-editor"; | ||||
|             } | ||||
|             { | ||||
|               label = ""; | ||||
|               command = "blueman-manager"; | ||||
|             } | ||||
|             { | ||||
|               label = ""; | ||||
|               command = "bash -c $HOME/.config/hypr/scripts/airplaneMode.sh"; | ||||
|               type = "toggle"; | ||||
|             } | ||||
|             { | ||||
|               label = ""; | ||||
|               command = "shutdown now"; | ||||
|             } | ||||
|             { | ||||
|               label = ""; | ||||
|               command = "hyprlock"; | ||||
|             } | ||||
|             { | ||||
|               label = ""; | ||||
|               command = "~/.config/hypr/scripts/wlogout.sh"; | ||||
|             } | ||||
|           ]; | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
|  | ||||
|     style = '' | ||||
|       * { | ||||
|         font-family: "monospace"; | ||||
|       } | ||||
|     ''; | ||||
|   }; | ||||
| } | ||||
| @@ -2,6 +2,9 @@ | ||||
| { | ||||
|   programs.ssh.enable = true; | ||||
|   programs.ssh.matchBlocks = { | ||||
|     "*" = { | ||||
|       identityFile = "${config.home.homeDirectory}/.ssh/main_key"; | ||||
|     }; | ||||
|     ela = lib.hm.dag.entryBefore ["eiger"] { | ||||
|       hostname = "ela.cscs.ch"; | ||||
|       user = "rmoll"; | ||||
|   | ||||
| @@ -7,7 +7,7 @@ in | ||||
|         cursor = { | ||||
|             size = lib.mkOption { | ||||
|                 type = lib.types.int; | ||||
|                 default = 35; | ||||
|                 default = 22; | ||||
|                 description = "Size of the cursor in pixels."; | ||||
|             }; | ||||
|         }; | ||||
| @@ -57,8 +57,8 @@ in | ||||
|             autoEnable = false; | ||||
|  | ||||
|             cursor = { | ||||
|                 package = pkgs.apple-cursor; | ||||
|                 name = "macOS"; | ||||
|                 package = pkgs.bibata-cursors; | ||||
|                 name = "Bibata-Modern-Ice"; | ||||
|                 size = cfg.cursor.size; | ||||
|             }; | ||||
|  | ||||
| @@ -84,7 +84,7 @@ in | ||||
|                 }; | ||||
|  | ||||
|                 monospace = { | ||||
|                     package = pkgs.nerdfonts.override { fonts = [ "FiraCode" ]; }; | ||||
|                     package = pkgs.nerd-fonts.fira-code; | ||||
|                     name = cfg.monospaceFont; | ||||
|                 }; | ||||
|  | ||||
|   | ||||
							
								
								
									
										9
									
								
								modules/home-manager/uxplay.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								modules/home-manager/uxplay.nix
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   lib, pkgs, ... | ||||
| }: | ||||
| { | ||||
|   # requires avahi or similar | ||||
|  | ||||
|   home.packages = with pkgs; [ uxplay ]; | ||||
|  | ||||
| } | ||||
| @@ -1,95 +1,139 @@ | ||||
| { config, pkgs, lib, ... }: | ||||
| let | ||||
|   cfg = config.nix-config.style; | ||||
|  | ||||
|   wofiPowerMenu = pkgs.writeShellScriptBin "wofi-power-menu" '' | ||||
|     #!/usr/bin/env bash | ||||
|  | ||||
|     options=" Power Off\n Reboot\n Lock\n Suspend" | ||||
|     selected=$(echo -e "$options" | wofi --dmenu --prompt "Power Menu") | ||||
|     #  --width 300 --height 250 | ||||
|  | ||||
|     case "$selected" in | ||||
|       " Power Off") systemctl poweroff ;; | ||||
|       " Reboot") systemctl reboot ;; | ||||
|       " Lock") hyprlock ;; | ||||
|       " Suspend") systemctl suspend ;; | ||||
|       *) exit 1 ;; | ||||
|     esac | ||||
|   ''; | ||||
|  | ||||
|   wofiFilePicker = pkgs.writeShellScriptBin "wofi-file-picker" '' | ||||
|     #!/usr/bin/env bash | ||||
|     initial=$(find $HOME -maxdepth 2 -type f) | ||||
|     selected=$(printf "%s\n" $initial | wofi --dmenu --prompt "Select a file") | ||||
|  | ||||
|     if [ -n "$selected" ]; then | ||||
|       xdg-open "$selected" | ||||
|     else | ||||
|       echo "No file selected" | ||||
|       exit 1 | ||||
|     fi | ||||
|   ''; | ||||
| in | ||||
| { | ||||
|  | ||||
|   home.packages = with pkgs; [ wofi-emoji ]; | ||||
|   options.nix-config = { | ||||
|     powerMenu = lib.mkOption { | ||||
|       description = "Package to use as a power menu"; | ||||
|       type = lib.types.package; | ||||
|       default = wofiPowerMenu; | ||||
|     }; | ||||
|   }; | ||||
|  | ||||
|   programs.wofi = { | ||||
|     enable = true; | ||||
|   config = { | ||||
|     programs.wofi = { | ||||
|       enable = true; | ||||
|  | ||||
|     settings = { | ||||
|       # global layout | ||||
|       width = "50%"; | ||||
|       height = "50%"; | ||||
|       orientation = "vertical"; | ||||
|       hide_scroll = true; | ||||
|       line_wrap = "off"; | ||||
|       dynamic_lines = true; | ||||
|       settings = { | ||||
|         # global layout | ||||
|         width = "50%"; | ||||
|         height = "50%"; | ||||
|         orientation = "vertical"; | ||||
|         hide_scroll = true; | ||||
|         line_wrap = "off"; | ||||
|         dynamic_lines = true; | ||||
|  | ||||
|       # search behaviour | ||||
|       matching = "fuzzy"; | ||||
|       single_click = true; | ||||
|         # search behaviour | ||||
|         matching = "fuzzy"; | ||||
|         single_click = true; | ||||
|  | ||||
|  | ||||
|       show = "drun"; | ||||
|       prompt = "Launch..."; | ||||
|       # normal_window = true; | ||||
|       layer = "top"; | ||||
|       term = "foot"; | ||||
|       halign = "fill"; | ||||
|         show = "drun"; | ||||
|         prompt = "Launch..."; | ||||
|         # normal_window = true; | ||||
|         layer = "top"; | ||||
|         term = "foot"; | ||||
|         halign = "fill"; | ||||
|  | ||||
|       # Rich rendering | ||||
|       allow_markup = true; | ||||
|       allow_images = true; | ||||
|       image_size = 24; | ||||
|         # Rich rendering | ||||
|         allow_markup = true; | ||||
|         allow_images = true; | ||||
|         image_size = 24; | ||||
|  | ||||
|  | ||||
|       exec_search = false; | ||||
|       hide_search = false; | ||||
|       parse_search = false; | ||||
|       insensitive = true; | ||||
|       no_actions = true; | ||||
|         exec_search = false; | ||||
|         hide_search = false; | ||||
|         parse_search = false; | ||||
|         insensitive = true; | ||||
|         no_actions = true; | ||||
|  | ||||
|  | ||||
|       filter_rate = 100; | ||||
|       key_expand = "Tab"; | ||||
|       key_exit = "Escape"; | ||||
|         filter_rate = 100; | ||||
|         key_expand = "Tab"; | ||||
|         key_exit = "Escape"; | ||||
|  | ||||
|       }; | ||||
|  | ||||
|  | ||||
|       style = '' | ||||
|         * { | ||||
|           font-family: ${cfg.monospaceFont}; | ||||
|           font-size: ${builtins.toString (cfg.fontSizes.desktop + 8)}px; | ||||
|           color: white; | ||||
|           background: transparent; | ||||
|         } | ||||
|  | ||||
|         #window { | ||||
|           background: rgba(1, 1, 1, 0.5); | ||||
|           margin: auto; | ||||
|           padding: 10px; | ||||
|         } | ||||
|  | ||||
|         #input { | ||||
|           padding: 10px; | ||||
|           margin-bottom: 10px; | ||||
|           border-radius: 15px; | ||||
|         } | ||||
|  | ||||
|         #outer-box { | ||||
|           padding: 20px; | ||||
|         } | ||||
|  | ||||
|         #img { | ||||
|           margin-right: 6px; | ||||
|         } | ||||
|  | ||||
|         #entry { | ||||
|           padding: 10px; | ||||
|           border-radius: 15px; | ||||
|         } | ||||
|  | ||||
|         #entry:selected { | ||||
|           background-color: #2e3440; | ||||
|           outline: none; | ||||
|           border: none; | ||||
|         } | ||||
|  | ||||
|         #text { | ||||
|           margin: 2px; | ||||
|         } | ||||
|       ''; | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     style = '' | ||||
|       * { | ||||
|         font-family: ${cfg.monospaceFont}; | ||||
|         font-size: ${builtins.toString (cfg.fontSizes.desktop + 8)}px; | ||||
|         color: white; | ||||
|         background: transparent; | ||||
|       } | ||||
|  | ||||
|       #window { | ||||
|         background: rgba(1, 1, 1, 0.5); | ||||
|         margin: auto; | ||||
|         padding: 10px; | ||||
|       } | ||||
|  | ||||
|       #input { | ||||
|         padding: 10px; | ||||
|         margin-bottom: 10px; | ||||
|         border-radius: 15px; | ||||
|       } | ||||
|  | ||||
|       #outer-box { | ||||
|         padding: 20px; | ||||
|       } | ||||
|  | ||||
|       #img { | ||||
|         margin-right: 6px; | ||||
|       } | ||||
|  | ||||
|       #entry { | ||||
|         padding: 10px; | ||||
|         border-radius: 15px; | ||||
|       } | ||||
|  | ||||
|       #entry:selected { | ||||
|         background-color: #2e3440; | ||||
|       } | ||||
|  | ||||
|       #text { | ||||
|         margin: 2px; | ||||
|       } | ||||
|     ''; | ||||
|     home.packages = with pkgs; [ | ||||
|       wofiPowerMenu | ||||
|       wofi-emoji | ||||
|     ]; | ||||
|   }; | ||||
| } | ||||
|   | ||||
| @@ -19,4 +19,14 @@ | ||||
|     ]; | ||||
|   }; | ||||
|  | ||||
|  | ||||
|   xdg.mimeApps.defaultApplications = { | ||||
|     "text/*" = [ "code" ]; | ||||
|     "application/x-yaml" = [ "code" ]; | ||||
|  | ||||
|     "application/pdf" = [ "papers" ]; | ||||
|     "image/*" = [ "loupe" ]; | ||||
|     "video/*" = [ "showtime" ]; | ||||
|   }; | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user