diff --git a/configs/quickshell/env.sh b/configs/quickshell/env.sh new file mode 100644 index 0000000..9300630 --- /dev/null +++ b/configs/quickshell/env.sh @@ -0,0 +1 @@ +export LD_LIBRARY_PATH="/nix/store/xm08aqdd7pxcdhm0ak6aqb1v7hw5q6ri-gcc-14.3.0-lib/lib:/nix/store/xx7cm72qy2c0643cm1ipngd87aqwkcdp-glibc-2.40-66/lib:/nix/store/l7xwm1f6f3zj2x8jwdbi8gdyfbx07sh7-zlib-1.3.1/lib:/nix/store/b9p0zpa93hwvh4d0r1rmgc2500yx2ldn-libffi-3.5.2/lib:/nix/store/61i74yjkj9p1qphfl7018ja4sdwkipx0-openssl-3.6.0/lib:/nix/store/xgavznqg1ay2hycpp7yy9ia1n751jcla-bzip2-1.0.8/lib:/nix/store/q5vlz5jl6p7mv220s2vf6z5pqi1n935z-xz-5.8.1/lib:/nix/store/yijhn548p2589pkybgvbhll09bqsxy0q-ncurses-6.5/lib:/nix/store/41cgbkwax6pd1sgi8l81mamv6rvarryj-readline-8.3p1/lib:/nix/store/l30c488dws7z5mazacqsmj25izb9jlp2-sqlite-3.50.4/lib" diff --git a/configs/quickshell/ii/GlobalStates.qml b/configs/quickshell/ii/GlobalStates.qml index 47c4e61..e389286 100644 --- a/configs/quickshell/ii/GlobalStates.qml +++ b/configs/quickshell/ii/GlobalStates.qml @@ -1,3 +1,5 @@ +import qs.modules.common +import qs import QtQuick import Quickshell import Quickshell.Hyprland @@ -15,34 +17,19 @@ Singleton { property bool osdVolumeOpen: false property bool oskOpen: false property bool overviewOpen: false - property bool sessionOpen: false - property bool workspaceShowNumbers: false - property bool superReleaseMightTrigger: true property bool screenLocked: false property bool screenLockContainsCharacters: false + property bool sessionOpen: false + property bool superDown: false + property bool superReleaseMightTrigger: true + property bool workspaceShowNumbers: false property real screenZoom: 1 onScreenZoomChanged: { Quickshell.execDetached(["hyprctl", "keyword", "cursor:zoom_factor", root.screenZoom.toString()]); } Behavior on screenZoom { - NumberAnimation { duration: 200; easing.type: Easing.OutCubic } - // animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) - } - - // When user is not reluctant while pressing super, they probably don't need to see workspace numbers - onSuperReleaseMightTriggerChanged: { - workspaceShowNumbersTimer.stop() - } - - Timer { - id: workspaceShowNumbersTimer - interval: 500 // Config.options.bar.workspaces.showNumberDelay - // interval: 0 - repeat: false - onTriggered: { - workspaceShowNumbers = true - } + animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) } GlobalShortcut { @@ -50,11 +37,10 @@ Singleton { description: "Hold to show workspace numbers, release to show icons" onPressed: { - workspaceShowNumbersTimer.start() + root.superDown = true } onReleased: { - workspaceShowNumbersTimer.stop() - workspaceShowNumbers = false + root.superDown = false } } @@ -69,4 +55,18 @@ Singleton { screenZoom = Math.max(screenZoom - 0.4, 1) } } + + IpcHandler { + target: "theme" + + function dark() { + const wallpaper = Config.options.background.wallpaperPath || `${Quickshell.env("HOME")}/Pictures/Wallpapers/konachan_random_image.png` + Quickshell.execDetached(["bash", `${Quickshell.env("HOME")}/.config/quickshell/scripts/colors/switchwall-wrapper.sh`, wallpaper, "--mode", "dark"]) + } + + function light() { + const wallpaper = Config.options.background.wallpaperPath || `${Quickshell.env("HOME")}/Pictures/Wallpapers/konachan_random_image.png` + Quickshell.execDetached(["bash", `${Quickshell.env("HOME")}/.config/quickshell/scripts/colors/switchwall-wrapper.sh`, wallpaper, "--mode", "light"]) + } + } } \ No newline at end of file diff --git a/configs/quickshell/ii/modules/bar/UtilButtons.qml b/configs/quickshell/ii/modules/bar/UtilButtons.qml index a9ecbb5..1e32bd5 100644 --- a/configs/quickshell/ii/modules/bar/UtilButtons.qml +++ b/configs/quickshell/ii/modules/bar/UtilButtons.qml @@ -5,6 +5,7 @@ import QtQuick import QtQuick.Layouts import Quickshell import Quickshell.Hyprland +import Quickshell.Io import Quickshell.Services.Pipewire import Quickshell.Services.UPower @@ -14,6 +15,20 @@ Item { implicitWidth: rowLayout.implicitWidth + rowLayout.spacing * 2 implicitHeight: rowLayout.implicitHeight + Process { + id: themeSwitchProcess + running: false + stdout: SplitParser { + onRead: data => console.log("switchwall:", data) + } + stderr: SplitParser { + onRead: data => console.log("switchwall err:", data) + } + onExited: (code, status) => { + console.log("switchwall exited:", code) + } + } + RowLayout { id: rowLayout @@ -25,7 +40,7 @@ Item { visible: Config.options.bar.utilButtons.showScreenSnip sourceComponent: CircleUtilButton { Layout.alignment: Qt.AlignVCenter - onClicked: Quickshell.execDetached(["qs", "-p", Quickshell.shellPath("screenshot.qml")]) + onClicked: Quickshell.execDetached(["quickshell", "-p", Quickshell.shellPath("screenshot.qml")]) MaterialSymbol { horizontalAlignment: Qt.AlignHCenter fill: 1 @@ -90,11 +105,11 @@ Item { sourceComponent: CircleUtilButton { Layout.alignment: Qt.AlignVCenter onClicked: event => { - if (Appearance.m3colors.darkmode) { - Hyprland.dispatch(`exec ${Directories.wallpaperSwitchScriptPath} --mode light --noswitch`); - } else { - Hyprland.dispatch(`exec ${Directories.wallpaperSwitchScriptPath} --mode dark --noswitch`); - } + const mode = Appearance.m3colors.darkmode ? "light" : "dark" + const wallpaper = Config.options.background.wallpaperPath || `${Quickshell.env("HOME")}/Pictures/Wallpapers/konachan_random_image.png` + themeSwitchProcess.command = ["bash", `${Directories.scriptPath}/colors/switchwall-wrapper.sh`, wallpaper, "--mode", mode] + themeSwitchProcess.running = false + themeSwitchProcess.running = true } MaterialSymbol { horizontalAlignment: Qt.AlignHCenter @@ -129,9 +144,9 @@ Item { horizontalAlignment: Qt.AlignHCenter fill: 0 text: switch(PowerProfiles.profile) { - case PowerProfile.PowerSaver: return "battery_saver" - case PowerProfile.Balanced: return "dynamic_form" - case PowerProfile.Performance: return "speed" + case PowerProfile.PowerSaver: return "energy_savings_leaf" + case PowerProfile.Balanced: return "settings_slow_motion" + case PowerProfile.Performance: return "local_fire_department" } iconSize: Appearance.font.pixelSize.large color: Appearance.colors.colOnLayer2 diff --git a/configs/quickshell/ii/modules/common/widgets/LightDarkPreferenceButton.qml b/configs/quickshell/ii/modules/common/widgets/LightDarkPreferenceButton.qml index 63dbd2c..fa9d205 100644 --- a/configs/quickshell/ii/modules/common/widgets/LightDarkPreferenceButton.qml +++ b/configs/quickshell/ii/modules/common/widgets/LightDarkPreferenceButton.qml @@ -17,7 +17,7 @@ GroupButton { colBackground: Appearance.colors.colLayer2 toggled: Appearance.m3colors.darkmode === dark onClicked: { - Quickshell.execDetached(["bash", "-c", `${Directories.wallpaperSwitchScriptPath} --mode ${dark ? "dark" : "light"} --noswitch`]) + Quickshell.execDetached(["bash", `${Directories.scriptPath}/colors/switchwall-wrapper.sh`, "--mode", dark ? "dark" : "light", "--noswitch"]) } contentItem: Item { anchors.centerIn: parent diff --git a/configs/quickshell/ii/scripts/colors/generate_colors_material.py b/configs/quickshell/ii/scripts/colors/generate_colors_material.py index db6b166..fbfd4d5 100755 --- a/configs/quickshell/ii/scripts/colors/generate_colors_material.py +++ b/configs/quickshell/ii/scripts/colors/generate_colors_material.py @@ -2,6 +2,7 @@ import argparse import math import json +import os from PIL import Image from materialyoucolor.quantize import QuantizeCelebi from materialyoucolor.score.score import Score @@ -86,6 +87,11 @@ if args.path is not None: elif args.color is not None: argb = hex_to_argb(args.color) hct = Hct.from_int(argb) +elif args.cache is not None and os.path.exists(args.cache): + with open(args.cache, 'r') as file: + cached_color = file.read().strip() + argb = hex_to_argb(cached_color) + hct = Hct.from_int(argb) if args.scheme == 'scheme-fruit-salad': from materialyoucolor.scheme.scheme_fruit_salad import SchemeFruitSalad as Scheme diff --git a/configs/quickshell/ii/scripts/colors/switchwall-wrapper.sh b/configs/quickshell/ii/scripts/colors/switchwall-wrapper.sh new file mode 100755 index 0000000..7459942 --- /dev/null +++ b/configs/quickshell/ii/scripts/colors/switchwall-wrapper.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# Wrapper to set up environment for switchwall.sh + +# Source environment config +[ -f "$HOME/.config/quickshell/env.sh" ] && source "$HOME/.config/quickshell/env.sh" + +export ILLOGICAL_IMPULSE_VIRTUAL_ENV="${ILLOGICAL_IMPULSE_VIRTUAL_ENV:-$HOME/.local/state/quickshell/.venv}" + +echo "[wrapper] Called with args: $@" >> /tmp/switchwall-wrapper.log +echo "[wrapper] LD_LIBRARY_PATH: $LD_LIBRARY_PATH" >> /tmp/switchwall-wrapper.log + +# Run switchwall.sh with all arguments +exec "$(dirname "$0")/switchwall.sh" "$@" diff --git a/configs/quickshell/ii/scripts/colors/switchwall.sh b/configs/quickshell/ii/scripts/colors/switchwall.sh index 31db37b..789cd99 100755 --- a/configs/quickshell/ii/scripts/colors/switchwall.sh +++ b/configs/quickshell/ii/scripts/colors/switchwall.sh @@ -1,5 +1,16 @@ #!/usr/bin/env bash +# Log execution +LOG="/tmp/switchwall.log" +echo "[$(date)] switchwall.sh started" >> "$LOG" +echo "ILLOGICAL_IMPULSE_VIRTUAL_ENV=$ILLOGICAL_IMPULSE_VIRTUAL_ENV" >> "$LOG" + +# Ensure LD_LIBRARY_PATH is set for Python venv +if [ -z "$LD_LIBRARY_PATH" ]; then + export LD_LIBRARY_PATH="/run/current-system/sw/lib" + echo "Set LD_LIBRARY_PATH=$LD_LIBRARY_PATH" >> "$LOG" +fi + QUICKSHELL_CONFIG_NAME="ii" XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}" @@ -84,9 +95,10 @@ check_and_prompt_upscale() { img_height=$(identify -format "%h" "$img" 2>/dev/null) fi if [[ "$img_width" -lt "$min_width_desired" || "$img_height" -lt "$min_height_desired" ]]; then - action=$(notify-send "Upscale?" \ + action=$(timeout 5 notify-send "Upscale?" \ "Image resolution (${img_width}x${img_height}) is lower than screen resolution (${min_width_desired}x${min_height_desired})" \ -A "open_upscayl=Open Upscayl"\ + -t 5000 \ -a "Wallpaper switcher") if [[ "$action" == "open_upscayl" ]]; then if command -v upscayl &>/dev/null; then @@ -187,7 +199,10 @@ switch() { exit 0 fi - check_and_prompt_upscale "$imgpath" & + # Only check upscale if not using --noswitch + if [[ -z "$noswitch_flag" ]]; then + check_and_prompt_upscale "$imgpath" & + fi kill_existing_mpvpaper if is_video "$imgpath"; then @@ -281,11 +296,34 @@ switch() { fi matugen "${matugen_args[@]}" - source "$(eval echo $ILLOGICAL_IMPULSE_VIRTUAL_ENV)/bin/activate" - python3 "$SCRIPT_DIR/generate_colors_material.py" "${generate_colors_material_args[@]}" \ - > "$STATE_DIR"/user/generated/material_colors.scss - "$SCRIPT_DIR"/applycolor.sh - deactivate + echo "[$(date)] Running python script" >> "$LOG" + "$(eval echo $ILLOGICAL_IMPULSE_VIRTUAL_ENV)/bin/python3" "$SCRIPT_DIR/generate_colors_material.py" "${generate_colors_material_args[@]}" \ + > "$STATE_DIR"/user/generated/material_colors.scss 2>> "$LOG" + echo "[$(date)] Python done, scss size: $(wc -l < "$STATE_DIR"/user/generated/material_colors.scss)" >> "$LOG" + + # Only convert to JSON if SCSS was generated successfully + if [ -s "$STATE_DIR"/user/generated/material_colors.scss ]; then + # Convert SCSS to JSON for quickshell MaterialThemeLoader + echo "[$(date)] Converting SCSS to JSON" >> "$LOG" + awk -F': ' '/^\$/ {gsub(/\$|;/, "", $0); print "\"" $1 "\": \"" $2 "\","}' \ + "$STATE_DIR"/user/generated/material_colors.scss | \ + sed '$ s/,$//' | \ + (echo "{"; cat; echo "}") > "$STATE_DIR"/user/generated/colors.json.tmp + mv "$STATE_DIR"/user/generated/colors.json.tmp "$STATE_DIR"/user/generated/colors.json + sync "$STATE_DIR"/user/generated/colors.json + echo "[$(date)] JSON created, size: $(wc -l < "$STATE_DIR"/user/generated/colors.json)" >> "$LOG" + else + echo "[$(date)] SCSS generation failed, skipping JSON creation" >> "$LOG" + fi + + "$XDG_CONFIG_HOME/quickshell/scripts/colors/applycolor.sh" + + # Wait for all file operations to complete + wait + sleep 1 + + # Trigger quickshell to reload theme via IPC (doesn't restart the process) + quickshell ipc -c ii call materialTheme reload 2>/dev/null || true # Pass screen width, height, and wallpaper path to post_process max_width_desired="$(hyprctl monitors -j | jq '([.[].width] | min)' | xargs)" @@ -300,6 +338,7 @@ main() { color_flag="" color="" noswitch_flag="" + choose_flag="" get_type_from_config() { jq -r '.appearance.palette.type' "$SHELL_CONFIG_FILE" 2>/dev/null || echo "auto" @@ -339,6 +378,10 @@ main() { imgpath=$(jq -r '.background.wallpaperPath' "$SHELL_CONFIG_FILE" 2>/dev/null || echo "") shift ;; + --choose) + choose_flag="1" + shift + ;; *) if [[ -z "$imgpath" ]]; then imgpath="$1" @@ -369,8 +412,17 @@ main() { # Only prompt for wallpaper if not using --color and not using --noswitch and no imgpath set if [[ -z "$imgpath" && -z "$color_flag" && -z "$noswitch_flag" ]]; then - cd "$(xdg-user-dir PICTURES)/Wallpapers/showcase" 2>/dev/null || cd "$(xdg-user-dir PICTURES)/Wallpapers" 2>/dev/null || cd "$(xdg-user-dir PICTURES)" || return 1 - imgpath="$(kdialog --getopenfilename . --title 'Choose wallpaper')" + # Try to pick a random wallpaper from Wallpapers directory + WALLPAPER_DIR="$(xdg-user-dir PICTURES)/Wallpapers" + if [[ -d "$WALLPAPER_DIR" ]] && [[ -z "$choose_flag" ]]; then + imgpath=$(find "$WALLPAPER_DIR" -type f \( -name "*.jpg" -o -name "*.png" \) 2>/dev/null | shuf -n 1) + fi + + # If --choose flag is set or still no wallpaper, prompt with kdialog + if [[ -n "$choose_flag" ]] || [[ -z "$imgpath" ]]; then + cd "$(xdg-user-dir PICTURES)/Wallpapers/showcase" 2>/dev/null || cd "$(xdg-user-dir PICTURES)/Wallpapers" 2>/dev/null || cd "$(xdg-user-dir PICTURES)" || return 1 + imgpath="$(kdialog --getopenfilename . --title 'Choose wallpaper')" + fi fi # If type_flag is 'auto', detect scheme type from image (after imgpath is set) diff --git a/configs/quickshell/ii/services/MaterialThemeLoader.qml b/configs/quickshell/ii/services/MaterialThemeLoader.qml index 8872c47..c325d81 100644 --- a/configs/quickshell/ii/services/MaterialThemeLoader.qml +++ b/configs/quickshell/ii/services/MaterialThemeLoader.qml @@ -2,6 +2,7 @@ pragma Singleton pragma ComponentBehavior: Bound import qs.modules.common +import qs.modules.common.functions import QtQuick import Quickshell import Quickshell.Io @@ -14,31 +15,37 @@ Singleton { id: root property string filePath: Directories.generatedMaterialThemePath - function reapplyTheme() { - themeFileView.reload() - } + Component.onCompleted: delayedFileRead.restart() - function applyColors(fileContent) { - const json = JSON.parse(fileContent) - for (const key in json) { - if (json.hasOwnProperty(key)) { - // Convert snake_case to CamelCase - const camelCaseKey = key.replace(/_([a-z])/g, (g) => g[1].toUpperCase()) - const m3Key = `m3${camelCaseKey}` - Appearance.m3colors[m3Key] = json[key] - } - } - - Appearance.m3colors.darkmode = (Appearance.m3colors.m3background.hslLightness < 0.5) + function reapplyTheme() { + delayedFileRead.restart() } Timer { id: delayedFileRead - interval: Config.options?.hacks?.arbitraryRaceConditionDelay ?? 100 + interval: Config.options?.hacks?.arbitraryRaceConditionDelay ?? 300 repeat: false running: false onTriggered: { - root.applyColors(themeFileView.text()) + console.log("MaterialThemeLoader: Timer triggered") + const fileContent = themeFileView.text() + console.log("MaterialThemeLoader: Read", fileContent.length, "bytes") + const json = JSON.parse(fileContent) + let colorCount = 0 + for (const key in json) { + if (json.hasOwnProperty(key)) { + if (key === 'darkmode' || key === 'transparent' || key.includes('paletteKeyColor') || key.startsWith('term')) { + continue + } + const camelCaseKey = key.replace(/_([a-z])/g, (g) => g[1].toUpperCase()) + const m3Key = `m3${camelCaseKey}` + Appearance.m3colors[m3Key] = json[key] + colorCount++ + } + } + console.log("MaterialThemeLoader: Applied", colorCount, "colors") + console.log("MaterialThemeLoader: m3primary =", Appearance.m3colors.m3primary) + Appearance.m3colors.darkmode = (Appearance.m3colors.m3background.hslLightness < 0.5) } } @@ -48,11 +55,8 @@ Singleton { watchChanges: true onFileChanged: { this.reload() - delayedFileRead.start() - } - onLoadedChanged: { - const fileContent = themeFileView.text() - root.applyColors(fileContent) + delayedFileRead.restart() } + onLoadedChanged: if (loaded) delayedFileRead.restart() } } diff --git a/configs/quickshell/scripts/colors/applycolor.sh b/configs/quickshell/scripts/colors/applycolor.sh index ddb93bd..9f920b9 100755 --- a/configs/quickshell/scripts/colors/applycolor.sh +++ b/configs/quickshell/scripts/colors/applycolor.sh @@ -9,7 +9,22 @@ CACHE_DIR="$XDG_CACHE_HOME/quickshell" STATE_DIR="$XDG_STATE_HOME/quickshell" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -term_alpha=100 #Set this to < 100 make all your terminals transparent +term_alpha=60 + +# Check transparency setting and adjust term_alpha accordingly +if [ -f "$STATE_DIR/user/generated/terminal/transparency" ]; then + transparency_mode=$(cat "$STATE_DIR/user/generated/terminal/transparency") + if [ "$transparency_mode" = "opaque" ]; then + term_alpha=100 + else + # For transparent mode, use the opacity setting from config or default to 80 + if [ -f "$STATE_DIR/user/generated/terminal/opacity" ]; then + term_alpha=$(cat "$STATE_DIR/user/generated/terminal/opacity") + else + term_alpha=80 + fi + fi +fi # sleep 0 # idk i wanted some delay or colors dont get applied properly if [ ! -d "$STATE_DIR"/user/generated ]; then mkdir -p "$STATE_DIR"/user/generated @@ -26,6 +41,7 @@ colorstrings=$(cat $STATE_DIR/user/generated/material_colors.scss | cut -d: -f2 IFS=$'\n' colorlist=($colornames) # Array of color names colorvalues=($colorstrings) # Array of color values +export colorlist colorvalues apply_term() { # Check if terminal escape sequence template exists @@ -43,13 +59,13 @@ apply_term() { sed -i "s/\$alpha/$term_alpha/g" "$STATE_DIR/user/generated/terminal/sequences.txt" + # Send escape sequences to all terminals for file in /dev/pts/*; do if [[ $file =~ ^/dev/pts/[0-9]+$ ]]; then - { - cat "$STATE_DIR"/user/generated/terminal/sequences.txt >"$file" - } & disown || true + cat "$STATE_DIR"/user/generated/terminal/sequences.txt >"$file" 2>/dev/null & fi done + wait } apply_qt() { @@ -57,16 +73,172 @@ apply_qt() { python "$CONFIG_DIR/scripts/kvantum/changeAdwColors.py" # apply config colors } +apply_foot() { + # Check if foot template exists + if [ ! -f "$SCRIPT_DIR/foot/foot.ini" ]; then + echo "Template file not found for Foot. Skipping that." + return + fi + + # Copy template + mkdir -p "$STATE_DIR/user/generated/foot" + cp "$SCRIPT_DIR/foot/foot.ini" "$STATE_DIR/user/generated/foot/foot.ini" + + # Apply colors (skip non-color variables like $darkmode, $transparent) + # Sort by variable name length (longest first) to avoid partial replacement issues + # e.g., $term10 must be replaced before $term1 to avoid "AC72FF0" malformed colors + filtered_indices=() + for i in "${!colorlist[@]}"; do + # Skip variables that don't start with color names or contain special values + if [[ "${colorlist[$i]}" == *"darkmode"* ]] || [[ "${colorlist[$i]}" == *"transparent"* ]] || [[ "${colorlist[$i]}" == *"palette"* ]]; then + continue + fi + filtered_indices+=($i) + done + + # Sort indices by variable name length (longest first) + IFS=$'\n' sorted_indices=($(for idx in "${filtered_indices[@]}"; do + echo "${#colorlist[$idx]} $idx" + done | sort -rn | cut -d' ' -f2)) + + for i in "${sorted_indices[@]}"; do + # Escape the $ in the color name for sed + color_name="${colorlist[$i]//$/\\$}" + # Remove # prefix from color value for foot compatibility + color_value="${colorvalues[$i]}" + color_value="${color_value#\#}" # Remove leading # if present + sed -i "s/${color_name}/${color_value}/g" "$STATE_DIR/user/generated/foot/foot.ini" + done + + # After all color replacements, ensure no # prefixes remain in color values + # This handles any edge cases where # prefixes weren't removed properly + sed -i 's/=\s*#\([0-9A-Fa-f]\{6\}\)/=\1/g' "$STATE_DIR/user/generated/foot/foot.ini" + + # Convert term_alpha percentage to decimal for foot (e.g., 70 -> 0.7) + foot_alpha=$(echo "scale=2; $term_alpha / 100" | bc) + # Use line number replacement to avoid sed pattern issues + sed -i "/^alpha=/c\\alpha=$foot_alpha" "$STATE_DIR/user/generated/foot/foot.ini" + + # Copy to actual config location + mkdir -p "$XDG_CONFIG_HOME/foot" + cp "$STATE_DIR/user/generated/foot/foot.ini" "$XDG_CONFIG_HOME/foot/foot.ini" +} + +apply_fuzzel() { + # Check if fuzzel template exists + if [ ! -f "$SCRIPT_DIR/fuzzel/fuzzel.ini" ]; then + echo "Template file not found for Fuzzel. Skipping that." + return + fi + + # Copy template + mkdir -p "$STATE_DIR/user/generated/fuzzel" + cp "$SCRIPT_DIR/fuzzel/fuzzel.ini" "$STATE_DIR/user/generated/fuzzel/fuzzel.ini" + + # Apply colors (skip non-color variables like $darkmode, $transparent) + # Sort by variable name length (longest first) to avoid partial replacement issues + filtered_indices=() + for i in "${!colorlist[@]}"; do + # Skip variables that don't start with color names or contain special values + if [[ "${colorlist[$i]}" == *"darkmode"* ]] || [[ "${colorlist[$i]}" == *"transparent"* ]] || [[ "${colorlist[$i]}" == *"palette"* ]]; then + continue + fi + filtered_indices+=($i) + done + + # Sort indices by variable name length (longest first) + IFS=$'\n' sorted_indices=($(for idx in "${filtered_indices[@]}"; do + echo "${#colorlist[$idx]} $idx" + done | sort -rn | cut -d' ' -f2)) + + for i in "${sorted_indices[@]}"; do + # Escape the $ in the color name for sed + color_name="${colorlist[$i]//$/\\$}" + # Keep # prefix for fuzzel (unlike foot) + color_value="${colorvalues[$i]}" + sed -i "s/${color_name}/${color_value}/g" "$STATE_DIR/user/generated/fuzzel/fuzzel.ini" + done + + # Copy to actual config location + mkdir -p "$XDG_CONFIG_HOME/fuzzel" + cp "$STATE_DIR/user/generated/fuzzel/fuzzel.ini" "$XDG_CONFIG_HOME/fuzzel/fuzzel.ini" +} + +# Function to convert hex color to RGB values +dehex() { + local hex="$1" + # Remove # if present + hex="${hex#\#}" + # Convert to RGB + printf "%d, %d, %d" "0x${hex:0:2}" "0x${hex:2:2}" "0x${hex:4:2}" +} + +apply_wofi() { + # Check if wofi template exists + if [ ! -f "$SCRIPT_DIR/wofi/style.css" ]; then + echo "Template file not found for Wofi colors. Skipping that." + return + fi + + # Copy template + mkdir -p "$XDG_CONFIG_HOME/wofi" + cp "$SCRIPT_DIR/wofi/style.css" "$XDG_CONFIG_HOME/wofi/style_new.css" + chmod +w "$XDG_CONFIG_HOME/wofi/style_new.css" + + # Apply colors (skip non-color variables like $darkmode, $transparent) + # Sort by variable name length (longest first) to avoid partial replacement issues + filtered_indices=() + for i in "${!colorlist[@]}"; do + # Skip variables that don't start with color names or contain special values + if [[ "${colorlist[$i]}" == *"darkmode"* ]] || [[ "${colorlist[$i]}" == *"transparent"* ]] || [[ "${colorlist[$i]}" == *"palette"* ]]; then + continue + fi + filtered_indices+=($i) + done + + # Sort indices by variable name length (longest first) + IFS=$'\n' sorted_indices=($(for idx in "${filtered_indices[@]}"; do + echo "${#colorlist[$idx]} $idx" + done | sort -rn | cut -d' ' -f2)) + + # Apply hex colors (without # prefix) - use {{ $variable }} syntax + for i in "${sorted_indices[@]}"; do + # Remove $ prefix for the template pattern + color_name="${colorlist[$i]#\$}" + # Remove # prefix for wofi + color_value="${colorvalues[$i]}" + color_value="${color_value#\#}" + sed -i "s/{{ \$${color_name} }}/${color_value}/g" "$XDG_CONFIG_HOME/wofi/style_new.css" + done + + # Apply RGB colors - use {{ $variable-rgb }} syntax + for i in "${sorted_indices[@]}"; do + # Remove $ prefix for the template pattern + color_name="${colorlist[$i]#\$}" + # Convert to RGB + dehexed=$(dehex "${colorvalues[$i]}") + sed -i "s/{{ \$${color_name}-rgb }}/${dehexed}/g" "$XDG_CONFIG_HOME/wofi/style_new.css" + done + + mv "$XDG_CONFIG_HOME/wofi/style_new.css" "$XDG_CONFIG_HOME/wofi/style.css" +} + # Check if terminal theming is enabled in config CONFIG_FILE="$XDG_CONFIG_HOME/illogical-impulse/config.json" if [ -f "$CONFIG_FILE" ]; then enable_terminal=$(jq -r '.appearance.wallpaperTheming.enableTerminal' "$CONFIG_FILE") if [ "$enable_terminal" = "true" ]; then - apply_term & + apply_term + apply_foot + apply_fuzzel + apply_wofi fi else echo "Config file not found at $CONFIG_FILE. Applying terminal theming by default." - apply_term & + apply_term + apply_foot + apply_fuzzel + apply_wofi fi # apply_qt & # Qt theming is already handled by kde-material-colors