diff --git a/home-manager/home.nix b/home-manager/home.nix index 5aa2c1f..b34eed4 100755 --- a/home-manager/home.nix +++ b/home-manager/home.nix @@ -18,10 +18,9 @@ ./modules/git.nix ./modules/programs.nix ./modules/custom/config.nix - ./modules/hypr/hypr.nix # TODO: make file with var for enable/disable hyprland + ./modules/hypr/hypr.nix ./modules/tmux.nix ]; - # programs.bash.bashrcExtra = ''echo "entering zsh" && zsh''; home.pointerCursor = let getFrom = url: hash: name: { diff --git a/home-manager/modules/hypr/hypr.nix b/home-manager/modules/hypr/hypr.nix index d0af7d2..93acc7a 100644 --- a/home-manager/modules/hypr/hypr.nix +++ b/home-manager/modules/hypr/hypr.nix @@ -1,7 +1,6 @@ { config, pkgs, lib, ... }: # TODO: -# - configure comands like hyprpaper, waybar, etc. # - make hyprexpo work { @@ -18,12 +17,19 @@ ./hypridle.nix # done ]; home.packages = with pkgs; [ + (writeShellScriptBin "next_wallpaper" + (builtins.readFile ./scripts/wallpaper/next_wallpaper.sh)) + (writeShellScriptBin "move_wallpaper" + (builtins.readFile ./scripts/wallpaper/move_wallpaper.sh)) + (writeShellScriptBin "fetch_wallpaper" + (builtins.readFile ./scripts/wallpaper/fetch_wallpaper.sh)) hyprland brightnessctl playerctl hyprshot nemo pywal + jq ]; services.swww.enable = true; programs.hyprpanel = { diff --git a/home-manager/modules/hypr/hyprland/keybinds.nix b/home-manager/modules/hypr/hyprland/keybinds.nix index afcd925..b207184 100644 --- a/home-manager/modules/hypr/hyprland/keybinds.nix +++ b/home-manager/modules/hypr/hyprland/keybinds.nix @@ -56,7 +56,15 @@ "${super}, L, exec, loginctl lock-session" '' - ${super}, Return, exec, ~/.config/hypr/scripts/launch_first_available.sh "kitty" "foot" "alacritty" "wezterm" "konsole" "kgx" "uxterm" "xterm" + ${super}+Shift, D, exec, ~/.config/hypr/scripts/wallpaper/fetch_wallpaper.sh + '' + + '' + ${super}+Shift, C, exec, ~/.config/hypr/scripts/wallpaper/next_wallpaper.sh -f $(zenity --title "Pick a wallpaper" --file-selection --file-filter \*.png) + '' + + '' + ${super}, Return, exec, ~/.config/hypr/scripts/launch_first_available.sh "kitty" "foot" "alacritty" "wezterm" "konsole" "kgx" "uxterm" "xterm" '' "${super}, T, exec, telegram-desktop" '' @@ -67,7 +75,7 @@ ${super}, C, exec, ~/.config/hypr/scripts/launch_first_available.sh "code" "codium" "cursor" "zed" "zedit" "zeditor" "kate" "gnome-text-editor" "emacs" "command -v nvim && kitty -1 nvim"'' '' - Ctrl+Shift, Escape, exec, ~/.config/hypr/scripts/launch_first_available.sh "kitty -1 fish -c btop"'' + Ctrl+Shift, Escape, exec, ~/.config/hypr/scripts/launch_first_available.sh "kitty -1 zsh -c btop"'' "${super}+Shift, 1, exec, ~/.config/hypr/scripts/workspace_action.sh movetoworkspacesilent 1" "${super}+Shift, 2, exec, ~/.config/hypr/scripts/workspace_action.sh movetoworkspacesilent 2" "${super}+Shift, 3, exec, ~/.config/hypr/scripts/workspace_action.sh movetoworkspacesilent 3" diff --git a/home-manager/modules/hypr/scripts/wallpaper/fetch_wallpaper.sh b/home-manager/modules/hypr/scripts/wallpaper/fetch_wallpaper.sh new file mode 100755 index 0000000..b34031f --- /dev/null +++ b/home-manager/modules/hypr/scripts/wallpaper/fetch_wallpaper.sh @@ -0,0 +1,135 @@ +#!/usr/bin/env bash +# fetch_wallpaper.sh +# Requires: wl-paste, curl, jq, move-wallpaper, next-wallpaper + +set -euo pipefail + +URL="$(wl-paste --no-newline || true)" +if [ -z "$URL" ]; then + echo "No URL in clipboard" >&2 + exit 1 +fi + +# extract id (last path segment, strip trailing slash and query) +WALLPAPER_ID="$(printf '%s' "$URL" | sed -E 's#^.*/##; s/[/?].*$//')" +if [ -z "$WALLPAPER_ID" ]; then + echo "Could not extract id from URL: $URL" >&2 + exit 1 +fi + +# Configuration +TEMP_DIR="/tmp/wallhaven_downloads" +API_KEY="$(pass api/wallhaven)" # Can set API key as environment variable +TARGET_RESOLUTION="2560x1600" + + +# Validate input +if [[ -z "$WALLPAPER_ID" ]]; then + echo "Error: No content in clipboard" + exit 1 +fi + +if [[ ! "$WALLPAPER_ID" =~ ^[a-zA-Z0-9]{4,8}$ ]]; then + echo "Error: Invalid wallhaven ID format: $WALLPAPER_ID" + exit 1 +fi + +# Create temp directory +mkdir -p "$TEMP_DIR" + +# Build API URL +API_URL="https://wallhaven.cc/api/v1/w/$WALLPAPER_ID" +if [[ -n "$API_KEY" ]]; then + API_URL="$API_URL?apikey=$API_KEY" +fi + +echo "Fetching wallpaper info for ID: $WALLPAPER_ID" + +# Fetch wallpaper data from API +response=$(curl -s -f "$API_URL") +curl_exit_code=$? + +if [[ $curl_exit_code -ne 0 ]]; then + echo "Error: Failed to fetch data from wallhaven API (curl exit: $curl_exit_code)" + exit 1 +fi + +# Check if jq is available for proper JSON parsing +if ! command -v jq &> /dev/null; then + echo "Error: jq is required for JSON parsing. Please install jq." + echo "Ubuntu/Debian: sudo apt install jq" + echo "Fedora: sudo dnf install jq" + echo "macOS: brew install jq" + exit 1 +fi + +# Parse JSON response +if echo "$response" | jq -e '.error' > /dev/null; then + error_msg=$(echo "$response" | jq -r '.error.message') + echo "API Error: $error_msg" + exit 1 +fi + +# Extract wallpaper information +wallpaper_data=$(echo "$response" | jq -r '.data') + +if [[ "$wallpaper_data" == "null" || -z "$wallpaper_data" ]]; then + echo "Error: No wallpaper data found in API response" + exit 1 +fi + +# Get image URL and details +image_url=$(echo "$response" | jq -r '.data.path') +resolution=$(echo "$response" | jq -r '.data.resolution') +file_type=$(echo "$response" | jq -r '.data.file_type') +file_size=$(echo "$response" | jq -r '.data.file_size') +purity=$(echo "$response" | jq -r '.data.purity') + +# Validate extracted data +if [[ -z "$image_url" || "$image_url" == "null" ]]; then + echo "Error: Could not extract image URL from API response" + exit 1 +fi + +echo "Wallpaper details:" +echo " Resolution: $resolution" +echo " File type: $file_type" +echo " File size: $((file_size / 1024)) KB" +echo " Purity: $purity" +echo " URL: $image_url" + +# Check if resolution matches target +if [[ "$resolution" != "$TARGET_RESOLUTION" ]]; then + echo "Warning: Wallpaper resolution is $resolution (target: $TARGET_RESOLUTION)" +fi + +# Download the image +filename=$(basename "$image_url") +full_path="$TEMP_DIR/$filename" + +echo "Downloading wallpaper to: $full_path" + +if curl -s -f -o "$full_path" "$image_url"; then + # Verify download + if [[ -f "$full_path" && -s "$full_path" ]]; then + downloaded_size=$(stat -c%s "$full_path" 2>/dev/null || stat -f%z "$full_path" 2>/dev/null) + echo "Download successful: $full_path ($((downloaded_size / 1024)) KB)" + + # Execute move_wallpaper command + echo "Executing: move_wallpaper -r \"$full_path\"" + if move_wallpaper -r "$full_path" 2>/dev/null; then + echo "Wallpaper processing completed successfully" + else + echo "move_wallpaper command completed (exit status ignored as requested)" + fi + + zenity --notification --text "Wallpaper downloaded!" + else + echo "Error: Downloaded file is empty or missing" + exit 1 + fi +else + echo "Error: Failed to download the wallpaper from: $image_url" + exit 1 +fi + diff --git a/home-manager/modules/zsh/move_wallpaper.sh b/home-manager/modules/hypr/scripts/wallpaper/move_wallpaper.sh similarity index 100% rename from home-manager/modules/zsh/move_wallpaper.sh rename to home-manager/modules/hypr/scripts/wallpaper/move_wallpaper.sh diff --git a/home-manager/modules/zsh/next_wallpaper.sh b/home-manager/modules/hypr/scripts/wallpaper/next_wallpaper.sh similarity index 70% rename from home-manager/modules/zsh/next_wallpaper.sh rename to home-manager/modules/hypr/scripts/wallpaper/next_wallpaper.sh index 3e524e3..b6186d3 100755 --- a/home-manager/modules/zsh/next_wallpaper.sh +++ b/home-manager/modules/hypr/scripts/wallpaper/next_wallpaper.sh @@ -4,7 +4,55 @@ # Then call: swww img "$WALLPAPER" set -euo pipefail +# Handle -f anywhere in argv: remove it from "$@" so getopts can still parse -r. +FORCE_FILE="" +_remaining=() +while [ $# -gt 0 ]; do + case "$1" in + -f) + if [ -z "${2-}" ]; then + echo "Option -f requires an argument" >&2 + exit 2 + fi + FORCE_FILE="$2" + shift 2 + ;; + *) + _remaining+=("$1") + shift + ;; + esac +done +# restore remaining args for subsequent getopts +if [ "${#_remaining[@]}" -gt 0 ]; then + set -- "${_remaining[@]}" +else + set -- +fi +# If -f was given, validate and immediately update the symlink & wallpaper, then exit. +if [ -n "$FORCE_FILE" ]; then + if [ ! -f "$FORCE_FILE" ]; then + echo "Specified wallpaper not found: $FORCE_FILE" >&2 + exit 1 + fi + + TARGET="$(readlink -f "$FORCE_FILE")" + SYMLINK_PATH="$HOME/Pictures/wallpaper.png" + + TMP_LINK="$(mktemp -u "${SYMLINK_PATH}.tmp.XXXX")" + ln -sfn -- "$TARGET" "$TMP_LINK" + mv -f "$TMP_LINK" "$SYMLINK_PATH" + + # export and trigger compositor/wallpaper tools + WALLPAPER="$TARGET" + swww img "$WALLPAPER" --transition-type fade + hyprpanel -q ; hyprpanel & disown + wal -c + wal -n -i "$WALLPAPER" + + exit 0 +fi RANDOM_MODE=0 while getopts "r" opt; do case "$opt" in diff --git a/home-manager/modules/zsh/zsh.nix b/home-manager/modules/zsh/zsh.nix index 2471260..fea85f6 100644 --- a/home-manager/modules/zsh/zsh.nix +++ b/home-manager/modules/zsh/zsh.nix @@ -4,11 +4,7 @@ home.packages = with pkgs; [ (writeShellScriptBin "select_command" (builtins.readFile ./select_command.sh)) - (writeShellScriptBin "move_wallpaper" - (builtins.readFile ./move_wallpaper.sh)) (writeShellScriptBin "move_avatar" (builtins.readFile ./move_avatar.sh)) - (writeShellScriptBin "next_wallpaper" - (builtins.readFile ./next_wallpaper.sh)) (writeShellScriptBin "update_git_config" (builtins.readFile ./update_system_from_git.sh)) zsh-powerlevel10k @@ -19,6 +15,7 @@ bat neofetch yazi + zenity ]; home.file.".p10k.zsh".source = ./p10k.zsh; @@ -101,6 +98,9 @@ mv_w = "move_wallpaper"; next_w = "next_wallpaper"; + next_wr = "next_wallpaper -r"; + next_wf = '' + next_wallpaper -f $(zenity --title "Pick a wallpaper" --file-selection --file-filter \*.png)''; mv_avatar = "move_avatar"; t = "todo";