aboutsummaryrefslogtreecommitdiffstats
path: root/config/hypr/scripts
diff options
context:
space:
mode:
authorPinapelz <yukais@pinapelz.com>2026-07-10 11:21:24 -0700
committerPinapelz <yukais@pinapelz.com>2026-07-10 11:21:24 -0700
commit24de2a31a52d17b6f7214197bdbfeab7428742dd (patch)
treef7736c4712d5a394525a3da2f2b4294e81ba9540 /config/hypr/scripts
parent861bf5be200bfcf2440fec4cda911d29ec18493f (diff)
parentbca86bbec4757cec1f6f5bdea2ed210542f10fae (diff)
Merge remote-tracking branch 'upstream'
Diffstat (limited to 'config/hypr/scripts')
-rwxr-xr-xconfig/hypr/scripts/Add-override-Hyprland-Portal.sh2
-rwxr-xr-xconfig/hypr/scripts/AirplaneMode.sh2
-rwxr-xr-xconfig/hypr/scripts/Animations.sh42
-rwxr-xr-xconfig/hypr/scripts/ApplyThemeMode.sh11
-rwxr-xr-xconfig/hypr/scripts/Brightness.sh2
-rwxr-xr-xconfig/hypr/scripts/BrightnessKbd.sh2
-rwxr-xr-xconfig/hypr/scripts/ChangeBlur.sh2
-rwxr-xr-xconfig/hypr/scripts/ChangeLayout.sh229
-rwxr-xr-xconfig/hypr/scripts/ChangeStarshipPrompt.sh78
-rwxr-xr-xconfig/hypr/scripts/ClipManager.sh2
-rwxr-xr-xconfig/hypr/scripts/DarkLight.sh138
-rwxr-xr-xconfig/hypr/scripts/Distro_update.sh2
-rwxr-xr-xconfig/hypr/scripts/Dropterminal.sh2
-rwxr-xr-xconfig/hypr/scripts/ExternalBrightness.sh2
-rwxr-xr-xconfig/hypr/scripts/Float-all-Windows.sh2
-rwxr-xr-xconfig/hypr/scripts/GameMode.sh6
-rwxr-xr-xconfig/hypr/scripts/Ghostty_themes.sh12
-rwxr-xr-xconfig/hypr/scripts/HyprLayoutModule.sh20
-rwxr-xr-xconfig/hypr/scripts/HyprlockWallpaperSelect.sh358
-rwxr-xr-xconfig/hypr/scripts/JavaManager.sh2
-rwxr-xr-xconfig/hypr/scripts/KeyBinds.sh6
-rwxr-xr-xconfig/hypr/scripts/KeyHints.sh4
-rwxr-xr-xconfig/hypr/scripts/KeybindsLayoutInit.sh14
-rwxr-xr-xconfig/hypr/scripts/KeyboardLayout.sh6
-rwxr-xr-xconfig/hypr/scripts/KillActiveProcess.sh2
-rwxr-xr-xconfig/hypr/scripts/Kitty_themes.sh10
-rwxr-xr-xconfig/hypr/scripts/KooLsDotsUpdate.sh4
-rwxr-xr-xconfig/hypr/scripts/Kool_Quick_Settings.sh109
-rwxr-xr-xconfig/hypr/scripts/LaunchFileManager.sh122
-rwxr-xr-xconfig/hypr/scripts/LaunchTerminal.sh160
-rwxr-xr-xconfig/hypr/scripts/LaunchThunar.sh50
-rwxr-xr-xconfig/hypr/scripts/LayoutKeybindDispatch.sh219
-rwxr-xr-xconfig/hypr/scripts/LockScreen.sh2
-rwxr-xr-xconfig/hypr/scripts/LuaAutoReload.sh17
-rwxr-xr-xconfig/hypr/scripts/MediaCtrl.sh2
-rwxr-xr-xconfig/hypr/scripts/MonitorProfiles.sh20
-rwxr-xr-xconfig/hypr/scripts/OverviewToggle.sh2
-rwxr-xr-xconfig/hypr/scripts/PersistWorkspaceLayout.sh223
-rwxr-xr-xconfig/hypr/scripts/Polkit-Diag.sh2
-rwxr-xr-xconfig/hypr/scripts/PortalHyprland.sh149
-rwxr-xr-xconfig/hypr/scripts/PortalHyprlandUbuntu.sh4
-rwxr-xr-xconfig/hypr/scripts/Refresh.sh4
-rwxr-xr-xconfig/hypr/scripts/RefreshNoWaybar.sh4
-rwxr-xr-xconfig/hypr/scripts/RofiEmoji.sh2
-rwxr-xr-xconfig/hypr/scripts/RofiFocusedWallpaperLink.sh180
-rwxr-xr-xconfig/hypr/scripts/RofiSearch.sh4
-rwxr-xr-xconfig/hypr/scripts/RofiThemeSelector-modified.sh12
-rwxr-xr-xconfig/hypr/scripts/RofiThemeSelector.sh8
-rwxr-xr-xconfig/hypr/scripts/ScreenShot.sh6
-rwxr-xr-xconfig/hypr/scripts/ScrollCycleColumnWidth.sh56
-rwxr-xr-xconfig/hypr/scripts/ScrollMaximizeToggle.sh175
-rwxr-xr-xconfig/hypr/scripts/Sounds.sh2
-rwxr-xr-xconfig/hypr/scripts/Tak0-Autodispatch.sh2
-rwxr-xr-xconfig/hypr/scripts/Tak0-Per-Window-Switch.sh4
-rwxr-xr-xconfig/hypr/scripts/ThemeChanger.sh42
-rwxr-xr-xconfig/hypr/scripts/Toggle-Active-Window-Audio.sh2
-rwxr-xr-xconfig/hypr/scripts/Toggle-weather-waybar-units.sh2
-rwxr-xr-xconfig/hypr/scripts/ToggleWaybarTime.sh101
-rwxr-xr-xconfig/hypr/scripts/TouchPad.sh6
-rwxr-xr-xconfig/hypr/scripts/UserConfigsSwitcher.sh2
-rwxr-xr-xconfig/hypr/scripts/Volume.sh4
-rwxr-xr-xconfig/hypr/scripts/WallpaperAutoChange.sh54
-rwxr-xr-xconfig/hypr/scripts/WallpaperDaemon.sh10
-rwxr-xr-xconfig/hypr/scripts/WallpaperEffects.sh140
-rwxr-xr-xconfig/hypr/scripts/WallpaperRandom.sh50
-rwxr-xr-xconfig/hypr/scripts/WallpaperSelect.sh267
-rwxr-xr-xconfig/hypr/scripts/WallustConfig.sh6
-rwxr-xr-xconfig/hypr/scripts/WallustSwww.sh58
-rwxr-xr-xconfig/hypr/scripts/WaybarLayout.sh8
-rwxr-xr-xconfig/hypr/scripts/WaybarScripts.sh6
-rwxr-xr-xconfig/hypr/scripts/WaybarStyles.sh8
-rwxr-xr-xconfig/hypr/scripts/ZshChangeTheme.sh74
-rwxr-xr-xconfig/hypr/scripts/fastfetch-wrapper.sh2
-rwxr-xr-xconfig/hypr/scripts/kooldots-add-ssh-agent.sh310
-rwxr-xr-xconfig/hypr/scripts/rofi-emacs-keybinds2
-rwxr-xr-xconfig/hypr/scripts/rofi-ssh-menu.sh2
-rwxr-xr-xconfig/hypr/scripts/sddm_wallpaper.sh599
-rwxr-xr-xconfig/hypr/scripts/set-default-thunar-terminal.sh2
-rwxr-xr-xconfig/hypr/scripts/update_WindowRules.sh2
79 files changed, 3855 insertions, 406 deletions
diff --git a/config/hypr/scripts/Add-override-Hyprland-Portal.sh b/config/hypr/scripts/Add-override-Hyprland-Portal.sh
index 1f321d51..b8a10ba4 100755
--- a/config/hypr/scripts/Add-override-Hyprland-Portal.sh
+++ b/config/hypr/scripts/Add-override-Hyprland-Portal.sh
@@ -14,7 +14,7 @@ SCRIPT_NAME="$(basename "$0")"
DRY_RUN=0
ACTION="apply"
-OVERRIDE_DIR="$HOME/.config/systemd/user/xdg-desktop-portal.service.d"
+OVERRIDE_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user/xdg-desktop-portal.service.d"
OVERRIDE_FILE="$OVERRIDE_DIR/override.conf"
PORTAL_UNITS=(
"xdg-desktop-portal.service"
diff --git a/config/hypr/scripts/AirplaneMode.sh b/config/hypr/scripts/AirplaneMode.sh
index 21aa04a8..17a8d9ac 100755
--- a/config/hypr/scripts/AirplaneMode.sh
+++ b/config/hypr/scripts/AirplaneMode.sh
@@ -7,7 +7,7 @@
# ==================================================
# Airplane Mode. Turning on or off all wifi using rfkill.
-notif="$HOME/.config/swaync/images/ja.png"
+notif="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images/ja.png"
# Check if any wireless device is blocked
wifi_blocked=$(rfkill list wifi | grep -o "Soft blocked: yes")
diff --git a/config/hypr/scripts/Animations.sh b/config/hypr/scripts/Animations.sh
index 5fb77750..ae93429b 100755
--- a/config/hypr/scripts/Animations.sh
+++ b/config/hypr/scripts/Animations.sh
@@ -13,22 +13,44 @@ if pidof rofi > /dev/null; then
fi
# Variables
-iDIR="$HOME/.config/swaync/images"
-SCRIPTSDIR="$HOME/.config/hypr/scripts"
-animations_dir="$HOME/.config/hypr/animations"
-UserConfigs="$HOME/.config/hypr/UserConfigs"
-rofi_theme="$HOME/.config/rofi/config-Animations.rasi"
-msg='❗NOTE:❗ This will copy animations into UserAnimations.conf'
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images"
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
+animations_dir="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/animations"
+UserConfigs="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserConfigs"
+rofi_theme="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-Animations.rasi"
+config_home="${XDG_CONFIG_HOME:-$HOME/.config}"
+hypr_dir="$config_home/hypr"
+lua_entry="$hypr_dir/hyprland.lua"
+legacy_lua_entry="$config_home/hyprland.lua"
+
+# Detect active Hyprland config mode (Lua entrypoint vs legacy .conf includes)
+if [[ -f "$lua_entry" || -f "$legacy_lua_entry" ]]; then
+ hypr_config_mode="lua"
+ animation_ext="lua"
+ target_animation_file="$UserConfigs/user_animations.lua"
+ msg='❗NOTE:❗ This will copy animations into user_animations.lua'
+else
+ hypr_config_mode="conf"
+ animation_ext="conf"
+ target_animation_file="$UserConfigs/UserAnimations.conf"
+ msg='❗NOTE:❗ This will copy animations into UserAnimations.conf'
+fi
+
# list of animation files, sorted alphabetically with numbers first
-animations_list=$(find -L "$animations_dir" -maxdepth 1 -type f | sed 's/.*\///' | sed 's/\.conf$//' | sort -V)
+animations_list=$(find -L "$animations_dir" -maxdepth 1 -type f -name "*.${animation_ext}" | sed 's/.*\///' | sed "s/\.${animation_ext}$//" | sort -V)
+
+if [[ -z "$animations_list" ]]; then
+ notify-send -u normal -i "$iDIR/ja.png" "No animation presets found" "Expected *.${animation_ext} in $animations_dir"
+ exit 0
+fi
# Rofi Menu
-chosen_file=$(echo "$animations_list" | rofi -i -dmenu -config $rofi_theme -mesg "$msg")
+chosen_file=$(echo "$animations_list" | rofi -i -dmenu -config "$rofi_theme" -mesg "$msg")
# Check if a file was selected
if [[ -n "$chosen_file" ]]; then
- full_path="$animations_dir/$chosen_file.conf"
- cp "$full_path" "$UserConfigs/UserAnimations.conf"
+ full_path="$animations_dir/$chosen_file.$animation_ext"
+ cp "$full_path" "$target_animation_file"
notify-send -u low -i "$iDIR/ja.png" "$chosen_file" "Hyprland Animation Loaded"
fi
diff --git a/config/hypr/scripts/ApplyThemeMode.sh b/config/hypr/scripts/ApplyThemeMode.sh
new file mode 100755
index 00000000..f0b45aaf
--- /dev/null
+++ b/config/hypr/scripts/ApplyThemeMode.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Re-apply saved Dark/Light mode on startup without toggling.
+
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
+"$SCRIPTSDIR/DarkLight.sh" --apply-current --preserve-wallpaper --no-notify
diff --git a/config/hypr/scripts/Brightness.sh b/config/hypr/scripts/Brightness.sh
index bf0f4bf1..d3f221bf 100755
--- a/config/hypr/scripts/Brightness.sh
+++ b/config/hypr/scripts/Brightness.sh
@@ -7,7 +7,7 @@
# ==================================================
# Script for Monitor backlights (if supported) using brightnessctl
-iDIR="$HOME/.config/swaync/icons"
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/icons"
notification_timeout=1000
step=10 # INCREASE/DECREASE BY THIS VALUE
diff --git a/config/hypr/scripts/BrightnessKbd.sh b/config/hypr/scripts/BrightnessKbd.sh
index 5bd09a78..ae24b2b2 100755
--- a/config/hypr/scripts/BrightnessKbd.sh
+++ b/config/hypr/scripts/BrightnessKbd.sh
@@ -7,7 +7,7 @@
# ==================================================
# Script for keyboard backlights (if supported) using brightnessctl
-iDIR="$HOME/.config/swaync/icons"
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/icons"
# Get keyboard brightness
get_kbd_backlight() {
diff --git a/config/hypr/scripts/ChangeBlur.sh b/config/hypr/scripts/ChangeBlur.sh
index 10b5914e..ca1be5ad 100755
--- a/config/hypr/scripts/ChangeBlur.sh
+++ b/config/hypr/scripts/ChangeBlur.sh
@@ -7,7 +7,7 @@
# ==================================================
# Script for changing blurs on the fly
-notif="$HOME/.config/swaync/images"
+notif="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images"
STATE=$(hyprctl -j getoption decoration:blur:passes | jq ".int")
diff --git a/config/hypr/scripts/ChangeLayout.sh b/config/hypr/scripts/ChangeLayout.sh
index 3c81bcbe..4e241e85 100755
--- a/config/hypr/scripts/ChangeLayout.sh
+++ b/config/hypr/scripts/ChangeLayout.sh
@@ -5,36 +5,168 @@
# License: GNU GPLv3
# SPDX-License-Identifier: GPL-3.0-or-later
# ==================================================
-# for changing Hyprland Layouts (master, dwindle, scrolling, monocle) on the fly
-
-notif="$HOME/.config/swaync/images/ja.png"
+# Switch Hyprland layouts per active monitor/workspace.
+# This avoids global layout mutations and keeps workspace-specific rules intact.
+notif="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images/ja.png"
+persist_layout_script="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/PersistWorkspaceLayout.sh"
layouts=(master dwindle scrolling monocle)
quiet_mode=0
+normalize_layout() {
+ case "$1" in
+ master | dwindle | scrolling | monocle)
+ printf '%s\n' "$1"
+ ;;
+ *)
+ printf '\n'
+ ;;
+ esac
+}
+
+wait_for_layout() {
+ local target="$1"
+ local actual=""
+ local attempt
+
+ for attempt in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
+ actual="$(get_layout)"
+ if [[ "$actual" == "$target" ]]; then
+ printf '%s\n' "$actual"
+ return 0
+ fi
+ sleep 0.03
+ done
+
+ printf '%s\n' "$actual"
+ return 1
+}
+
+persist_current_workspace_layout() {
+ local target_layout="$1"
+
+ if [[ ! -x "$persist_layout_script" ]]; then
+ return 0
+ fi
+
+ "$persist_layout_script" --quiet --layout "$target_layout" >/dev/null 2>&1 || true
+}
+
+get_active_workspace_json() {
+ hyprctl -j activeworkspace 2>/dev/null || printf '{}'
+}
+
get_layout() {
- hyprctl -j getoption general:layout | jq -r '.str'
+ local ws_json layout
+
+ ws_json="$(get_active_workspace_json)"
+ layout="$(jq -r '.tiledLayout // .tiled_layout // .layout // empty' <<<"$ws_json" 2>/dev/null || true)"
+ layout="$(normalize_layout "$layout")"
+
+ if [[ -z "$layout" ]]; then
+ layout="$(hyprctl -j getoption general:layout 2>/dev/null | jq -r '.str // empty' 2>/dev/null || true)"
+ layout="$(normalize_layout "$layout")"
+ fi
+
+ if [[ -z "$layout" ]]; then
+ layout="dwindle"
+ fi
+
+ printf '%s\n' "$layout"
}
-set_hypr_layout() {
+get_workspace_selector() {
+ local ws_json="$1"
+ local ws_id ws_name
+
+ ws_id="$(jq -r '.id // empty' <<<"$ws_json" 2>/dev/null || true)"
+ ws_name="$(jq -r '.name // empty' <<<"$ws_json" 2>/dev/null || true)"
+
+ if [[ "$ws_id" =~ ^[0-9]+$ ]] && ((ws_id > 0)); then
+ printf '%s\n' "$ws_id"
+ return 0
+ fi
+
+ if [[ -n "$ws_name" && "$ws_name" != "null" ]]; then
+ if [[ "$ws_name" == name:* || "$ws_name" == special:* ]]; then
+ printf '%s\n' "$ws_name"
+ else
+ printf 'name:%s\n' "$ws_name"
+ fi
+ return 0
+ fi
+
+ return 1
+}
+
+get_workspace_label() {
+ local ws_json="$1"
+ local ws_name ws_id
+
+ ws_name="$(jq -r '.name // empty' <<<"$ws_json" 2>/dev/null || true)"
+ ws_id="$(jq -r '.id // empty' <<<"$ws_json" 2>/dev/null || true)"
+
+ if [[ -n "$ws_name" && "$ws_name" != "null" ]]; then
+ printf '%s\n' "$ws_name"
+ return
+ fi
+
+ if [[ -n "$ws_id" && "$ws_id" != "null" ]]; then
+ printf '%s\n' "$ws_id"
+ return
+ fi
+
+ printf 'current\n'
+}
+
+get_monitor_name() {
+ local ws_json="$1"
+ jq -r '.monitor // empty' <<<"$ws_json" 2>/dev/null || true
+}
+
+escape_lua_string() {
+ local value="$1"
+ value="${value//\\/\\\\}"
+ value="${value//\"/\\\"}"
+ printf '%s' "$value"
+}
+
+is_ok_output() {
+ local output="$1"
+ local normalized
+
+ normalized="$(printf '%s\n' "$output" | tr -d '\r' | sed '/^[[:space:]]*$/d')"
+ [[ -z "$normalized" || "$normalized" == "ok" ]]
+}
+
+set_workspace_layout_rule() {
local target="$1"
- local output
+ local ws_json workspace_selector monitor_name output
+ local ws_escaped monitor_escaped target_escaped
+
+ ws_json="$(get_active_workspace_json)"
+ workspace_selector="$(get_workspace_selector "$ws_json" || true)"
+ monitor_name="$(get_monitor_name "$ws_json")"
- output="$(hyprctl keyword general:layout "$target" 2>&1)"
+ if [[ -z "$workspace_selector" || -z "$monitor_name" ]]; then
+ echo "Unable to resolve active workspace context" >&2
+ return 1
+ fi
+
+ output="$(hyprctl keyword workspace "${workspace_selector}, monitor:${monitor_name}, layout:${target}" 2>&1 || true)"
if grep -q "keyword can't work with non-legacy parsers" <<<"$output"; then
- output="$(hyprctl eval "hl.config({ general = { layout = \"${target}\" } })" 2>&1)"
+ ws_escaped="$(escape_lua_string "$workspace_selector")"
+ monitor_escaped="$(escape_lua_string "$monitor_name")"
+ target_escaped="$(escape_lua_string "$target")"
+ output="$(hyprctl eval "hl.workspace_rule({ workspace = \"${ws_escaped}\", monitor = \"${monitor_escaped}\", layout = \"${target_escaped}\" })" 2>&1 || true)"
fi
- if ! grep -q "^ok$" <<<"$output"; then
+ if ! is_ok_output "$output"; then
echo "$output" >&2
return 1
fi
}
-hypr_keyword() {
- hyprctl keyword "$@" >/dev/null 2>&1 || true
-}
-
next_layout() {
local current="$1"
local i
@@ -49,65 +181,24 @@ next_layout() {
set_layout() {
local target="$1"
+ local ws_json workspace_label monitor_name actual
- if ! set_hypr_layout "$target"; then
+ ws_json="$(get_active_workspace_json)"
+ workspace_label="$(get_workspace_label "$ws_json")"
+ monitor_name="$(get_monitor_name "$ws_json")"
+
+ if ! set_workspace_layout_rule "$target"; then
if [[ "$quiet_mode" -eq 0 ]]; then
notify-send -e -u critical -i "$notif" " Layout switch failed: $target"
fi
return 1
fi
- hypr_keyword unbind SUPER,j
- hypr_keyword unbind SUPER,k
- hypr_keyword bind SUPER,j,cyclenext
- hypr_keyword bind SUPER,k,cyclenext,prev
- hypr_keyword unbind SUPER,left
- hypr_keyword unbind SUPER,right
- hypr_keyword unbind SUPER,up
- hypr_keyword unbind SUPER,down
- hypr_keyword unbind SUPER,O
-
- case "$target" in
- "dwindle")
- hypr_keyword bind SUPER,left,cyclenext,prev
- hypr_keyword bind SUPER,up,cyclenext,prev
- hypr_keyword bind SUPER,right,cyclenext
- hypr_keyword bind SUPER,down,cyclenext
- hypr_keyword bind SUPER,O,layoutmsg,togglesplit
- ;;
- "scrolling")
- hypr_keyword bind SUPER,left,cyclenext,prev
- hypr_keyword bind SUPER,up,cyclenext,prev
- hypr_keyword bind SUPER,right,cyclenext
- hypr_keyword bind SUPER,down,cyclenext
- ;;
- "monocle")
- hypr_keyword bind SUPER,left,layoutmsg,cycleprev
- hypr_keyword bind SUPER,up,layoutmsg,cycleprev
- hypr_keyword bind SUPER,right,layoutmsg,cyclenext
- hypr_keyword bind SUPER,down,layoutmsg,cyclenext
- ;;
- "master")
- hypr_keyword bind SUPER,left,movefocus,l
- hypr_keyword bind SUPER,right,movefocus,r
- hypr_keyword bind SUPER,up,movefocus,u
- hypr_keyword bind SUPER,down,movefocus,d
- ;;
- *)
- hypr_keyword bind SUPER,left,movefocus,l
- hypr_keyword bind SUPER,right,movefocus,r
- hypr_keyword bind SUPER,up,movefocus,u
- hypr_keyword bind SUPER,down,movefocus,d
- echo "Unknown layout: $target" >&2
- return 1
- ;;
- esac
-
- local actual
- actual="$(get_layout)"
+ actual="$(wait_for_layout "$target")"
if [[ "$actual" == "$target" ]]; then
+ persist_current_workspace_layout "$target"
if [[ "$quiet_mode" -eq 0 ]]; then
- notify-send -e -u low -i "$notif" " ${actual^} Layout"
+ notify-send -e -u low -i "$notif" " ${actual^} Layout · WS ${workspace_label}${monitor_name:+ @ ${monitor_name}}"
fi
else
if [[ "$quiet_mode" -eq 0 ]]; then
@@ -127,16 +218,20 @@ arg="${1:-toggle}"
case "$arg" in
init)
- set_layout "$current"
+ # No startup keybind rebinding required anymore.
+ exit 0
+ ;;
+current | status | get)
+ printf '%s\n' "$current"
;;
-toggle|next)
+toggle | next)
set_layout "$(next_layout "$current")"
;;
-master|dwindle|scrolling|monocle)
+master | dwindle | scrolling | monocle)
set_layout "$arg"
;;
*)
- echo "Usage: $(basename "$0") [--quiet|--no-notify] [toggle|next|init|master|dwindle|scrolling|monocle]" >&2
+ echo "Usage: $(basename "$0") [--quiet|--no-notify] [toggle|next|init|current|master|dwindle|scrolling|monocle]" >&2
exit 1
;;
esac
diff --git a/config/hypr/scripts/ChangeStarshipPrompt.sh b/config/hypr/scripts/ChangeStarshipPrompt.sh
new file mode 100755
index 00000000..44e50936
--- /dev/null
+++ b/config/hypr/scripts/ChangeStarshipPrompt.sh
@@ -0,0 +1,78 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Switch Starship prompt configs via Rofi.
+
+CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
+STARSHIP_DIR="$CONFIG_HOME/starship"
+HYPR_STARSHIP_DIR="$CONFIG_HOME/hypr/starship"
+STARSHIP_CONFIG="$CONFIG_HOME/starship.toml"
+BACKUP_FILE="$STARSHIP_CONFIG.original"
+ROFI_THEME="$CONFIG_HOME/rofi/config-starship.rasi"
+RESTORE_LABEL="Retore orignal prompt"
+
+if ! command -v starship >/dev/null 2>&1; then
+ echo "starship is not installed"
+ exit 1
+fi
+
+if [[ ! -f "$ROFI_THEME" ]]; then
+ echo "Rofi theme not found: $ROFI_THEME"
+ exit 1
+fi
+
+if [[ ! -d "$STARSHIP_DIR" ]]; then
+ echo "Starship config directory not found: $STARSHIP_DIR"
+ exit 1
+fi
+
+mapfile -t available_prompts < <(find "$STARSHIP_DIR" -maxdepth 1 -type f -name "*.toml" -printf "%f\n" 2>/dev/null | sort -V)
+
+if [[ ${#available_prompts[@]} -eq 0 ]]; then
+ echo "No Starship prompt files found in $STARSHIP_DIR"
+ exit 1
+fi
+
+rofi_options=("${available_prompts[@]}")
+if [[ -f "$BACKUP_FILE" ]]; then
+ rofi_options+=("$RESTORE_LABEL")
+fi
+
+selection="$(printf '%s\n' "${rofi_options[@]}" | rofi -dmenu -i -p "Select Starship Prompt" -mesg "Select Starship Prompt" -theme "$ROFI_THEME")"
+
+if [[ -z "$selection" ]]; then
+ exit 0
+fi
+
+if [[ "$selection" == "$RESTORE_LABEL" ]]; then
+ if [[ -f "$BACKUP_FILE" ]]; then
+ if [[ -L "$STARSHIP_CONFIG" ]]; then
+ rm -f "$STARSHIP_CONFIG"
+ fi
+ cp -f "$BACKUP_FILE" "$STARSHIP_CONFIG"
+ else
+ echo "Backup not found: $BACKUP_FILE"
+ fi
+ exit 0
+fi
+
+selected_path="$STARSHIP_DIR/$selection"
+if [[ ! -f "$selected_path" && -f "$HYPR_STARSHIP_DIR/$selection" ]]; then
+ selected_path="$HYPR_STARSHIP_DIR/$selection"
+fi
+
+if [[ ! -f "$selected_path" ]]; then
+ echo "Selected prompt not found: $selection"
+ exit 1
+fi
+
+if [[ -f "$STARSHIP_CONFIG" && ! -L "$STARSHIP_CONFIG" ]]; then
+ cp -f "$STARSHIP_CONFIG" "$BACKUP_FILE"
+ rm -f "$STARSHIP_CONFIG"
+fi
+
+ln -sfn "$selected_path" "$STARSHIP_CONFIG"
diff --git a/config/hypr/scripts/ClipManager.sh b/config/hypr/scripts/ClipManager.sh
index e3fbd066..19e15fd6 100755
--- a/config/hypr/scripts/ClipManager.sh
+++ b/config/hypr/scripts/ClipManager.sh
@@ -8,7 +8,7 @@
# Clipboard Manager. This script uses cliphist, rofi, and wl-copy.
# Variables
-rofi_theme="$HOME/.config/rofi/config-clipboard.rasi"
+rofi_theme="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-clipboard.rasi"
msg='👀 **note** CTRL DEL = cliphist del (entry) or ALT DEL - cliphist wipe (all)'
# Actions:
# CTRL Del to delete an entry
diff --git a/config/hypr/scripts/DarkLight.sh b/config/hypr/scripts/DarkLight.sh
index 5b1cc3e7..16f1a4ef 100755
--- a/config/hypr/scripts/DarkLight.sh
+++ b/config/hypr/scripts/DarkLight.sh
@@ -13,24 +13,79 @@ PICTURES_DIR="$(xdg-user-dir PICTURES 2>/dev/null || echo "$HOME/Pictures")"
wallpaper_base_path="$PICTURES_DIR/wallpapers/Dynamic-Wallpapers"
dark_wallpapers="$wallpaper_base_path/Dark"
light_wallpapers="$wallpaper_base_path/Light"
-hypr_config_path="$HOME/.config/hypr"
-swaync_style="$HOME/.config/swaync/style.css"
-ags_style="$HOME/.config/ags/user/style.css"
-SCRIPTSDIR="$HOME/.config/hypr/scripts"
+hypr_config_path="${XDG_CONFIG_HOME:-$HOME/.config}/hypr"
+swaync_style="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/style.css"
+ags_style="${XDG_CONFIG_HOME:-$HOME/.config}/ags/user/style.css"
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
# shellcheck source=/dev/null
. "$SCRIPTSDIR/WallpaperCmd.sh"
-notif="$HOME/.config/swaync/images/bell.png"
-wallust_rofi="$HOME/.config/wallust/templates/colors-rofi.rasi"
+notif="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images/bell.png"
+wallust_rofi="${XDG_CONFIG_HOME:-$HOME/.config}/wallust/templates/colors-rofi.rasi"
+theme_state_dir="${XDG_STATE_HOME:-$HOME/.local/state}/hypr"
+theme_state_file="$theme_state_dir/theme_mode"
+legacy_theme_state_file="$HOME/.cache/.theme_mode"
-kitty_conf="$HOME/.config/kitty/kitty.conf"
+kitty_conf="${XDG_CONFIG_HOME:-$HOME/.config}/kitty/kitty.conf"
-wallust_config="$HOME/.config/wallust/wallust.toml"
+wallust_config="${XDG_CONFIG_HOME:-$HOME/.config}/wallust/wallust.toml"
pallete_dark="dark16"
pallete_light="light16"
-qt5ct_dark="$HOME/.config/qt5ct/colors/Catppuccin-Mocha.conf"
-qt5ct_light="$HOME/.config/qt5ct/colors/Catppuccin-Latte.conf"
-qt6ct_dark="$HOME/.config/qt6ct/colors/Catppuccin-Mocha.conf"
-qt6ct_light="$HOME/.config/qt6ct/colors/Catppuccin-Latte.conf"
+qt5ct_dark="${XDG_CONFIG_HOME:-$HOME/.config}/qt5ct/colors/Catppuccin-Mocha.conf"
+qt5ct_light="${XDG_CONFIG_HOME:-$HOME/.config}/qt5ct/colors/Catppuccin-Latte.conf"
+qt6ct_dark="${XDG_CONFIG_HOME:-$HOME/.config}/qt6ct/colors/Catppuccin-Mocha.conf"
+qt6ct_light="${XDG_CONFIG_HOME:-$HOME/.config}/qt6ct/colors/Catppuccin-Latte.conf"
+apply_saved_mode=0
+notify_enabled=1
+preserve_wallpaper=0
+forced_mode=""
+
+normalize_mode() {
+ case "$1" in
+ Dark|Light) printf '%s' "$1" ;;
+ *) printf '' ;;
+ esac
+}
+
+read_saved_mode() {
+ local mode=""
+ if [ -f "$theme_state_file" ]; then
+ mode="$(normalize_mode "$(tr -d '\r\n' < "$theme_state_file")")"
+ fi
+ if [ -z "$mode" ] && [ -f "$legacy_theme_state_file" ]; then
+ mode="$(normalize_mode "$(tr -d '\r\n' < "$legacy_theme_state_file")")"
+ fi
+ [ -n "$mode" ] && printf '%s' "$mode" || printf 'Dark'
+}
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --apply-current)
+ apply_saved_mode=1
+ ;;
+ --mode)
+ shift
+ forced_mode="$(normalize_mode "${1:-}")"
+ ;;
+ --no-notify)
+ notify_enabled=0
+ ;;
+ --preserve-wallpaper)
+ preserve_wallpaper=1
+ ;;
+ --help)
+ cat <<'EOF'
+Usage: DarkLight.sh [--apply-current] [--mode Dark|Light] [--no-notify] [--preserve-wallpaper]
+ (no args) Toggle between Dark and Light and persist selection
+ --apply-current Re-apply saved mode (defaults to Dark when unset)
+ --mode <mode> Force target mode to Dark or Light
+ --no-notify Suppress notifications
+ --preserve-wallpaper Keep current wallpaper instead of choosing random Dynamic-Wallpapers image
+EOF
+ exit 0
+ ;;
+ esac
+ shift
+done
# intial kill process
for pid in waybar rofi swaync ags swaybg; do
@@ -45,28 +100,33 @@ done
swww="$WWW_CMD img"
effect="--transition-bezier .43,1.19,1,.4 --transition-fps 60 --transition-type grow --transition-pos 0.925,0.977 --transition-duration 2"
-# Determine current theme mode
-if [ "$(cat $HOME/.cache/.theme_mode)" = "Light" ]; then
+# Determine target theme mode
+saved_mode="$(read_saved_mode)"
+if [ -n "$forced_mode" ]; then
+ next_mode="$forced_mode"
+elif [ "$apply_saved_mode" -eq 1 ]; then
+ next_mode="$saved_mode"
+elif [ "$saved_mode" = "Light" ]; then
next_mode="Dark"
- # Logic for Dark mode
- wallpaper_path="$dark_wallpapers"
else
next_mode="Light"
- # Logic for Light mode
- wallpaper_path="$light_wallpapers"
fi
# Select Qt color scheme templates for the upcoming mode
if [ "$next_mode" = "Dark" ]; then
+ wallpaper_path="$dark_wallpapers"
qt5ct_color_scheme="$qt5ct_dark"
qt6ct_color_scheme="$qt6ct_dark"
else
+ wallpaper_path="$light_wallpapers"
qt5ct_color_scheme="$qt5ct_light"
qt6ct_color_scheme="$qt6ct_light"
fi
# Function to update theme mode for the next cycle
update_theme_mode() {
- echo "$next_mode" > "$HOME/.cache/.theme_mode"
+ mkdir -p "$theme_state_dir" "$HOME/.cache"
+ echo "$next_mode" > "$theme_state_file"
+ echo "$next_mode" > "$legacy_theme_state_file"
}
# Function to notify user
@@ -84,8 +144,8 @@ fi
# Function to set Waybar style
set_waybar_style() {
theme="$1"
- waybar_styles="$HOME/.config/waybar/style"
- waybar_style_link="$HOME/.config/waybar/style.css"
+ waybar_styles="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/style"
+ waybar_style_link="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/style.css"
style_prefix="\\[${theme}\\].*\\.css$"
style_file=$(find -L "$waybar_styles" -maxdepth 1 -type f -regex ".*$style_prefix" | shuf -n 1)
@@ -99,7 +159,7 @@ set_waybar_style() {
# Call the function after determining the mode
set_waybar_style "$next_mode"
-notify_user "$next_mode"
+[ "$notify_enabled" -eq 1 ] && notify_user "$next_mode"
# swaync color change
@@ -140,29 +200,31 @@ for pid_kitty in $(pidof kitty); do
done
# Set Dynamic Wallpaper for Dark or Light Mode
-if [ "$next_mode" = "Dark" ]; then
- next_wallpaper="$(find -L "${dark_wallpapers}" -type f \( -iname "*.jpg" -o -iname "*.png" \) -print0 | shuf -n1 -z | xargs -0)"
-else
- next_wallpaper="$(find -L "${light_wallpapers}" -type f \( -iname "*.jpg" -o -iname "*.png" \) -print0 | shuf -n1 -z | xargs -0)"
-fi
+if [ "$preserve_wallpaper" -eq 0 ]; then
+ if [ "$next_mode" = "Dark" ]; then
+ next_wallpaper="$(find -L "${dark_wallpapers}" -type f \( -iname "*.jpg" -o -iname "*.png" \) -print0 | shuf -n1 -z | xargs -0)"
+ else
+ next_wallpaper="$(find -L "${light_wallpapers}" -type f \( -iname "*.jpg" -o -iname "*.png" \) -print0 | shuf -n1 -z | xargs -0)"
+ fi
-# Update wallpaper using swww command
-$swww "${next_wallpaper}" $effect
+ # Update wallpaper using swww command
+ $swww "${next_wallpaper}" $effect
+fi
# Set Kvantum Manager theme & QT5/QT6 settings
if [ "$next_mode" = "Dark" ]; then
kvantum_theme="catppuccin-mocha-blue"
- #qt5ct_color_scheme="$HOME/.config/qt5ct/colors/Catppuccin-Mocha.conf"
- #qt6ct_color_scheme="$HOME/.config/qt6ct/colors/Catppuccin-Mocha.conf"
+ #qt5ct_color_scheme="${XDG_CONFIG_HOME:-$HOME/.config}/qt5ct/colors/Catppuccin-Mocha.conf"
+ #qt6ct_color_scheme="${XDG_CONFIG_HOME:-$HOME/.config}/qt6ct/colors/Catppuccin-Mocha.conf"
else
kvantum_theme="catppuccin-latte-blue"
- #qt5ct_color_scheme="$HOME/.config/qt5ct/colors/Catppuccin-Latte.conf"
- #qt6ct_color_scheme="$HOME/.config/qt6ct/colors/Catppuccin-Latte.conf"
+ #qt5ct_color_scheme="${XDG_CONFIG_HOME:-$HOME/.config}/qt5ct/colors/Catppuccin-Latte.conf"
+ #qt6ct_color_scheme="${XDG_CONFIG_HOME:-$HOME/.config}/qt6ct/colors/Catppuccin-Latte.conf"
fi
-sed -i "s|^color_scheme_path=.*$|color_scheme_path=$qt5ct_color_scheme|" "$HOME/.config/qt5ct/qt5ct.conf"
-sed -i "s|^color_scheme_path=.*$|color_scheme_path=$qt6ct_color_scheme|" "$HOME/.config/qt6ct/qt6ct.conf"
+sed -i "s|^color_scheme_path=.*$|color_scheme_path=$qt5ct_color_scheme|" "${XDG_CONFIG_HOME:-$HOME/.config}/qt5ct/qt5ct.conf"
+sed -i "s|^color_scheme_path=.*$|color_scheme_path=$qt6ct_color_scheme|" "${XDG_CONFIG_HOME:-$HOME/.config}/qt6ct/qt6ct.conf"
kvantummanager --set "$kvantum_theme"
@@ -234,8 +296,8 @@ set_custom_gtk_theme() {
gsettings set $icon_setting "$selected_icon"
## QT5ct icon_theme
- sed -i "s|^icon_theme=.*$|icon_theme=$selected_icon|" "$HOME/.config/qt5ct/qt5ct.conf"
- sed -i "s|^icon_theme=.*$|icon_theme=$selected_icon|" "$HOME/.config/qt6ct/qt6ct.conf"
+ sed -i "s|^icon_theme=.*$|icon_theme=$selected_icon|" "${XDG_CONFIG_HOME:-$HOME/.config}/qt5ct/qt5ct.conf"
+ sed -i "s|^icon_theme=.*$|icon_theme=$selected_icon|" "${XDG_CONFIG_HOME:-$HOME/.config}/qt6ct/qt6ct.conf"
# Flatpak GTK apps (icons)
if command -v flatpak &> /dev/null; then
@@ -268,7 +330,7 @@ ${SCRIPTSDIR}/Refresh.sh
sleep 0.5
# Display notifications for theme and icon changes
-notify-send -u low -i "$notif" " Themes switched to:" " $next_mode Mode"
+[ "$notify_enabled" -eq 1 ] && notify-send -u low -i "$notif" " Themes switched to:" " $next_mode Mode"
exit 0
diff --git a/config/hypr/scripts/Distro_update.sh b/config/hypr/scripts/Distro_update.sh
index b9bcae71..20a710ee 100755
--- a/config/hypr/scripts/Distro_update.sh
+++ b/config/hypr/scripts/Distro_update.sh
@@ -8,7 +8,7 @@
# Simple bash script to check and will try to update your system
# Local Paths
-iDIR="$HOME/.config/swaync/images"
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images"
# Check for required tools (kitty)
if ! command -v kitty &> /dev/null; then
diff --git a/config/hypr/scripts/Dropterminal.sh b/config/hypr/scripts/Dropterminal.sh
index 21349d4a..8c301f68 100755
--- a/config/hypr/scripts/Dropterminal.sh
+++ b/config/hypr/scripts/Dropterminal.sh
@@ -24,7 +24,7 @@ LOCK_FILE="/tmp/dropdown_terminal_lock"
LAST_TOGGLE_FILE="/tmp/dropdown_terminal_last_toggle"
MIN_TOGGLE_INTERVAL_MS=250
DROPDOWN_KITTY_CLASS="kitty-dropterm"
-CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
+CONFIG_HOME="${XDG_CONFIG_HOME:-${XDG_CONFIG_HOME:-$HOME/.config}}"
HYPR_DIR="$CONFIG_HOME/hypr"
LUA_ENTRY="$HYPR_DIR/hyprland.lua"
LEGACY_LUA_ENTRY="$CONFIG_HOME/hyprland.lua"
diff --git a/config/hypr/scripts/ExternalBrightness.sh b/config/hypr/scripts/ExternalBrightness.sh
index 59081e1d..f3bf2487 100755
--- a/config/hypr/scripts/ExternalBrightness.sh
+++ b/config/hypr/scripts/ExternalBrightness.sh
@@ -18,7 +18,7 @@ cache_file="/tmp/external_brightness_displays.cache"
cache_ttl=300 # 5 minutes
# Detect active Hyprland config mode (Lua entrypoint vs legacy .conf includes)
-config_home="${XDG_CONFIG_HOME:-$HOME/.config}"
+config_home="${XDG_CONFIG_HOME:-${XDG_CONFIG_HOME:-$HOME/.config}}"
hypr_dir="$config_home/hypr"
lua_entry="$hypr_dir/hyprland.lua"
legacy_lua_entry="$config_home/hyprland.lua"
diff --git a/config/hypr/scripts/Float-all-Windows.sh b/config/hypr/scripts/Float-all-Windows.sh
index 25fdc465..1f754ec5 100755
--- a/config/hypr/scripts/Float-all-Windows.sh
+++ b/config/hypr/scripts/Float-all-Windows.sh
@@ -7,7 +7,7 @@
# ==================================================
# Detect active Hyprland config mode (Lua entrypoint vs legacy .conf includes)
-config_home="${XDG_CONFIG_HOME:-$HOME/.config}"
+config_home="${XDG_CONFIG_HOME:-${XDG_CONFIG_HOME:-$HOME/.config}}"
hypr_dir="$config_home/hypr"
lua_entry="$hypr_dir/hyprland.lua"
legacy_lua_entry="$config_home/hyprland.lua"
diff --git a/config/hypr/scripts/GameMode.sh b/config/hypr/scripts/GameMode.sh
index b104179e..c3a02948 100755
--- a/config/hypr/scripts/GameMode.sh
+++ b/config/hypr/scripts/GameMode.sh
@@ -7,13 +7,13 @@
# ==================================================
# Game Mode. Turning off all animations
-notif="$HOME/.config/swaync/images/ja.png"
-SCRIPTSDIR="$HOME/.config/hypr/scripts"
+notif="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images/ja.png"
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
# shellcheck source=/dev/null
. "$SCRIPTSDIR/WallpaperCmd.sh"
# Detect active Hyprland config mode (Lua entrypoint vs legacy .conf includes)
-config_home="${XDG_CONFIG_HOME:-$HOME/.config}"
+config_home="${XDG_CONFIG_HOME:-${XDG_CONFIG_HOME:-$HOME/.config}}"
hypr_dir="$config_home/hypr"
lua_entry="$hypr_dir/hyprland.lua"
legacy_lua_entry="$config_home/hyprland.lua"
diff --git a/config/hypr/scripts/Ghostty_themes.sh b/config/hypr/scripts/Ghostty_themes.sh
index c3fcd792..7eef6c1c 100755
--- a/config/hypr/scripts/Ghostty_themes.sh
+++ b/config/hypr/scripts/Ghostty_themes.sh
@@ -7,14 +7,14 @@
# ==================================================
# Ghostty theme selector
-config_file="$HOME/.config/ghostty/config"
-iDIR="$HOME/.config/swaync/images"
-rofi_theme_primary="$HOME/.config/rofi/config-ghostty-theme.rasi"
-rofi_theme_fallback="$HOME/.config/rofi/config-edit.rasi"
-wallust_include_path="$HOME/.config/ghostty/wallust.conf"
+config_file="${XDG_CONFIG_HOME:-$HOME/.config}/ghostty/config"
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images"
+rofi_theme_primary="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-ghostty-theme.rasi"
+rofi_theme_fallback="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-edit.rasi"
+wallust_include_path="${XDG_CONFIG_HOME:-$HOME/.config}/ghostty/wallust.conf"
wallust_option_label="Set by wallpaper"
default_option_label="Default - no color"
-wallust_refresh_script="$HOME/.config/hypr/scripts/WallustSwww.sh"
+wallust_refresh_script="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/WallustSwww.sh"
notify_user() {
local icon="$1"
diff --git a/config/hypr/scripts/HyprLayoutModule.sh b/config/hypr/scripts/HyprLayoutModule.sh
index 22f12920..14e3b524 100755
--- a/config/hypr/scripts/HyprLayoutModule.sh
+++ b/config/hypr/scripts/HyprLayoutModule.sh
@@ -9,8 +9,8 @@
IFS=$'\n\t'
-SCRIPTSDIR="$HOME/.config/hypr/scripts"
-rofi_config="$HOME/.config/rofi/config-waybar-layout.rasi"
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
+rofi_config="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-layout.rasi"
change_layout="${SCRIPTSDIR}/ChangeLayout.sh"
layouts=(dwindle scrolling monocle master)
@@ -35,7 +35,17 @@ layout_name() {
}
get_layout() {
- hyprctl -j getoption general:layout 2>/dev/null | jq -r '.str // "unknown"' 2>/dev/null
+ local layout
+
+ if [[ -x "$change_layout" ]]; then
+ layout="$("$change_layout" --quiet current 2>/dev/null || true)"
+ if [[ -n "$layout" ]]; then
+ printf '%s\n' "$layout"
+ return
+ fi
+ fi
+
+ hyprctl -j activeworkspace 2>/dev/null | jq -r '.tiledLayout // .tiled_layout // "unknown"' 2>/dev/null
}
next_layout() {
@@ -68,7 +78,7 @@ show_status() {
current="$(get_layout)"
icon="$(layout_icon "$current")"
name="$(layout_name "$current")"
- tooltip="Hyprland layout: ${name} (${icon})\n\nLeft click: Select layout\nRight click: Cycle layout\n\nOptions:\n🄳 Dwindle\n🅂 Scrolling\n🄼 Monocle\nⓜ Master"
+ tooltip="Workspace layout: ${name} (${icon})\n\nLeft click: Select layout for active workspace\nRight click: Cycle active workspace layout\n\nOptions:\n🄳 Dwindle\n🅂 Scrolling\n🄼 Monocle\nⓜ Master"
printf '{"text":"%s","tooltip":"%s","class":"%s"}\n' "$icon" "$tooltip" "$current"
}
@@ -97,7 +107,7 @@ show_menu() {
return 0
fi
- choice="$(printf '%s\n' "${options[@]}" | rofi -i -dmenu -p "Layout" -mesg "Left click selects • Right click cycles" -selected-row "$default_row" -config "$rofi_config")"
+ choice="$(printf '%s\n' "${options[@]}" | rofi -i -dmenu -p "Workspace layout" -mesg "Select layout for this workspace" -selected-row "$default_row" -config "$rofi_config")"
[[ -z "$choice" ]] && exit 0
case "$choice" in
diff --git a/config/hypr/scripts/HyprlockWallpaperSelect.sh b/config/hypr/scripts/HyprlockWallpaperSelect.sh
new file mode 100755
index 00000000..a139ca36
--- /dev/null
+++ b/config/hypr/scripts/HyprlockWallpaperSelect.sh
@@ -0,0 +1,358 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Hyprlock wallpaper selector (images + video fallback)
+
+PICTURES_DIR="$(xdg-user-dir PICTURES 2>/dev/null || echo "$HOME/Pictures")"
+wallDIR="$PICTURES_DIR/wallpapers"
+scriptsDir="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images"
+# shellcheck source=/dev/null
+. "$scriptsDir/WallpaperCmd.sh" 2>/dev/null || true
+
+rofi_theme="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-wallpaper.rasi"
+lock_cache_dir="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects"
+lock_wallpaper_link="$lock_cache_dir/.hyprlock_current"
+lock_wallpaper_current="$lock_cache_dir/.wallpaper_current"
+video_cache_dir="$HOME/.cache/hyprlock_preview"
+find_notify_send() {
+ local candidate=""
+ if candidate="$(command -v notify-send 2>/dev/null)"; then
+ [ -n "$candidate" ] && [ -x "$candidate" ] && { printf '%s\n' "$candidate"; return 0; }
+ fi
+ for candidate in /usr/bin/notify-send /usr/sbin/notify-send /bin/notify-send /sbin/notify-send; do
+ [ -x "$candidate" ] && { printf '%s\n' "$candidate"; return 0; }
+ done
+ return 1
+}
+
+NOTIFY_SEND_BIN="$(find_notify_send || true)"
+
+notify_err() {
+ if [ -n "$NOTIFY_SEND_BIN" ]; then
+ if [ -f "$iDIR/error.png" ]; then
+ "$NOTIFY_SEND_BIN" -i "$iDIR/error.png" "Hyprlock Wallpaper" "$1"
+ else
+ "$NOTIFY_SEND_BIN" "Hyprlock Wallpaper" "$1"
+ fi
+ fi
+}
+
+notify_ok() {
+ if [ -n "$NOTIFY_SEND_BIN" ]; then
+ if [ -f "$iDIR/ja.png" ]; then
+ "$NOTIFY_SEND_BIN" -i "$iDIR/ja.png" "Hyprlock Wallpaper" "$1"
+ else
+ "$NOTIFY_SEND_BIN" "Hyprlock Wallpaper" "$1"
+ fi
+ fi
+}
+
+if ! command -v rofi >/dev/null 2>&1; then
+ notify_err "rofi not found"
+ exit 1
+fi
+if ! command -v hyprctl >/dev/null 2>&1; then
+ notify_err "hyprctl not found"
+ exit 1
+fi
+if ! command -v jq >/dev/null 2>&1; then
+ notify_err "jq not found"
+ exit 1
+fi
+if ! command -v bc >/dev/null 2>&1; then
+ notify_err "bc not found"
+ exit 1
+fi
+read_wallpaper_from_query() {
+ local monitor="$1"
+ [ -n "$monitor" ] || return 1
+ "$WWW_CMD" query 2>/dev/null | awk -v mon="$monitor" '
+ {
+ line=$0
+ sub(/^Monitor[[:space:]]+/, "", line)
+ sub(/^:[[:space:]]*/, "", line)
+ mon_name=line
+ sub(/:.*/, "", mon_name)
+ gsub(/^[[:space:]]+|[[:space:]]+$/, "", mon_name)
+ if (mon_name != mon) next
+
+ path=line
+ sub(/^.*image:[[:space:]]*/, "", path)
+ gsub(/^[[:space:]]+|[[:space:]]+$/, "", path)
+ if (path != line && length(path) > 0) {
+ print path
+ exit
+ }
+ }
+ '
+}
+
+read_cached_wallpaper() {
+ local cache_file="$1"
+ [ -f "$cache_file" ] || return 1
+ awk 'NF && $0 !~ /^filter/ {print; exit}' "$cache_file"
+}
+
+read_wallpaper_from_cache() {
+ local monitor="$1"
+ local cache_root="${WWW_CACHE_DIR:-$HOME/.cache/awww}"
+ local cache_file="$cache_root/$monitor"
+ local fallback_cache=""
+ local path=""
+
+ case "$cache_root" in
+ "$HOME/.cache/awww")
+ fallback_cache="$HOME/.cache/swww/$monitor"
+ ;;
+ "$HOME/.cache/swww")
+ fallback_cache="$HOME/.cache/awww/$monitor"
+ ;;
+ esac
+
+ path="$(read_cached_wallpaper "$cache_file" 2>/dev/null || true)"
+ if [ -z "$path" ] && [ -n "$fallback_cache" ]; then
+ path="$(read_cached_wallpaper "$fallback_cache" 2>/dev/null || true)"
+ fi
+
+ [ -n "$path" ] && [ -f "$path" ] || return 1
+ printf '%s\n' "$path"
+}
+
+get_active_workspace_monitor() {
+ hyprctl activeworkspace -j 2>/dev/null | jq -r '.monitor // empty' | head -n1
+}
+
+monitor_exists() {
+ local monitor="$1"
+ [ -n "$monitor" ] || return 1
+ hyprctl monitors -j 2>/dev/null | jq -r --arg mon "$monitor" '.[] | select(.name == $mon) | .name' | grep -qx "$monitor"
+}
+
+focused_monitor=""
+requested_monitor="${1:-${HYPRLOCK_TARGET_MONITOR:-}}"
+if monitor_exists "$requested_monitor"; then
+ focused_monitor="$requested_monitor"
+fi
+if [[ -z "$focused_monitor" ]]; then
+ workspace_monitor="$(get_active_workspace_monitor)"
+ if monitor_exists "$workspace_monitor"; then
+ focused_monitor="$workspace_monitor"
+ fi
+fi
+if [[ -z "$focused_monitor" ]]; then
+ focused_monitor=$(hyprctl monitors -j | jq -r '.[] | select(.focused) | .name' | head -n1)
+fi
+if [[ -z "$focused_monitor" ]]; then
+ notify_err "Could not detect target monitor"
+ exit 1
+fi
+
+per_monitor_rofi_link="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/.current_wallpaper_${focused_monitor}"
+per_monitor_wallpaper_current="$lock_cache_dir/.wallpaper_current_${focused_monitor}"
+
+scale_factor=$(hyprctl monitors -j | jq -r --arg mon "$focused_monitor" '.[] | select(.name == $mon) | .scale')
+monitor_height=$(hyprctl monitors -j | jq -r --arg mon "$focused_monitor" '.[] | select(.name == $mon) | .height')
+icon_size=$(echo "scale=1; ($monitor_height * 3) / ($scale_factor * 150)" | bc)
+adjusted_icon_size=$(echo "$icon_size" | awk '{if ($1 < 15) $1 = 20; if ($1 > 25) $1 = 25; print $1}')
+rofi_override="element-icon{size:${adjusted_icon_size}%;}"
+
+mapfile -d '' PICS < <(find -L "${wallDIR}" -type f \( \
+ -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.gif" -o \
+ -iname "*.bmp" -o -iname "*.tiff" -o -iname "*.webp" -o \
+ -iname "*.mp4" -o -iname "*.mkv" -o -iname "*.mov" -o -iname "*.webm" \) -print0)
+
+if [ "${#PICS[@]}" -eq 0 ]; then
+ notify_err "No wallpapers found in $wallDIR"
+ exit 1
+fi
+
+RANDOM_PIC="${PICS[$((RANDOM % ${#PICS[@]}))]}"
+RANDOM_PIC_NAME="Random: $(basename "$RANDOM_PIC")"
+
+current_lock_path=""
+if [ -L "$lock_wallpaper_link" ]; then
+ current_lock_path="$(readlink -f "$lock_wallpaper_link" 2>/dev/null || true)"
+elif [ -f "$lock_wallpaper_link" ]; then
+ current_lock_path="$lock_wallpaper_link"
+fi
+current_lock_name=""
+if [ -n "$current_lock_path" ]; then
+ current_lock_name="Current: $(basename "$current_lock_path")"
+fi
+
+current_monitor_path=""
+if [ -n "${WWW_CMD:-}" ] && command -v "$WWW_CMD" >/dev/null 2>&1; then
+ current_monitor_path="$(read_wallpaper_from_query "$focused_monitor")"
+fi
+if [ -z "$current_monitor_path" ] && [ -L "$per_monitor_rofi_link" ]; then
+ current_monitor_path="$(readlink -f "$per_monitor_rofi_link" 2>/dev/null || true)"
+fi
+if [ -z "$current_monitor_path" ] && [ -f "$per_monitor_rofi_link" ]; then
+ current_monitor_path="$per_monitor_rofi_link"
+fi
+if [ -z "$current_monitor_path" ] && [ -f "$per_monitor_wallpaper_current" ]; then
+ current_monitor_path="$per_monitor_wallpaper_current"
+fi
+if [ -z "$current_monitor_path" ]; then
+ current_monitor_path="$(read_wallpaper_from_cache "$focused_monitor" 2>/dev/null || true)"
+fi
+if [ -n "$current_monitor_path" ] && [ ! -f "$current_monitor_path" ]; then
+ current_monitor_path=""
+fi
+current_monitor_name=""
+if [ -n "$current_monitor_path" ]; then
+ current_monitor_name="Current monitor: $(basename "$current_monitor_path")"
+fi
+
+rofi_command="rofi -i -show -dmenu -config $rofi_theme -theme-str $rofi_override"
+
+menu() {
+ IFS=$'\n' sorted_options=($(sort <<<"${PICS[*]}"))
+ printf "%s\x00icon\x1f%s\n" "$RANDOM_PIC_NAME" "$RANDOM_PIC"
+ if [ -n "$current_monitor_name" ]; then
+ printf "%s\x00icon\x1f%s\n" "$current_monitor_name" "$current_monitor_path"
+ fi
+ if [ -n "$current_lock_name" ]; then
+ printf "%s\x00icon\x1f%s\n" "$current_lock_name" "$current_lock_path"
+ fi
+ for pic_path in "${sorted_options[@]}"; do
+ pic_name=$(basename "$pic_path")
+ if [[ "$pic_name" =~ \.gif$ ]]; then
+ cache_gif_image="$HOME/.cache/gif_preview/${pic_name}.png"
+ if [[ ! -f "$cache_gif_image" ]]; then
+ mkdir -p "$HOME/.cache/gif_preview"
+ magick "$pic_path[0]" -resize 1920x1080 "$cache_gif_image"
+ fi
+ printf "%s\x00icon\x1f%s\n" "$pic_name" "$cache_gif_image"
+ elif [[ "$pic_name" =~ \.(mp4|mkv|mov|webm|MP4|MKV|MOV|WEBM)$ ]]; then
+ cache_preview_image="$HOME/.cache/video_preview/${pic_name}.png"
+ if [[ ! -f "$cache_preview_image" ]]; then
+ mkdir -p "$HOME/.cache/video_preview"
+ ffmpeg -v error -y -i "$pic_path" -ss 00:00:01.000 -vframes 1 "$cache_preview_image"
+ fi
+ printf "%s\x00icon\x1f%s\n" "$pic_name" "$cache_preview_image"
+ else
+ printf "%s\x00icon\x1f%s\n" "$pic_name" "$pic_path"
+ fi
+ done
+}
+
+update_hyprlock_config() {
+ local conf="$1"
+ local path="$2"
+ [ -f "$conf" ] || return 0
+
+ if grep -qE '^[[:space:]]*path[[:space:]]*=' "$conf"; then
+ sed -i -E "s|^[[:space:]]*path[[:space:]]*=.*| path = $path|" "$conf"
+ elif grep -qE '^[[:space:]]*background[[:space:]]*{' "$conf"; then
+ sed -i -E "/^[[:space:]]*background[[:space:]]*{/a\\ path = $path" "$conf"
+ else
+ printf "\nbackground {\n path = %s\n}\n" "$path" >>"$conf"
+ fi
+}
+
+set_hyprlock_wallpaper() {
+ local selected_file="$1"
+ local target_monitor="${2:-$focused_monitor}"
+ local final_path="$selected_file"
+
+ if [ ! -f "$selected_file" ]; then
+ notify_err "Failed for $target_monitor: selected file not found"
+ return 1
+ fi
+
+ if [[ "$selected_file" =~ \.(mp4|mkv|mov|webm|MP4|MKV|MOV|WEBM)$ ]]; then
+ if ! command -v ffmpeg >/dev/null 2>&1; then
+ notify_err "Failed for $target_monitor: ffmpeg not found for video preview"
+ return 1
+ fi
+ mkdir -p "$video_cache_dir"
+ local video_name
+ video_name="$(basename "$selected_file")"
+ final_path="$video_cache_dir/${video_name}.png"
+ if ! ffmpeg -v error -y -i "$selected_file" -ss 00:00:01.000 -vframes 1 "$final_path"; then
+ notify_err "Failed for $target_monitor: could not generate video preview"
+ return 1
+ fi
+ fi
+
+ mkdir -p "$lock_cache_dir"
+ if ! ln -sf "$final_path" "$lock_wallpaper_link"; then
+ notify_err "Failed for $target_monitor: could not update hyprlock wallpaper link"
+ return 1
+ fi
+ if ! cp -f "$final_path" "$lock_wallpaper_current"; then
+ notify_err "Failed for $target_monitor: could not update lock fallback wallpaper"
+ return 1
+ fi
+
+ update_hyprlock_config "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/hyprlock.conf" "$lock_wallpaper_link"
+ update_hyprlock_config "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/hyprlock-2k.conf" "$lock_wallpaper_link"
+ update_hyprlock_config "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/hyprlock-1080p.conf" "$lock_wallpaper_link"
+
+ pkill -USR1 hyprlock 2>/dev/null || true
+
+ local resolved_path=""
+ if [ -L "$lock_wallpaper_link" ]; then
+ resolved_path="$(readlink -f "$lock_wallpaper_link" 2>/dev/null || true)"
+ elif [ -f "$lock_wallpaper_link" ]; then
+ resolved_path="$lock_wallpaper_link"
+ fi
+
+ if [ -z "$resolved_path" ] || [ ! -f "$resolved_path" ]; then
+ notify_err "Failed for $target_monitor: hyprlock wallpaper was not applied"
+ return 1
+ fi
+
+ notify_ok "Set for $target_monitor: $(basename "$resolved_path")"
+ return 0
+}
+
+main() {
+ choice=$(menu | $rofi_command)
+ choice=$(echo "$choice" | xargs)
+
+ if [[ -z "$choice" ]]; then
+ exit 0
+ fi
+
+ if [[ "$choice" == "$RANDOM_PIC_NAME" ]]; then
+ set_hyprlock_wallpaper "$RANDOM_PIC" "$focused_monitor" || exit 1
+ return
+ fi
+ if [[ "$choice" == "$current_monitor_name" && -n "$current_monitor_path" ]]; then
+ set_hyprlock_wallpaper "$current_monitor_path" "$focused_monitor" || exit 1
+ return
+ fi
+
+ if [[ "$choice" == "$current_lock_name" && -n "$current_lock_path" ]]; then
+ set_hyprlock_wallpaper "$current_lock_path" "$focused_monitor" || exit 1
+ return
+ fi
+
+ if [[ -f "$choice" ]]; then
+ set_hyprlock_wallpaper "$choice" "$focused_monitor" || exit 1
+ return
+ fi
+
+ choice_basename=$(basename "$choice" | sed 's/\(.*\)\.[^.]*$/\1/')
+ selected_file=$(find "$wallDIR" -iname "$choice_basename.*" -print -quit)
+
+ if [[ -z "$selected_file" ]]; then
+ notify_err "Selected choice not found: $choice"
+ exit 1
+ fi
+
+ set_hyprlock_wallpaper "$selected_file" "$focused_monitor" || exit 1
+}
+
+if pidof rofi >/dev/null; then
+ pkill rofi
+fi
+
+main
diff --git a/config/hypr/scripts/JavaManager.sh b/config/hypr/scripts/JavaManager.sh
index 728c69a3..8f8f5612 100755
--- a/config/hypr/scripts/JavaManager.sh
+++ b/config/hypr/scripts/JavaManager.sh
@@ -201,7 +201,7 @@ generate_list() {
}
# --- 6. rofi ---
-THEME="$HOME/.config/rofi/config.rasi"
+THEME="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config.rasi"
SELECTION=$(generate_list | rofi -dmenu -i \
-p "󰒓 Java" \
diff --git a/config/hypr/scripts/KeyBinds.sh b/config/hypr/scripts/KeyBinds.sh
index 1005e797..aff7b808 100755
--- a/config/hypr/scripts/KeyBinds.sh
+++ b/config/hypr/scripts/KeyBinds.sh
@@ -16,7 +16,7 @@ if pidof rofi > /dev/null; then
fi
# define the config files
-config_home="${XDG_CONFIG_HOME:-$HOME/.config}"
+config_home="${XDG_CONFIG_HOME:-${XDG_CONFIG_HOME:-$HOME/.config}}"
hypr_dir="$config_home/hypr"
keybinds_conf="$hypr_dir/configs/Keybinds.conf"
user_keybinds_conf="$hypr_dir/UserConfigs/UserKeybinds.conf"
@@ -26,7 +26,7 @@ lua_user_keybinds="$hypr_dir/UserConfigs/user_keybinds.lua"
lua_system_keybinds="$hypr_dir/configs/system_keybinds.lua"
lua_legacy_system_keybinds="$hypr_dir/UserConfigs/system_keybinds.lua"
lua_overrides="$hypr_dir/UserConfigs/user_overrides.lua"
-rofi_theme="$HOME/.config/rofi/config-keybinds.rasi"
+rofi_theme="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-keybinds.rasi"
msg='☣️ NOTE ☣️: Clicking with Mouse or Pressing ENTER will have NO function'
# detect active Hyprland config mode (Lua entrypoint vs legacy .conf includes)
@@ -55,7 +55,7 @@ fi
# Parse binds using the python script for speed
# The last argument must be the user config for override logic to work correctly
-display_keybinds=$("$HOME/.config/hypr/scripts/keybinds_parser.py" "${files[@]}")
+display_keybinds=$("${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/keybinds_parser.py" "${files[@]}")
# Check for suggestions file created by python script
if [[ -f "/tmp/hypr_keybind_suggestions_file" ]]; then
diff --git a/config/hypr/scripts/KeyHints.sh b/config/hypr/scripts/KeyHints.sh
index a9f6660a..08415dab 100755
--- a/config/hypr/scripts/KeyHints.sh
+++ b/config/hypr/scripts/KeyHints.sh
@@ -61,8 +61,8 @@ GDK_BACKEND=$BACKEND yad \
"CTRL ALT L" "screen lock" "(hyprlock)" \
"CTRL ALT Del" "Hyprland Exit" "(NOTE: Hyprland Will exit immediately)" \
" SHIFT F" "Fullscreen" "Toggles to full screen" \
- " CTL F" "Fake Fullscreen" "Toggles to fake full screen" \
- " ALT L" "Toggle Dwindle|Floating|Monocle|Master layouts" "Hyprland Layouts" \
+ " F" "Fake Fullscreen" "Toggles to fake full screen" \
+ " ALT L" "Toggle Dwindle|Scrolling|Monocle|Master layouts" "Active workspace layout" \
" SPACEBAR" "Toggle float" "single window" \
" ALT SPACEBAR" "Toggle all windows to float" "all windows" \
" ALT O" "Toggle Blur" "normal or less blur" \
diff --git a/config/hypr/scripts/KeybindsLayoutInit.sh b/config/hypr/scripts/KeybindsLayoutInit.sh
index 280e381b..08aff951 100755
--- a/config/hypr/scripts/KeybindsLayoutInit.sh
+++ b/config/hypr/scripts/KeybindsLayoutInit.sh
@@ -5,14 +5,14 @@
# License: GNU GPLv3
# SPDX-License-Identifier: GPL-3.0-or-later
# ==================================================
-# Initialize J/K keybinds so they always cycle windows globally (no layout-specific behavior).
+# Legacy startup hook for layout keybind initialization.
+# Runtime keybind behavior is now resolved per keypress based on active workspace layout.
set -euo pipefail
-# Always reset and bind SUPER+J/K the same way on startup
-hyprctl keyword unbind SUPER,j || true
-hyprctl keyword unbind SUPER,k || true
+scripts_dir="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
-# Cycle windows globally
-hyprctl keyword bind SUPER,j,cyclenext
-hyprctl keyword bind SUPER,k,cyclenext,prev
+# Keep compatibility with existing startup entries while avoiding global rebinding.
+if [[ -x "${scripts_dir}/ChangeLayout.sh" ]]; then
+ "${scripts_dir}/ChangeLayout.sh" --quiet init >/dev/null 2>&1 || true
+fi
diff --git a/config/hypr/scripts/KeyboardLayout.sh b/config/hypr/scripts/KeyboardLayout.sh
index fe092e7f..f126b895 100755
--- a/config/hypr/scripts/KeyboardLayout.sh
+++ b/config/hypr/scripts/KeyboardLayout.sh
@@ -5,10 +5,10 @@
# License: GNU GPLv3
# SPDX-License-Identifier: GPL-3.0-or-later
# ==================================================
-# This is for changing kb_layouts. Set kb_layouts in "$HOME/.config/hypr/UserConfigs/UserSettings.conf"
+# This is for changing kb_layouts. Set kb_layouts in "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserConfigs/UserSettings.conf"
-notif_icon="$HOME/.config/swaync/images/ja.png"
-SCRIPTSDIR="$HOME/.config/hypr/scripts"
+notif_icon="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images/ja.png"
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
# Refined ignore list with patterns or specific device names
ignore_patterns=(
diff --git a/config/hypr/scripts/KillActiveProcess.sh b/config/hypr/scripts/KillActiveProcess.sh
index 66d6b009..9af3f813 100755
--- a/config/hypr/scripts/KillActiveProcess.sh
+++ b/config/hypr/scripts/KillActiveProcess.sh
@@ -13,7 +13,7 @@
active_pid=$(hyprctl activewindow | grep -o 'pid: [0-9]*' | cut -d' ' -f2)
if [[ -z "$active_pid" || ! "$active_pid" =~ ^[0-9]+$ ]]; then
- notify-send -u low -i "$HOME/.config/swaync/images/error.png" "Kill Active Window" "No active window PID found."
+ notify-send -u low -i "${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images/error.png" "Kill Active Window" "No active window PID found."
exit 1
fi
diff --git a/config/hypr/scripts/Kitty_themes.sh b/config/hypr/scripts/Kitty_themes.sh
index 24a4ae11..0de21f8c 100755
--- a/config/hypr/scripts/Kitty_themes.sh
+++ b/config/hypr/scripts/Kitty_themes.sh
@@ -8,11 +8,11 @@
# Kitty Themes Source https://github.com/dexpota/kitty-themes #
# Define directories and variables
-kitty_themes_DiR="$HOME/.config/kitty/kitty-themes" # Kitty Themes Directory
-kitty_config="$HOME/.config/kitty/kitty.conf"
-iDIR="$HOME/.config/swaync/images" # For notifications
-rofi_theme_for_this_script="$HOME/.config/rofi/config-kitty-theme.rasi"
-wallust_refresh_script="$HOME/.config/hypr/scripts/WallustSwww.sh"
+kitty_themes_DiR="${XDG_CONFIG_HOME:-$HOME/.config}/kitty/kitty-themes" # Kitty Themes Directory
+kitty_config="${XDG_CONFIG_HOME:-$HOME/.config}/kitty/kitty.conf"
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images" # For notifications
+rofi_theme_for_this_script="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-kitty-theme.rasi"
+wallust_refresh_script="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/WallustSwww.sh"
debug_log="${XDG_CACHE_HOME:-$HOME/.cache}/kooldots-kitty-themes.log"
# --- Helper Functions ---
diff --git a/config/hypr/scripts/KooLsDotsUpdate.sh b/config/hypr/scripts/KooLsDotsUpdate.sh
index 887993a5..0cfb42a4 100755
--- a/config/hypr/scripts/KooLsDotsUpdate.sh
+++ b/config/hypr/scripts/KooLsDotsUpdate.sh
@@ -8,8 +8,8 @@
# simple bash script to check if update is available by comparing local version and github version
# Local Paths
-local_dir="$HOME/.config/hypr"
-iDIR="$HOME/.config/swaync/images/"
+local_dir="${XDG_CONFIG_HOME:-$HOME/.config}/hypr"
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images/"
local_version=$(find "$local_dir" -maxdepth 1 -name 'v*' -printf '%f\n' 2>/dev/null | sort -V | tail -n 1 | sed 's/^v//')
KooL_Dots_DIR="$HOME/Hyprland-Dots"
diff --git a/config/hypr/scripts/Kool_Quick_Settings.sh b/config/hypr/scripts/Kool_Quick_Settings.sh
index 6ec02bb8..70e98459 100755
--- a/config/hypr/scripts/Kool_Quick_Settings.sh
+++ b/config/hypr/scripts/Kool_Quick_Settings.sh
@@ -49,11 +49,31 @@ fi
# variables
configs="$hypr_dir/configs"
UserConfigs="$hypr_dir/UserConfigs"
-rofi_theme="$HOME/.config/rofi/config-edit.rasi"
+rofi_theme="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-edit.rasi"
msg=' ⁉️ Choose what to do ⁉️'
-iDIR="$HOME/.config/swaync/images"
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images"
scriptsDir="$hypr_dir/scripts"
UserScripts="$hypr_dir/UserScripts"
+user_defaults_conf="$UserConfigs/01-UserDefaults.conf"
+user_defaults_lua="$UserConfigs/user_defaults.lua"
+user_env_conf="$UserConfigs/ENVariables.conf"
+user_env_lua="$UserConfigs/user_env.lua"
+user_keybinds_conf="$UserConfigs/UserKeybinds.conf"
+user_keybinds_lua="$UserConfigs/user_keybinds.lua"
+user_startup_conf="$UserConfigs/Startup_Apps.conf"
+user_startup_lua="$UserConfigs/user_startup.lua"
+user_window_rules_conf="$UserConfigs/WindowRules.conf"
+user_window_rules_lua="$UserConfigs/user_window_rules.lua"
+user_layer_rules_conf="$UserConfigs/LayerRules.conf"
+user_layer_rules_lua="$UserConfigs/user_layer_rules.lua"
+user_settings_conf="$UserConfigs/UserSettings.conf"
+user_settings_lua="$UserConfigs/user_settings.lua"
+user_decorations_conf="$UserConfigs/UserDecorations.conf"
+user_decorations_lua="$UserConfigs/user_decorations.lua"
+user_animations_conf="$UserConfigs/UserAnimations.conf"
+user_animations_lua="$UserConfigs/user_animations.lua"
+user_laptops_conf="$UserConfigs/Laptops.conf"
+user_laptops_lua="$UserConfigs/user_laptops.lua"
# Function to show info notification
show_info() {
@@ -64,6 +84,22 @@ show_info() {
fi
}
+get_context_monitor_name() {
+ if ! command -v hyprctl >/dev/null 2>&1; then
+ return 1
+ fi
+ local monitor=""
+ if command -v jq >/dev/null 2>&1; then
+ monitor="$(hyprctl activeworkspace -j 2>/dev/null | jq -r '.monitor // empty' | head -n1)"
+ if [[ -z "$monitor" ]]; then
+ monitor="$(hyprctl monitors -j 2>/dev/null | jq -r '.[] | select(.focused) | .name' | head -n1)"
+ fi
+ else
+ monitor="$(hyprctl monitors 2>/dev/null | awk '/^Monitor/{name=$2} /focused: yes/{print name; exit}')"
+ fi
+ printf '%s' "$monitor"
+}
+
# Determine whether an editor command is terminal-based (TUI)
is_tui_editor() {
local -a cmd=("$@")
@@ -103,9 +139,24 @@ resolve_system_lua_file() {
fi
}
-resolve_user_defaults_lua_file() {
- local preferred="$UserConfigs/user_defaults.lua"
- printf '%s' "$preferred"
+resolve_mode_file() {
+ local preferred="$1"
+ local fallback="$2"
+ if [[ -f "$preferred" || ! -f "$fallback" ]]; then
+ printf '%s' "$preferred"
+ else
+ printf '%s' "$fallback"
+ fi
+}
+
+resolve_user_overlay_file() {
+ local lua_file="$1"
+ local conf_file="$2"
+ if [[ "$hypr_config_mode" == "lua" ]]; then
+ resolve_mode_file "$lua_file" "$conf_file"
+ else
+ resolve_mode_file "$conf_file" "$lua_file"
+ fi
}
# Function to toggle Rainbow Borders script availability and refresh UI components
toggle_rainbow_borders() {
@@ -271,6 +322,7 @@ Edit System Default Startup Apps
Edit System Default Window Rules
Edit System Default Layer Rules
Edit System Default Settings
+Change Starship Prompt
--- UTILITIES ---
Set SDDM Wallpaper
Choose Kitty Terminal Theme
@@ -280,11 +332,13 @@ Configure Workspace Rules (nwg-displays)
GTK Settings (nwg-look)
QT Apps Settings (qt6ct)
QT Apps Settings (qt5ct)
+Set Hyprlock Wallpaper
Choose Hyprland Animations
Choose Monitor Profiles
Choose Rofi Themes
Search for Keybinds
Toggle Waybar Weather units (C/F)
+Toggle Waybar Clock (12H/24H)
Toggle Game Mode
Switch Dark-Light Theme
Rainbow Borders Mode
@@ -293,36 +347,32 @@ EOF
# Main function to handle menu selection
main() {
+ local quick_settings_monitor
+ quick_settings_monitor="$(get_context_monitor_name)"
choice=$(menu | rofi -i -dmenu -config $rofi_theme -mesg "$msg")
# Map choices to corresponding files
case "$choice" in
"Edit User Defaults")
- if [[ "$hypr_config_mode" == "lua" ]]; then file="$(resolve_user_defaults_lua_file)"; else file="$UserConfigs/01-UserDefaults.conf"; fi ;;
+ file="$(resolve_user_overlay_file "$user_defaults_lua" "$user_defaults_conf")" ;;
"Edit User ENV variables")
- if [[ "$hypr_config_mode" == "lua" ]]; then file="$UserConfigs/user_env.lua"; else file="$UserConfigs/ENVariables.conf"; fi ;;
+ file="$(resolve_user_overlay_file "$user_env_lua" "$user_env_conf")" ;;
"Edit User Keybinds")
- if [[ "$hypr_config_mode" == "lua" ]]; then file="$UserConfigs/user_keybinds.lua"; else file="$UserConfigs/UserKeybinds.conf"; fi ;;
+ file="$(resolve_user_overlay_file "$user_keybinds_lua" "$user_keybinds_conf")" ;;
"Edit User Startup Apps (overlay)")
- if [[ "$hypr_config_mode" == "lua" ]]; then file="$UserConfigs/user_startup.lua"; else file="$UserConfigs/Startup_Apps.conf"; fi ;;
+ file="$(resolve_user_overlay_file "$user_startup_lua" "$user_startup_conf")" ;;
"Edit User Window Rules (overlay)")
- if [[ "$hypr_config_mode" == "lua" ]]; then file="$UserConfigs/user_window_rules.lua"; else file="$UserConfigs/WindowRules.conf"; fi ;;
+ file="$(resolve_user_overlay_file "$user_window_rules_lua" "$user_window_rules_conf")" ;;
"Edit User Layer Rules (overlay)")
- if [[ "$hypr_config_mode" == "lua" ]]; then file="$UserConfigs/user_layer_rules.lua"; else file="$UserConfigs/LayerRules.conf"; fi ;;
+ file="$(resolve_user_overlay_file "$user_layer_rules_lua" "$user_layer_rules_conf")" ;;
"Edit User Settings")
- if [[ "$hypr_config_mode" == "lua" ]]; then
- file="$UserConfigs/user_settings.lua"
- show_info "Lua mode detected. Edit UserConfigs/user_settings.lua for user settings."
- else
- file="$configs/SystemSettings.conf"
- show_info "Editing default settings. Copy to UserConfigs/UserSettings.conf to override."
- fi ;;
+ file="$(resolve_user_overlay_file "$user_settings_lua" "$user_settings_conf")" ;;
"Edit User Decorations")
- if [[ "$hypr_config_mode" == "lua" ]]; then file="$UserConfigs/user_decorations.lua"; else file="$UserConfigs/UserDecorations.conf"; fi ;;
+ file="$(resolve_user_overlay_file "$user_decorations_lua" "$user_decorations_conf")" ;;
"Edit User Animations")
- if [[ "$hypr_config_mode" == "lua" ]]; then file="$UserConfigs/user_animations.lua"; else file="$UserConfigs/UserAnimations.conf"; fi ;;
+ file="$(resolve_user_overlay_file "$user_animations_lua" "$user_animations_conf")" ;;
"Edit User Laptop Settings")
- if [[ "$hypr_config_mode" == "lua" ]]; then file="$UserConfigs/user_laptops.lua"; else file="$UserConfigs/Laptops.conf"; fi ;;
+ file="$(resolve_user_overlay_file "$user_laptops_lua" "$user_laptops_conf")" ;;
"Edit System Default Keybinds")
if [[ "$hypr_config_mode" == "lua" ]]; then file="$(resolve_system_lua_file system_keybinds.lua)"; else file="$configs/Keybinds.conf"; fi ;;
"Edit System Default Startup Apps")
@@ -333,7 +383,14 @@ main() {
if [[ "$hypr_config_mode" == "lua" ]]; then file="$(resolve_system_lua_file system_layer_rules.lua)"; else file="$configs/LayerRules.conf"; fi ;;
"Edit System Default Settings")
if [[ "$hypr_config_mode" == "lua" ]]; then file="$(resolve_system_lua_file system_settings.lua)"; else file="$configs/SystemSettings.conf"; fi ;;
- "Set SDDM Wallpaper") $scriptsDir/sddm_wallpaper.sh --normal ;;
+ "Change Starship Prompt") "$scriptsDir/ChangeStarshipPrompt.sh" ;;
+ "Set SDDM Wallpaper")
+ if [[ -n "$quick_settings_monitor" ]]; then
+ "$scriptsDir/sddm_wallpaper.sh" --normal "$quick_settings_monitor"
+ else
+ "$scriptsDir/sddm_wallpaper.sh" --normal
+ fi
+ ;;
"Choose Kitty Terminal Theme") $scriptsDir/Kitty_themes.sh ;;
"Choose Ghostty Terminal Theme") $scriptsDir/Ghostty_themes.sh ;;
"Configure Monitors (nwg-displays)")
@@ -366,11 +423,19 @@ main() {
exit 1
fi
qt5ct ;;
+ "Set Hyprlock Wallpaper")
+ if [[ -n "$quick_settings_monitor" ]]; then
+ "$scriptsDir/HyprlockWallpaperSelect.sh" "$quick_settings_monitor"
+ else
+ "$scriptsDir/HyprlockWallpaperSelect.sh"
+ fi
+ ;;
"Choose Hyprland Animations") $scriptsDir/Animations.sh ;;
"Choose Monitor Profiles") $scriptsDir/MonitorProfiles.sh ;;
"Choose Rofi Themes") $scriptsDir/RofiThemeSelector.sh ;;
"Search for Keybinds") $scriptsDir/KeyBinds.sh ;;
"Toggle Waybar Weather units (C/F)") $scriptsDir/Toggle-weather-waybar-units.sh ;;
+ "Toggle Waybar Clock (12H/24H)") $scriptsDir/ToggleWaybarTime.sh ;;
"Toggle Game Mode") $scriptsDir/GameMode.sh ;;
"Switch Dark-Light Theme") $scriptsDir/DarkLight.sh ;;
"Rainbow Borders Mode") rainbow_borders_menu ;;
diff --git a/config/hypr/scripts/LaunchFileManager.sh b/config/hypr/scripts/LaunchFileManager.sh
new file mode 100755
index 00000000..8436451b
--- /dev/null
+++ b/config/hypr/scripts/LaunchFileManager.sh
@@ -0,0 +1,122 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Launch preferred file manager with fallback handling.
+# Usage:
+# LaunchFileManager.sh "<preferred-file-manager-cmd>" "<preferred-terminal-cmd>"
+# Examples:
+# LaunchFileManager.sh "thunar" "kitty"
+
+set -u
+
+notify_msg() {
+ local urgency="${1:-normal}"
+ local body="${2:-}"
+ if command -v notify-send >/dev/null 2>&1; then
+ notify-send -u "$urgency" "KooL Launchers" "$body"
+ fi
+}
+
+trim() {
+ local value="${1:-}"
+ value="${value#"${value%%[![:space:]]*}"}"
+ value="${value%"${value##*[![:space:]]}"}"
+ printf '%s' "$value"
+}
+
+command_bin_from_string() {
+ local cmd
+ cmd="$(trim "${1:-}")"
+ [[ -n "$cmd" ]] || return 1
+ (
+ eval "set -- $cmd"
+ printf '%s' "${1:-}"
+ ) 2>/dev/null
+}
+
+command_exists_from_string() {
+ local bin
+ bin="$(command_bin_from_string "${1:-}" 2>/dev/null || true)"
+ [[ -n "$bin" ]] || return 1
+ command -v "$bin" >/dev/null 2>&1
+}
+
+launch_command_string() {
+ local cmd
+ cmd="$(trim "${1:-}")"
+ [[ -n "$cmd" ]] || return 1
+
+ if ! command_exists_from_string "$cmd"; then
+ return 127
+ fi
+
+ (
+ eval "exec $cmd"
+ ) >/dev/null 2>&1 &
+ local pid=$!
+
+ sleep 0.35
+ if kill -0 "$pid" >/dev/null 2>&1; then
+ disown "$pid" >/dev/null 2>&1 || true
+ return 0
+ fi
+
+ wait "$pid"
+ local rc=$?
+ [[ $rc -eq 0 ]]
+}
+
+append_unique_candidate() {
+ local candidate
+ candidate="$(trim "${1:-}")"
+ [[ -n "$candidate" ]] || return 0
+ local existing
+ for existing in "${CANDIDATES[@]}"; do
+ [[ "$existing" == "$candidate" ]] && return 0
+ done
+ CANDIDATES+=("$candidate")
+}
+
+script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+terminal_launcher="$script_dir/LaunchTerminal.sh"
+
+preferred_files="$(trim "${1:-${FILE_MANAGER:-}}")"
+preferred_term="$(trim "${2:-${TERMINAL:-kitty}}")"
+
+declare -a CANDIDATES=()
+append_unique_candidate "$preferred_files"
+append_unique_candidate "thunar"
+append_unique_candidate "dolphin"
+append_unique_candidate "nautilus"
+
+reported_preferred_issue=0
+
+for candidate in "${CANDIDATES[@]}"; do
+ if launch_command_string "$candidate"; then
+ exit 0
+ fi
+
+ if [[ $reported_preferred_issue -eq 0 && -n "$preferred_files" && "$candidate" == "$preferred_files" ]]; then
+ if ! command_exists_from_string "$preferred_files"; then
+ notify_msg normal "Preferred file manager '$preferred_files' is not installed. Falling back."
+ else
+ notify_msg normal "Preferred file manager '$preferred_files' failed to launch. Falling back."
+ fi
+ reported_preferred_issue=1
+ fi
+done
+
+if command -v yazi >/dev/null 2>&1; then
+ if [[ -x "$terminal_launcher" ]] && "$terminal_launcher" "$preferred_term" "yazi"; then
+ exit 0
+ fi
+else
+ notify_msg normal "No GUI file manager was launched and 'yazi' is not installed."
+fi
+
+notify_msg critical "Unable to launch file manager. Tried preferred app, thunar, dolphin, nautilus, then terminal + yazi."
+exit 1
diff --git a/config/hypr/scripts/LaunchTerminal.sh b/config/hypr/scripts/LaunchTerminal.sh
new file mode 100755
index 00000000..8992a40d
--- /dev/null
+++ b/config/hypr/scripts/LaunchTerminal.sh
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Launch preferred terminal with fallback handling.
+# Usage:
+# LaunchTerminal.sh "<preferred-terminal-cmd>" [payload-command]
+# Examples:
+# LaunchTerminal.sh "kitty"
+# LaunchTerminal.sh "ghostty" "yazi"
+
+set -u
+
+notify_msg() {
+ local urgency="${1:-normal}"
+ local body="${2:-}"
+ if command -v notify-send >/dev/null 2>&1; then
+ notify-send -u "$urgency" "KooL Launchers" "$body"
+ fi
+}
+
+trim() {
+ local value="${1:-}"
+ value="${value#"${value%%[![:space:]]*}"}"
+ value="${value%"${value##*[![:space:]]}"}"
+ printf '%s' "$value"
+}
+
+shell_quote() {
+ local value="${1:-}"
+ printf "'%s'" "${value//\'/\'\\\'\'}"
+}
+
+command_bin_from_string() {
+ local cmd
+ cmd="$(trim "${1:-}")"
+ [[ -n "$cmd" ]] || return 1
+ (
+ eval "set -- $cmd"
+ printf '%s' "${1:-}"
+ ) 2>/dev/null
+}
+
+command_exists_from_string() {
+ local bin
+ bin="$(command_bin_from_string "${1:-}" 2>/dev/null || true)"
+ [[ -n "$bin" ]] || return 1
+ command -v "$bin" >/dev/null 2>&1
+}
+
+launch_command_string() {
+ local cmd
+ cmd="$(trim "${1:-}")"
+ [[ -n "$cmd" ]] || return 1
+
+ if ! command_exists_from_string "$cmd"; then
+ return 127
+ fi
+
+ (
+ eval "exec $cmd"
+ ) >/dev/null 2>&1 &
+ local pid=$!
+
+ sleep 0.35
+ if kill -0 "$pid" >/dev/null 2>&1; then
+ disown "$pid" >/dev/null 2>&1 || true
+ return 0
+ fi
+
+ wait "$pid"
+ local rc=$?
+ [[ $rc -eq 0 ]]
+}
+
+build_terminal_command() {
+ local term_cmd payload bin q_payload
+ term_cmd="$(trim "${1:-}")"
+ payload="$(trim "${2:-}")"
+
+ if [[ -z "$payload" ]]; then
+ printf '%s' "$term_cmd"
+ return 0
+ fi
+
+ bin="$(command_bin_from_string "$term_cmd" 2>/dev/null || true)"
+ q_payload="$(shell_quote "$payload")"
+
+ case "$bin" in
+ gnome-terminal)
+ printf '%s -- %s' "$term_cmd" "$q_payload"
+ ;;
+ wezterm)
+ case "$term_cmd" in
+ *" start "* | "wezterm start")
+ printf '%s -- %s' "$term_cmd" "$q_payload"
+ ;;
+ *)
+ printf '%s start -- %s' "$term_cmd" "$q_payload"
+ ;;
+ esac
+ ;;
+ *)
+ printf '%s -e %s' "$term_cmd" "$q_payload"
+ ;;
+ esac
+}
+
+append_unique_candidate() {
+ local candidate
+ candidate="$(trim "${1:-}")"
+ [[ -n "$candidate" ]] || return 0
+ local existing
+ for existing in "${CANDIDATES[@]}"; do
+ [[ "$existing" == "$candidate" ]] && return 0
+ done
+ CANDIDATES+=("$candidate")
+}
+
+preferred_term="$(trim "${1:-${TERMINAL:-}}")"
+payload_cmd="$(trim "${2:-}")"
+
+declare -a CANDIDATES=()
+append_unique_candidate "$preferred_term"
+append_unique_candidate "kitty"
+append_unique_candidate "ghostty"
+append_unique_candidate "alacritty"
+append_unique_candidate "wezterm"
+append_unique_candidate "konsole"
+append_unique_candidate "gnome-terminal"
+
+reported_preferred_issue=0
+candidate_cmd=""
+
+for candidate in "${CANDIDATES[@]}"; do
+ candidate_cmd="$(build_terminal_command "$candidate" "$payload_cmd")"
+ if launch_command_string "$candidate_cmd"; then
+ exit 0
+ fi
+
+ if [[ $reported_preferred_issue -eq 0 && -n "$preferred_term" && "$candidate" == "$preferred_term" ]]; then
+ if ! command_exists_from_string "$preferred_term"; then
+ notify_msg normal "Preferred terminal '$preferred_term' is not installed. Falling back."
+ else
+ notify_msg normal "Preferred terminal '$preferred_term' failed to launch. Falling back."
+ fi
+ reported_preferred_issue=1
+ fi
+done
+
+if [[ -n "$payload_cmd" ]]; then
+ notify_msg critical "Unable to launch terminal for command '$payload_cmd'."
+else
+ notify_msg critical "Unable to launch terminal. Install one of: kitty, ghostty, alacritty, wezterm, konsole, gnome-terminal."
+fi
+
+exit 1
diff --git a/config/hypr/scripts/LaunchThunar.sh b/config/hypr/scripts/LaunchThunar.sh
new file mode 100755
index 00000000..08ff911e
--- /dev/null
+++ b/config/hypr/scripts/LaunchThunar.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+#
+# Launch Thunar reliably from Hyprland keybinds.
+
+runtime="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
+
+if [ -z "${WAYLAND_DISPLAY:-}" ]; then
+ for sock in "$runtime"/wayland-[0-9]*; do
+ [ -S "$sock" ] || continue
+ case "$(basename "$sock")" in
+ *awww*) continue ;;
+ esac
+ export WAYLAND_DISPLAY="$(basename "$sock")"
+ break
+ done
+fi
+
+if [ -z "${DISPLAY:-}" ] && [ -n "${WAYLAND_DISPLAY:-}" ]; then
+ export DISPLAY=:1
+fi
+
+# If a stale daemon exists with no visible windows, restart it.
+if pgrep -x thunar >/dev/null 2>&1; then
+ if command -v hyprctl >/dev/null 2>&1; then
+ if ! python3 - <<'PY'
+import json
+import subprocess
+import sys
+
+try:
+ clients = json.loads(subprocess.check_output(["hyprctl", "clients", "-j"], text=True))
+except Exception:
+ sys.exit(0)
+
+sys.exit(0 if any((c.get("class") or "").lower() == "thunar" for c in clients) else 1)
+PY
+ then
+ thunar --quit >/dev/null 2>&1 || pkill -x thunar >/dev/null 2>&1 || true
+ sleep 0.2
+ fi
+ fi
+fi
+
+exec thunar "$HOME"
diff --git a/config/hypr/scripts/LayoutKeybindDispatch.sh b/config/hypr/scripts/LayoutKeybindDispatch.sh
new file mode 100755
index 00000000..48d3a1c5
--- /dev/null
+++ b/config/hypr/scripts/LayoutKeybindDispatch.sh
@@ -0,0 +1,219 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Dispatch layout-sensitive navigation actions per active workspace.
+# This keeps SUPER+J/K and SUPER+arrow behavior aligned with workspace rules.
+
+set -u
+
+if ! command -v hyprctl >/dev/null 2>&1; then
+ exit 0
+fi
+
+LUA_CYCLE_SCRIPT="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/LuaCycleWindow.sh"
+
+normalize_layout() {
+ case "$1" in
+ master | dwindle | scrolling | monocle)
+ printf '%s\n' "$1"
+ ;;
+ *)
+ printf '\n'
+ ;;
+ esac
+}
+
+get_active_layout() {
+ local layout
+
+ layout="$(hyprctl -j activeworkspace 2>/dev/null | jq -r '.tiledLayout // .tiled_layout // .layout // empty' 2>/dev/null || true)"
+ layout="$(normalize_layout "$layout")"
+
+ if [[ -z "$layout" ]]; then
+ layout="$(hyprctl -j getoption general:layout 2>/dev/null | jq -r '.str // empty' 2>/dev/null || true)"
+ layout="$(normalize_layout "$layout")"
+ fi
+
+ if [[ -z "$layout" ]]; then
+ layout="dwindle"
+ fi
+
+ printf '%s\n' "$layout"
+}
+
+dispatch_quiet() {
+ local dispatcher="$1"
+ shift || true
+ if (($# > 0)); then
+ hyprctl dispatch "$dispatcher" "$@" >/dev/null 2>&1 || true
+ else
+ hyprctl dispatch "$dispatcher" >/dev/null 2>&1 || true
+ fi
+}
+
+get_active_window_address() {
+ if ! command -v jq >/dev/null 2>&1; then
+ printf '\n'
+ return 0
+ fi
+ hyprctl -j activewindow 2>/dev/null | jq -r '.address // empty' 2>/dev/null || true
+}
+
+dispatch_changed_focus() {
+ local before after dispatcher="$1"
+ shift || true
+ before="$(get_active_window_address)"
+ dispatch_quiet "$dispatcher" "$@"
+ after="$(get_active_window_address)"
+ [[ -n "$before" && -n "$after" && "$before" != "$after" ]]
+}
+
+direction_word() {
+ case "$1" in
+ l | left) printf 'left\n' ;;
+ r | right) printf 'right\n' ;;
+ u | up) printf 'up\n' ;;
+ d | down) printf 'down\n' ;;
+ *) printf 'right\n' ;;
+ esac
+}
+
+dispatch_lua_focus() {
+ local dir_word
+ dir_word="$(direction_word "$1")"
+ hyprctl dispatch "hl.dsp.focus({ direction = \"$dir_word\" })" >/dev/null 2>&1 || true
+}
+
+cycle_lua() {
+ local mode="${1:-next}"
+ if [[ -x "$LUA_CYCLE_SCRIPT" ]]; then
+ "$LUA_CYCLE_SCRIPT" "$mode" >/dev/null 2>&1 || true
+ return 0
+ fi
+ case "$mode" in
+ previous | prev | back) dispatch_lua_focus left ;;
+ *) dispatch_lua_focus right ;;
+ esac
+}
+
+cycle_next() {
+ local layout="$1"
+ case "$layout" in
+ scrolling)
+ if ! dispatch_changed_focus layoutmsg "focus r"; then
+ dispatch_lua_focus right
+ fi
+ ;;
+ monocle)
+ if ! dispatch_changed_focus layoutmsg cyclenext; then
+ cycle_lua next
+ fi
+ ;;
+ *)
+ if ! dispatch_changed_focus cyclenext; then
+ cycle_lua next
+ fi
+ ;;
+ esac
+}
+
+cycle_prev() {
+ local layout="$1"
+ case "$layout" in
+ scrolling)
+ if ! dispatch_changed_focus layoutmsg "focus l"; then
+ dispatch_lua_focus left
+ fi
+ ;;
+ monocle)
+ if ! dispatch_changed_focus layoutmsg cycleprev; then
+ cycle_lua previous
+ fi
+ ;;
+ *)
+ if ! dispatch_changed_focus cyclenext prev; then
+ cycle_lua previous
+ fi
+ ;;
+ esac
+}
+
+focus_by_layout() {
+ local layout="$1"
+ local direction="$2"
+
+ case "$layout" in
+ master)
+ if ! dispatch_changed_focus movefocus "$direction"; then
+ dispatch_lua_focus "$direction"
+ fi
+ ;;
+ monocle)
+ case "$direction" in
+ l | u) cycle_prev "$layout" ;;
+ *) cycle_next "$layout" ;;
+ esac
+ ;;
+ dwindle | scrolling)
+ case "$direction" in
+ l | u)
+ if [[ "$layout" == "scrolling" ]]; then
+ if ! dispatch_changed_focus layoutmsg "focus $direction"; then
+ dispatch_lua_focus "$direction"
+ fi
+ else
+ cycle_prev "$layout"
+ fi
+ ;;
+ *)
+ if [[ "$layout" == "scrolling" ]]; then
+ if ! dispatch_changed_focus layoutmsg "focus $direction"; then
+ dispatch_lua_focus "$direction"
+ fi
+ else
+ cycle_next "$layout"
+ fi
+ ;;
+ esac
+ ;;
+ *)
+ if ! dispatch_changed_focus movefocus "$direction"; then
+ dispatch_lua_focus "$direction"
+ fi
+ ;;
+ esac
+}
+
+layout="$(get_active_layout)"
+
+case "${1:-}" in
+cycle-next | next)
+ cycle_next "$layout"
+ ;;
+cycle-prev | prev | previous)
+ cycle_prev "$layout"
+ ;;
+focus-left | left)
+ focus_by_layout "$layout" l
+ ;;
+focus-right | right)
+ focus_by_layout "$layout" r
+ ;;
+focus-up | up)
+ focus_by_layout "$layout" u
+ ;;
+focus-down | down)
+ focus_by_layout "$layout" d
+ ;;
+layout | current-layout | status)
+ printf '%s\n' "$layout"
+ ;;
+*)
+ echo "Usage: $(basename "$0") [cycle-next|cycle-prev|focus-left|focus-right|focus-up|focus-down|layout]" >&2
+ exit 1
+ ;;
+esac
diff --git a/config/hypr/scripts/LockScreen.sh b/config/hypr/scripts/LockScreen.sh
index b795a8f7..c63a1e90 100755
--- a/config/hypr/scripts/LockScreen.sh
+++ b/config/hypr/scripts/LockScreen.sh
@@ -10,7 +10,7 @@
#pidof hyprlock || hyprlock -q
# Ensure weather cache is up-to-date before locking (Waybar/lockscreen readers)
-bash "$HOME/.config/hypr/UserScripts/WeatherWrap.sh" >/dev/null 2>&1 &
+bash "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserScripts/WeatherWrap.sh" >/dev/null 2>&1 &
loginctl lock-session
diff --git a/config/hypr/scripts/LuaAutoReload.sh b/config/hypr/scripts/LuaAutoReload.sh
index 4a9d5040..128c1fc9 100755
--- a/config/hypr/scripts/LuaAutoReload.sh
+++ b/config/hypr/scripts/LuaAutoReload.sh
@@ -9,8 +9,23 @@
set -euo pipefail
-watch_root="$HOME/.config/hypr"
+watch_root="${XDG_CONFIG_HOME:-$HOME/.config}/hypr"
[ -d "$watch_root" ] || exit 0
+session="${HYPRLAND_INSTANCE_SIGNATURE:-default}"
+pid_file="/tmp/hypr-lua-autoreload-${session}.pid"
+
+if [ -f "$pid_file" ]; then
+ existing_pid="$(cat "$pid_file" 2>/dev/null || true)"
+ if [ -n "$existing_pid" ] && kill -0 "$existing_pid" 2>/dev/null; then
+ exit 0
+ fi
+fi
+
+echo "$$" >"$pid_file"
+cleanup() {
+ rm -f "$pid_file"
+}
+trap cleanup EXIT INT TERM
reload_hypr() {
hyprctl reload >/dev/null 2>&1 || true
diff --git a/config/hypr/scripts/MediaCtrl.sh b/config/hypr/scripts/MediaCtrl.sh
index aeabcac9..958543dc 100755
--- a/config/hypr/scripts/MediaCtrl.sh
+++ b/config/hypr/scripts/MediaCtrl.sh
@@ -7,7 +7,7 @@
# ==================================================
# Playerctl
-music_icon="$HOME/.config/swaync/icons/music.png"
+music_icon="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/icons/music.png"
# Play the next track
play_next() {
diff --git a/config/hypr/scripts/MonitorProfiles.sh b/config/hypr/scripts/MonitorProfiles.sh
index 6330d45c..09467e76 100755
--- a/config/hypr/scripts/MonitorProfiles.sh
+++ b/config/hypr/scripts/MonitorProfiles.sh
@@ -13,7 +13,7 @@ if pidof rofi > /dev/null; then
fi
# Detect active Hyprland config mode (Lua entrypoint vs legacy .conf includes)
-config_home="${XDG_CONFIG_HOME:-$HOME/.config}"
+config_home="${XDG_CONFIG_HOME:-${XDG_CONFIG_HOME:-$HOME/.config}}"
hypr_dir="$config_home/hypr"
lua_entry="$hypr_dir/hyprland.lua"
legacy_lua_entry="$config_home/hyprland.lua"
@@ -35,22 +35,22 @@ if [[ -z "$hypr_config_mode" ]]; then
fi
# Variables
-iDIR="$HOME/.config/swaync/images"
-SCRIPTSDIR="$HOME/.config/hypr/scripts"
-monitor_dir="$HOME/.config/hypr/Monitor_Profiles"
-target_conf="$HOME/.config/hypr/monitors.conf"
-target_lua_user="$HOME/.config/hypr/UserConfigs/monitors.lua"
-target_lua_legacy="$HOME/.config/hypr/lua/monitors.lua"
-rofi_theme="$HOME/.config/rofi/config-Monitors.rasi"
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images"
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
+monitor_dir="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/Monitor_Profiles"
+target_conf="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/monitors.conf"
+target_lua_user="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserConfigs/monitors.lua"
+target_lua_legacy="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/lua/monitors.lua"
+rofi_theme="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-Monitors.rasi"
if [[ "$hypr_config_mode" == "lua" ]]; then
profile_ext="lua"
target="$target_lua_user"
- msg="❗NOTE:❗ This will overwrite $HOME/.config/hypr/UserConfigs/monitors.lua"
+ msg="❗NOTE:❗ This will overwrite ${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserConfigs/monitors.lua"
else
profile_ext="conf"
target="$target_conf"
- msg="❗NOTE:❗ This will overwrite $HOME/.config/hypr/monitors.conf"
+ msg="❗NOTE:❗ This will overwrite ${XDG_CONFIG_HOME:-$HOME/.config}/hypr/monitors.conf"
fi
# Define the list of files to ignore
diff --git a/config/hypr/scripts/OverviewToggle.sh b/config/hypr/scripts/OverviewToggle.sh
index 456ccef1..7c55ae82 100755
--- a/config/hypr/scripts/OverviewToggle.sh
+++ b/config/hypr/scripts/OverviewToggle.sh
@@ -9,7 +9,7 @@
set -euo pipefail
-QS_OVERVIEW_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/quickshell/overview"
+QS_OVERVIEW_DIR="${XDG_CONFIG_HOME:-${XDG_CONFIG_HOME:-$HOME/.config}}/quickshell/overview"
# 1) Prefer Quickshell when installed and configured
if command -v qs >/dev/null 2>&1 && [ -d "$QS_OVERVIEW_DIR" ]; then
diff --git a/config/hypr/scripts/PersistWorkspaceLayout.sh b/config/hypr/scripts/PersistWorkspaceLayout.sh
new file mode 100755
index 00000000..b5745880
--- /dev/null
+++ b/config/hypr/scripts/PersistWorkspaceLayout.sh
@@ -0,0 +1,223 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Persist active monitor/workspace layout back into ~/.config/hypr/workspaces.conf.
+
+set -u
+
+quiet_mode=0
+layout_override=""
+workspace_override=""
+monitor_override=""
+workspaces_file="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/workspaces.conf"
+
+usage() {
+ cat <<'EOF'
+Usage: PersistWorkspaceLayout.sh [--quiet] [--layout <layout>] [--workspace <selector>] [--monitor <monitor>] [--file <path>]
+ --quiet Suppress console notifications.
+ --layout <layout> Override layout (master|dwindle|scrolling|monocle).
+ --workspace <sel> Override workspace selector (e.g. 5, name:code, special:scratchpad).
+ --monitor <name> Override monitor name.
+ --file <path> Target workspace rules file (default: ~/.config/hypr/workspaces.conf).
+EOF
+}
+
+normalize_layout() {
+ case "$1" in
+ master | dwindle | scrolling | monocle)
+ printf '%s\n' "$1"
+ ;;
+ *)
+ printf '\n'
+ ;;
+ esac
+}
+
+require_cmd() {
+ command -v "$1" >/dev/null 2>&1 || {
+ echo "Missing dependency: $1" >&2
+ exit 1
+ }
+}
+
+get_active_workspace_json() {
+ hyprctl -j activeworkspace 2>/dev/null || printf '{}'
+}
+
+get_workspace_selector() {
+ local ws_json="$1"
+ local ws_id ws_name
+
+ ws_id="$(jq -r '.id // empty' <<<"$ws_json" 2>/dev/null || true)"
+ ws_name="$(jq -r '.name // empty' <<<"$ws_json" 2>/dev/null || true)"
+
+ if [[ "$ws_id" =~ ^[0-9]+$ ]] && ((ws_id > 0)); then
+ printf '%s\n' "$ws_id"
+ return 0
+ fi
+
+ if [[ -n "$ws_name" && "$ws_name" != "null" ]]; then
+ if [[ "$ws_name" == name:* || "$ws_name" == special:* ]]; then
+ printf '%s\n' "$ws_name"
+ else
+ printf 'name:%s\n' "$ws_name"
+ fi
+ return 0
+ fi
+
+ return 1
+}
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --quiet | --no-notify)
+ quiet_mode=1
+ shift
+ ;;
+ --layout)
+ layout_override="${2:-}"
+ shift 2
+ ;;
+ --workspace)
+ workspace_override="${2:-}"
+ shift 2
+ ;;
+ --monitor)
+ monitor_override="${2:-}"
+ shift 2
+ ;;
+ --file)
+ workspaces_file="${2:-}"
+ shift 2
+ ;;
+ -h | --help)
+ usage
+ exit 0
+ ;;
+ *)
+ echo "Unknown argument: $1" >&2
+ usage >&2
+ exit 1
+ ;;
+ esac
+done
+
+require_cmd hyprctl
+require_cmd jq
+require_cmd awk
+require_cmd mktemp
+
+ws_json="$(get_active_workspace_json)"
+workspace_selector="${workspace_override:-$(get_workspace_selector "$ws_json" || true)}"
+monitor_name="${monitor_override:-$(jq -r '.monitor // empty' <<<"$ws_json" 2>/dev/null || true)}"
+
+if [[ -n "$layout_override" ]]; then
+ layout_name="$(normalize_layout "$layout_override")"
+else
+ layout_name="$(jq -r '.tiledLayout // .tiled_layout // empty' <<<"$ws_json" 2>/dev/null || true)"
+ layout_name="$(normalize_layout "$layout_name")"
+ if [[ -z "$layout_name" ]]; then
+ layout_name="$(hyprctl -j getoption general:layout 2>/dev/null | jq -r '.str // empty' 2>/dev/null || true)"
+ layout_name="$(normalize_layout "$layout_name")"
+ fi
+fi
+
+if [[ -z "$workspace_selector" || -z "$monitor_name" || -z "$layout_name" ]]; then
+ echo "Unable to resolve workspace, monitor, or layout for persistence" >&2
+ exit 1
+fi
+
+mkdir -p "$(dirname "$workspaces_file")"
+touch "$workspaces_file"
+
+tmp_file="$(mktemp "${workspaces_file}.XXXXXX")"
+cleanup() {
+ rm -f "$tmp_file"
+}
+trap cleanup EXIT
+
+awk \
+ -v target_ws="$workspace_selector" \
+ -v target_mon="$monitor_name" \
+ -v target_layout="$layout_name" '
+function trim(v) {
+ gsub(/^[[:space:]]+|[[:space:]]+$/, "", v)
+ return v
+}
+BEGIN {
+ updated = 0
+}
+{
+ line = $0
+ content = line
+ comment = ""
+ hash_pos = index(line, "#")
+ if (hash_pos > 0) {
+ content = substr(line, 1, hash_pos - 1)
+ comment = substr(line, hash_pos)
+ }
+ stripped = trim(content)
+ indent_len = match(line, /[^[:space:]]/) - 1
+ if (indent_len < 0) {
+ indent_len = length(line)
+ }
+ indent = substr(line, 1, indent_len)
+
+ if (stripped ~ /^workspace[[:space:]]*=/) {
+ sub(/^workspace[[:space:]]*=[[:space:]]*/, "", stripped)
+ token_count = split(stripped, tokens, /,/)
+ ws = trim(tokens[1])
+ mon = ""
+ extras_count = 0
+ delete extras
+
+ for (i = 2; i <= token_count; i++) {
+ token = trim(tokens[i])
+ if (token == "") {
+ continue
+ }
+ if (token ~ /^monitor:/) {
+ mon = trim(substr(token, 9))
+ continue
+ }
+ if (token ~ /^layout:/) {
+ continue
+ }
+ extras[++extras_count] = token
+ }
+
+ if (ws == target_ws && mon == target_mon) {
+ if (!updated) {
+ rebuilt = indent "workspace = " ws ", monitor:" target_mon ", layout:" target_layout
+ for (i = 1; i <= extras_count; i++) {
+ rebuilt = rebuilt ", " extras[i]
+ }
+ if (comment != "") {
+ rebuilt = rebuilt " " comment
+ }
+ print rebuilt
+ updated = 1
+ }
+ next
+ }
+ }
+
+ print line
+}
+END {
+ if (!updated) {
+ print "workspace = " target_ws ", monitor:" target_mon ", layout:" target_layout
+ }
+}
+' "$workspaces_file" >"$tmp_file"
+
+mv "$tmp_file" "$workspaces_file"
+trap - EXIT
+
+if [[ "$quiet_mode" -eq 0 ]]; then
+ printf 'Saved workspace layout: %s @ %s -> %s\n' "$workspace_selector" "$monitor_name" "$layout_name"
+fi
diff --git a/config/hypr/scripts/Polkit-Diag.sh b/config/hypr/scripts/Polkit-Diag.sh
index aa4e69a8..8e0e9f23 100755
--- a/config/hypr/scripts/Polkit-Diag.sh
+++ b/config/hypr/scripts/Polkit-Diag.sh
@@ -15,7 +15,7 @@ INSTALL_OVERRIDE=0
FORCE_OVERRIDE=0
# Systemd override details for hyprpolkitagent
-OVERRIDE_DIR="$HOME/.config/systemd/user/hyprpolkitagent.service.d"
+OVERRIDE_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user/hyprpolkitagent.service.d"
OVERRIDE_FILE="$OVERRIDE_DIR/override.conf"
OVERRIDE_CONTENT="[Unit]
diff --git a/config/hypr/scripts/PortalHyprland.sh b/config/hypr/scripts/PortalHyprland.sh
index 3d3dc410..54ea71bb 100755
--- a/config/hypr/scripts/PortalHyprland.sh
+++ b/config/hypr/scripts/PortalHyprland.sh
@@ -10,21 +10,73 @@
set -euo pipefail
is_ubuntu_family() {
if [[ ! -r /etc/os-release ]]; then
- return 1
+ #return 1
+ # It's been reported this also addresses
+ # The xdg-desktop-portal failure when not using
+ # UWSM on Arch
+ exit 0
fi
# shellcheck disable=SC1091
. /etc/os-release
- [[ "${ID:-}" == "ubuntu" \
- || "${ID:-}" == "linuxmint" \
- || "${ID:-}" == "zorin" \
- || "${ID:-}" == "rhino" \
- || "${ID_LIKE:-}" == *ubuntu* ]]
+ [[ "${ID:-}" == "ubuntu" ||
+ "${ID:-}" == "linuxmint" ||
+ "${ID:-}" == "zorin" ||
+ "${ID:-}" == "rhino" ||
+ "${ID_LIKE:-}" == *ubuntu* ]]
}
kill_quietly() {
killall -q "$1" 2>/dev/null || true
}
+wait_for_wayland() {
+ local runtime_dir="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
+ export XDG_RUNTIME_DIR="$runtime_dir"
+
+ if [[ -n "${WAYLAND_DISPLAY:-}" && -S "$runtime_dir/$WAYLAND_DISPLAY" ]]; then
+ return 0
+ fi
+
+ for _ in $(seq 1 120); do
+ if [[ -n "${WAYLAND_DISPLAY:-}" && -S "$runtime_dir/$WAYLAND_DISPLAY" ]]; then
+ return 0
+ fi
+
+ for socket in "$runtime_dir"/wayland-[0-9]*; do
+ [[ -S "$socket" ]] || continue
+ case "$(basename "$socket")" in
+ *awww*) continue ;;
+ esac
+ export WAYLAND_DISPLAY="$(basename "$socket")"
+ return 0
+ done
+ sleep 0.1
+ done
+
+ return 1
+}
+
+ensure_portal_env() {
+ export XDG_CURRENT_DESKTOP="${XDG_CURRENT_DESKTOP:-Hyprland}"
+ export XDG_SESSION_DESKTOP="${XDG_SESSION_DESKTOP:-Hyprland}"
+ export XDG_SESSION_TYPE="${XDG_SESSION_TYPE:-wayland}"
+ if [[ -f "/usr/share/glib-2.0/schemas/gschemas.compiled" ]]; then
+ export GSETTINGS_SCHEMA_DIR="/usr/share/glib-2.0/schemas"
+ fi
+
+ local data_dirs="${XDG_DATA_DIRS:-}"
+ if [[ -z "$data_dirs" ]]; then
+ data_dirs="/usr/local/share:/usr/share"
+ else
+ if [[ ":$data_dirs:" != *":/usr/local/share:"* ]]; then
+ data_dirs="/usr/local/share:$data_dirs"
+ fi
+ if [[ ":$data_dirs:" != *":/usr/share:"* ]]; then
+ data_dirs="$data_dirs:/usr/share"
+ fi
+ fi
+ export XDG_DATA_DIRS="$data_dirs"
+}
start_portal_binary() {
local description="$1"
@@ -38,29 +90,74 @@ start_portal_binary() {
echo "Warning: no $description binary found (checked: $*)" >&2
return 1
}
-if ! is_ubuntu_family; then
- exit 0
-fi
+stop_portal_processes() {
+ kill_quietly xdg-desktop-portal-hyprland
+ kill_quietly xdg-desktop-portal-wlr
+ kill_quietly xdg-desktop-portal-gnome
+ kill_quietly xdg-desktop-portal-gtk
+ kill_quietly xdg-desktop-portal
+}
+
+restart_portal_via_systemd() {
+ command -v systemctl >/dev/null 2>&1 || return 1
+ ensure_portal_env
+ if command -v dbus-update-activation-environment >/dev/null 2>&1; then
+ dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP XDG_SESSION_DESKTOP XDG_SESSION_TYPE XDG_DATA_DIRS GSETTINGS_SCHEMA_DIR >/dev/null 2>&1 || true
+ fi
+
+ systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP XDG_SESSION_DESKTOP XDG_SESSION_TYPE XDG_DATA_DIRS GSETTINGS_SCHEMA_DIR >/dev/null 2>&1 || true
+ systemctl --user stop xdg-desktop-portal.service xdg-desktop-portal-hyprland.service xdg-desktop-portal-gtk.service >/dev/null 2>&1 || true
+ stop_portal_processes
+ sleep 0.5
+ systemctl --user reset-failed xdg-desktop-portal-hyprland.service xdg-desktop-portal.service xdg-desktop-portal-gtk.service >/dev/null 2>&1 || true
+ systemctl --user start graphical-session.target >/dev/null 2>&1 || true
+
+ for _ in $(seq 1 30); do
+ if systemctl --user is-active --quiet graphical-session.target; then
+ break
+ fi
+ sleep 0.1
+ done
+
+ systemctl --user start xdg-desktop-portal-hyprland.service >/dev/null 2>&1 || true
+ if is_ubuntu_family; then
+ systemctl --user start xdg-desktop-portal-gtk.service >/dev/null 2>&1 || true
+ fi
-sleep 1
-kill_quietly xdg-desktop-portal-hyprland
-kill_quietly xdg-desktop-portal-wlr
-kill_quietly xdg-desktop-portal-gnome
-kill_quietly xdg-desktop-portal-gtk
-kill_quietly xdg-desktop-portal
-sleep 1
+ for _ in $(seq 1 60); do
+ if systemctl --user is-active --quiet xdg-desktop-portal-hyprland.service; then
+ return 0
+ fi
+ sleep 0.1
+ done
+ return 1
+}
-start_portal_binary "xdg-desktop-portal-hyprland" \
- /usr/lib/xdg-desktop-portal-hyprland \
- /usr/libexec/xdg-desktop-portal-hyprland
+restart_portal_manually() {
+ sleep 1
+ stop_portal_processes
+ sleep 1
-sleep 2
+ start_portal_binary "xdg-desktop-portal-hyprland" \
+ /usr/lib/xdg-desktop-portal-hyprland \
+ /usr/libexec/xdg-desktop-portal-hyprland
-start_portal_binary "xdg-desktop-portal-gtk" \
- /usr/lib/xdg-desktop-portal-gtk \
- /usr/libexec/xdg-desktop-portal-gtk
+ sleep 2
-start_portal_binary "xdg-desktop-portal" \
- /usr/lib/xdg-desktop-portal \
- /usr/libexec/xdg-desktop-portal
+ if is_ubuntu_family; then
+ start_portal_binary "xdg-desktop-portal-gtk" \
+ /usr/lib/xdg-desktop-portal-gtk \
+ /usr/libexec/xdg-desktop-portal-gtk || true
+ fi
+
+ start_portal_binary "xdg-desktop-portal" \
+ /usr/lib/xdg-desktop-portal \
+ /usr/libexec/xdg-desktop-portal
+}
+wait_for_wayland || true
+if command -v systemctl >/dev/null 2>&1; then
+ restart_portal_via_systemd || true
+else
+ restart_portal_manually
+fi
diff --git a/config/hypr/scripts/PortalHyprlandUbuntu.sh b/config/hypr/scripts/PortalHyprlandUbuntu.sh
index 86e1a6d3..79762a84 100755
--- a/config/hypr/scripts/PortalHyprlandUbuntu.sh
+++ b/config/hypr/scripts/PortalHyprlandUbuntu.sh
@@ -17,8 +17,8 @@ if [[ -r /etc/os-release ]]; then
|| "${ID:-}" == "zorin" \
|| "${ID:-}" == "rhino" \
|| "${ID_LIKE:-}" == *ubuntu* ]]; then
- if [[ -x "$HOME/.config/hypr/scripts/PortalHyprland.sh" ]]; then
- "$HOME/.config/hypr/scripts/PortalHyprland.sh"
+ if [[ -x "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/PortalHyprland.sh" ]]; then
+ "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/PortalHyprland.sh"
fi
fi
fi
diff --git a/config/hypr/scripts/Refresh.sh b/config/hypr/scripts/Refresh.sh
index 1b043705..ed8c4a0c 100755
--- a/config/hypr/scripts/Refresh.sh
+++ b/config/hypr/scripts/Refresh.sh
@@ -7,8 +7,8 @@
# ==================================================
# Scripts for refreshing ags, waybar, rofi, swaync, wallust
-SCRIPTSDIR=$HOME/.config/hypr/scripts
-UserScripts=$HOME/.config/hypr/UserScripts
+SCRIPTSDIR=${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts
+UserScripts=${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserScripts
# Define file_exists function
file_exists() {
diff --git a/config/hypr/scripts/RefreshNoWaybar.sh b/config/hypr/scripts/RefreshNoWaybar.sh
index e92780b1..c9e7464e 100755
--- a/config/hypr/scripts/RefreshNoWaybar.sh
+++ b/config/hypr/scripts/RefreshNoWaybar.sh
@@ -10,8 +10,8 @@
# Used by automatic wallpaper change
# Modified inorder to refresh rofi background, Wallust, SwayNC only
-SCRIPTSDIR=$HOME/.config/hypr/scripts
-UserScripts=$HOME/.config/hypr/UserScripts
+SCRIPTSDIR=${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts
+UserScripts=${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserScripts
# Define file_exists function
file_exists() {
diff --git a/config/hypr/scripts/RofiEmoji.sh b/config/hypr/scripts/RofiEmoji.sh
index 539a03b6..65463abc 100755
--- a/config/hypr/scripts/RofiEmoji.sh
+++ b/config/hypr/scripts/RofiEmoji.sh
@@ -7,7 +7,7 @@
# ==================================================
# Variables
-rofi_theme="$HOME/.config/rofi/config-emoji.rasi"
+rofi_theme="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-emoji.rasi"
msg='** note ** 👀 Click or Return to choose || Ctrl V to Paste'
# Check if rofi is already running
diff --git a/config/hypr/scripts/RofiFocusedWallpaperLink.sh b/config/hypr/scripts/RofiFocusedWallpaperLink.sh
new file mode 100755
index 00000000..c0f8d64a
--- /dev/null
+++ b/config/hypr/scripts/RofiFocusedWallpaperLink.sh
@@ -0,0 +1,180 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Resolve focused-monitor wallpaper and refresh rofi focused wallpaper link.
+
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
+ROFI_FOCUSED_LINK="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/.current_wallpaper_focused"
+ROFI_GLOBAL_LINK="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/.current_wallpaper"
+WALLPAPER_CURRENT="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_current"
+
+# shellcheck source=/dev/null
+. "$SCRIPTSDIR/WallpaperCmd.sh" 2>/dev/null || true
+
+read_cached_wallpaper() {
+ local cache_file="$1"
+ [[ -f "$cache_file" ]] || return 1
+ awk 'NF && $0 !~ /^filter/ {print; exit}' "$cache_file"
+}
+
+read_wallpaper_from_query() {
+ local monitor="$1"
+ [[ -n "$monitor" ]] || return 1
+ [[ -n "${WWW_CMD:-}" ]] || return 1
+ command -v "$WWW_CMD" >/dev/null 2>&1 || return 1
+ "$WWW_CMD" query 2>/dev/null | awk -v mon="$monitor" '
+ {
+ line=$0
+ sub(/^Monitor[[:space:]]+/, "", line)
+ sub(/^:[[:space:]]*/, "", line)
+ mon_name=line
+ sub(/:.*/, "", mon_name)
+ gsub(/^[[:space:]]+|[[:space:]]+$/, "", mon_name)
+ if (mon_name != mon) next
+
+ path=line
+ sub(/^.*image:[[:space:]]*/, "", path)
+ gsub(/^[[:space:]]+|[[:space:]]+$/, "", path)
+ if (path != line && length(path) > 0) {
+ print path
+ exit
+ }
+ }
+ '
+}
+
+resolve_link_or_file() {
+ local path="$1"
+ local resolved=""
+ if [[ -L "$path" ]]; then
+ resolved="$(readlink -f "$path" 2>/dev/null || true)"
+ if [[ -n "$resolved" && -f "$resolved" ]]; then
+ printf '%s\n' "$resolved"
+ return 0
+ fi
+ fi
+ if [[ -f "$path" ]]; then
+ printf '%s\n' "$path"
+ return 0
+ fi
+ return 1
+}
+
+get_active_workspace_monitor() {
+ command -v hyprctl >/dev/null 2>&1 || return 1
+ if command -v jq >/dev/null 2>&1; then
+ hyprctl activeworkspace -j 2>/dev/null | jq -r '.monitor // empty' | head -n1
+ else
+ hyprctl monitors 2>/dev/null | awk '/^Monitor/{name=$2} /focused: yes/{print name; exit}'
+ fi
+}
+
+get_focused_monitor() {
+ command -v hyprctl >/dev/null 2>&1 || return 1
+ if command -v jq >/dev/null 2>&1; then
+ hyprctl monitors -j 2>/dev/null | jq -r '.[] | select(.focused) | .name' | head -n1
+ else
+ hyprctl monitors 2>/dev/null | awk '/^Monitor/{name=$2} /focused: yes/{print name; exit}'
+ fi
+}
+
+monitor_exists() {
+ local monitor="$1"
+ [[ -n "$monitor" ]] || return 1
+ command -v hyprctl >/dev/null 2>&1 || return 1
+ if command -v jq >/dev/null 2>&1; then
+ hyprctl monitors -j 2>/dev/null | jq -r --arg mon "$monitor" '.[] | select(.name == $mon) | .name' | grep -qx "$monitor"
+ else
+ hyprctl monitors 2>/dev/null | awk '/^Monitor/{print $2}' | grep -qx "$monitor"
+ fi
+}
+
+resolve_target_monitor() {
+ local monitor=""
+ monitor="$(get_active_workspace_monitor 2>/dev/null || true)"
+ if monitor_exists "$monitor"; then
+ printf '%s\n' "$monitor"
+ return 0
+ fi
+ monitor="$(get_focused_monitor 2>/dev/null || true)"
+ if [[ -n "$monitor" ]]; then
+ printf '%s\n' "$monitor"
+ return 0
+ fi
+ return 1
+}
+
+read_wallpaper_from_cache() {
+ local monitor="$1"
+ local cache_root="${WWW_CACHE_DIR:-$HOME/.cache/awww}"
+ local cache_file="$cache_root/$monitor"
+ local fallback_cache=""
+ local path=""
+
+ case "$cache_root" in
+ "$HOME/.cache/awww")
+ fallback_cache="$HOME/.cache/swww/$monitor"
+ ;;
+ "$HOME/.cache/swww")
+ fallback_cache="$HOME/.cache/awww/$monitor"
+ ;;
+ esac
+
+ path="$(read_cached_wallpaper "$cache_file" 2>/dev/null || true)"
+ if [[ -z "$path" && -n "$fallback_cache" ]]; then
+ path="$(read_cached_wallpaper "$fallback_cache" 2>/dev/null || true)"
+ fi
+ [[ -n "$path" && -f "$path" ]] || return 1
+ printf '%s\n' "$path"
+}
+
+resolve_focused_wallpaper() {
+ local monitor="$1"
+ local path=""
+ local per_monitor_link=""
+ local per_monitor_current=""
+
+ if [[ -n "$monitor" ]]; then
+ per_monitor_link="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/.current_wallpaper_${monitor}"
+ per_monitor_current="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_current_${monitor}"
+
+ path="$(read_wallpaper_from_query "$monitor" 2>/dev/null || true)"
+ if [[ -z "$path" ]]; then
+ path="$(resolve_link_or_file "$per_monitor_link" 2>/dev/null || true)"
+ fi
+ if [[ -z "$path" ]]; then
+ path="$(resolve_link_or_file "$per_monitor_current" 2>/dev/null || true)"
+ fi
+ if [[ -z "$path" ]]; then
+ path="$(read_wallpaper_from_cache "$monitor" 2>/dev/null || true)"
+ fi
+ fi
+
+ if [[ -z "$path" ]]; then
+ path="$(resolve_link_or_file "$ROFI_GLOBAL_LINK" 2>/dev/null || true)"
+ fi
+ if [[ -z "$path" ]]; then
+ path="$(resolve_link_or_file "$WALLPAPER_CURRENT" 2>/dev/null || true)"
+ fi
+
+ [[ -n "$path" && -f "$path" ]] || return 1
+ printf '%s\n' "$path"
+}
+
+main() {
+ local target_monitor=""
+ local wallpaper_path=""
+
+ target_monitor="$(resolve_target_monitor 2>/dev/null || true)"
+ wallpaper_path="$(resolve_focused_wallpaper "$target_monitor" 2>/dev/null || true)"
+ [[ -n "$wallpaper_path" && -f "$wallpaper_path" ]] || exit 1
+
+ mkdir -p "$(dirname "$ROFI_FOCUSED_LINK")"
+ ln -sf "$wallpaper_path" "$ROFI_FOCUSED_LINK"
+}
+
+main "$@"
diff --git a/config/hypr/scripts/RofiSearch.sh b/config/hypr/scripts/RofiSearch.sh
index 42b54d75..05520ed0 100755
--- a/config/hypr/scripts/RofiSearch.sh
+++ b/config/hypr/scripts/RofiSearch.sh
@@ -8,7 +8,7 @@
# For Searching via web browsers
# Define the path to the config file
-config_file=$HOME/.config/hypr/UserConfigs/01-UserDefaults.conf
+config_file=${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserConfigs/01-UserDefaults.conf
if ! command -v jq >/dev/null 2>&1; then
notify-send -u low "Rofi Search" "jq is required for URL encoding. Please install jq."
exit 1
@@ -33,7 +33,7 @@ if [[ -z "$Search_Engine" ]]; then
fi
# Rofi theme and message
-rofi_theme="$HOME/.config/rofi/config-search.rasi"
+rofi_theme="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-search.rasi"
msg='‼️ **note** ‼️ search via default web browser'
# Kill Rofi if already running before execution
diff --git a/config/hypr/scripts/RofiThemeSelector-modified.sh b/config/hypr/scripts/RofiThemeSelector-modified.sh
index 535b7313..9dfafba1 100755
--- a/config/hypr/scripts/RofiThemeSelector-modified.sh
+++ b/config/hypr/scripts/RofiThemeSelector-modified.sh
@@ -5,12 +5,12 @@
# License: GNU GPLv3
# SPDX-License-Identifier: GPL-3.0-or-later
# ==================================================
-# A modified version of Rofi-Theme-Selector, concentrating only on ~/.local and also, applying only 10 @themes in ~/.config/rofi/config.rasi
+# A modified version of Rofi-Theme-Selector, concentrating only on ~/.local and also, applying only 10 @themes in ${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config.rasi
# as opposed to continous adding of //@theme
# This code is released in public domain by Dave Davenport <qball@gmpclient.org>
-iDIR="$HOME/.config/swaync/images"
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images"
OS="linux"
@@ -42,7 +42,7 @@ fi
TMP_CONFIG_FILE=$(${MKTEMP}).rasi
#rofi_theme_dir="${HOME}/.local/share/rofi/themes"
-rofi_config_file="${XDG_CONFIG_HOME:-${HOME}/.config}/rofi/config.rasi"
+rofi_config_file="${XDG_CONFIG_HOME:-${XDG_CONFIG_HOME:-$HOME/.config}}/rofi/config.rasi"
##
# Array with parts to the found themes.
@@ -57,7 +57,7 @@ declare -a theme_names
##
# Find themes in defined directories
find_themes() {
- directories=("$HOME/.local/share/rofi/themes" "$HOME/.config/rofi/themes")
+ directories=("$HOME/.local/share/rofi/themes" "${XDG_CONFIG_HOME:-$HOME/.config}/rofi/themes")
for TD in "${directories[@]}"; do
if [ -d "$TD" ]; then
@@ -86,8 +86,8 @@ add_theme_to_config() {
# Determine the correct path for the theme
if [[ -f "$HOME/.local/share/rofi/themes/$theme_name.rasi" ]]; then
theme_path="$HOME/.local/share/rofi/themes/$theme_name.rasi"
- elif [[ -f "$HOME/.config/rofi/themes/$theme_name.rasi" ]]; then
- theme_path="$HOME/.config/rofi/themes/$theme_name.rasi"
+ elif [[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/rofi/themes/$theme_name.rasi" ]]; then
+ theme_path="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/themes/$theme_name.rasi"
else
echo "Theme not found: $theme_name"
return 1
diff --git a/config/hypr/scripts/RofiThemeSelector.sh b/config/hypr/scripts/RofiThemeSelector.sh
index db723b6f..1841b4f5 100755
--- a/config/hypr/scripts/RofiThemeSelector.sh
+++ b/config/hypr/scripts/RofiThemeSelector.sh
@@ -8,11 +8,11 @@
# Rofi Themes - Script to preview and apply themes by live-reloading the config.
# --- Configuration ---
-ROFI_THEMES_DIR_CONFIG="$HOME/.config/rofi/themes"
+ROFI_THEMES_DIR_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/themes"
ROFI_THEMES_DIR_LOCAL="$HOME/.local/share/rofi/themes"
-ROFI_CONFIG_FILE="$HOME/.config/rofi/config.rasi"
-ROFI_THEME_FOR_THIS_SCRIPT="$HOME/.config/rofi/config-rofi-theme.rasi" # A separate rofi theme for the picker itself
-IDIR="$HOME/.config/swaync/images" # For notifications
+ROFI_CONFIG_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config.rasi"
+ROFI_THEME_FOR_THIS_SCRIPT="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-rofi-theme.rasi" # A separate rofi theme for the picker itself
+IDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images" # For notifications
# --- Helper Functions ---
diff --git a/config/hypr/scripts/ScreenShot.sh b/config/hypr/scripts/ScreenShot.sh
index baad89a1..ed914552 100755
--- a/config/hypr/scripts/ScreenShot.sh
+++ b/config/hypr/scripts/ScreenShot.sh
@@ -13,9 +13,9 @@ PICTURES_DIR="$(xdg-user-dir PICTURES 2>/dev/null || echo "$HOME/Pictures")"
dir="$PICTURES_DIR/Screenshots"
file="Screenshot_${time}_${RANDOM}.png"
-iDIR="$HOME/.config/swaync/icons"
-iDoR="$HOME/.config/swaync/images"
-sDIR="$HOME/.config/hypr/scripts"
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/icons"
+iDoR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images"
+sDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
active_window_class=$(hyprctl -j activewindow | jq -r '(.class)')
active_window_file="Screenshot_${time}_${active_window_class}.png"
diff --git a/config/hypr/scripts/ScrollCycleColumnWidth.sh b/config/hypr/scripts/ScrollCycleColumnWidth.sh
new file mode 100755
index 00000000..c9ab2668
--- /dev/null
+++ b/config/hypr/scripts/ScrollCycleColumnWidth.sh
@@ -0,0 +1,56 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+if ! command -v hyprctl >/dev/null 2>&1; then
+ exit 0
+fi
+
+if ! command -v jq >/dev/null 2>&1; then
+ exit 0
+fi
+
+workspace_json="$(hyprctl -j activeworkspace 2>/dev/null || true)"
+layout_name="$(jq -r '.tiledLayout // .tiled_layout // empty' <<<"$workspace_json")"
+
+if [[ "$layout_name" != "scrolling" ]]; then
+ exit 0
+fi
+
+window_json="$(hyprctl -j activewindow 2>/dev/null || true)"
+column_width="$(jq -r '.layout.column.width // .layout.column // empty' <<<"$window_json")"
+window_monitor="$(jq -r '.monitor // empty' <<<"$window_json")"
+window_width="$(jq -r '.size[0] // empty' <<<"$window_json")"
+
+if [[ -n "$column_width" && "$column_width" != "null" ]]; then
+ if ! awk -v v="$column_width" 'BEGIN { exit !(v > 0 && v <= 1.0) }'; then
+ column_width=""
+ fi
+fi
+
+if [[ -z "$column_width" || "$column_width" == "null" ]]; then
+ monitors_json="$(hyprctl -j monitors 2>/dev/null || true)"
+ monitor_width="$(jq -r --arg id "$window_monitor" '.[] | select((.id | tostring) == $id) | .width' <<<"$monitors_json" 2>/dev/null | head -n1)"
+ if [[ -n "$window_width" && -n "$monitor_width" && "$window_width" != "null" && "$monitor_width" != "null" ]]; then
+ column_width="$(awk -v w="$window_width" -v mw="$monitor_width" 'BEGIN { if (w > 0 && mw > 0) printf "%.6f", (w / mw); }')"
+ fi
+fi
+
+if [[ -z "$column_width" || "$column_width" == "null" ]]; then
+ exit 0
+fi
+
+presets=(0.25 0.33 0.5 0.66 0.75 1.0)
+closest_idx=0
+best_diff=""
+
+for idx in "${!presets[@]}"; do
+ preset="${presets[$idx]}"
+ diff="$(awk -v a="$preset" -v b="$column_width" 'BEGIN { d = a - b; if (d < 0) d = -d; printf "%.12f", d }')"
+ if [[ -z "$best_diff" ]] || awk -v d="$diff" -v b="$best_diff" 'BEGIN { exit !(d < b) }'; then
+ best_diff="$diff"
+ closest_idx="$idx"
+ fi
+done
+
+next_idx=$(( (closest_idx + 1) % ${#presets[@]} ))
+hyprctl dispatch layoutmsg "colresize ${presets[$next_idx]}" >/dev/null 2>&1 || true
diff --git a/config/hypr/scripts/ScrollMaximizeToggle.sh b/config/hypr/scripts/ScrollMaximizeToggle.sh
new file mode 100755
index 00000000..29c06eb4
--- /dev/null
+++ b/config/hypr/scripts/ScrollMaximizeToggle.sh
@@ -0,0 +1,175 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+if ! command -v hyprctl >/dev/null 2>&1; then
+ exit 1
+fi
+dispatch_ok() {
+ local dispatcher="$1"
+ shift
+ local output=""
+ case "$dispatcher" in
+ fullscreen)
+ if [[ "${1:-}" == "1" ]]; then
+ output="$(hyprctl dispatch 'hl.dsp.window.fullscreen({ mode = "maximized" })' 2>&1 || true)"
+ else
+ output="$(hyprctl dispatch 'hl.dsp.window.fullscreen({ mode = "fullscreen" })' 2>&1 || true)"
+ fi
+ ;;
+ layoutmsg)
+ local msg="${1:-}"
+ msg="${msg//\\/\\\\}"
+ msg="${msg//\"/\\\"}"
+ output="$(hyprctl dispatch "hl.dsp.layout(\"${msg}\")" 2>&1 || true)"
+ ;;
+ *)
+ output="$(hyprctl dispatch "$dispatcher" "$@" 2>&1 || true)"
+ ;;
+ esac
+ local normalized=""
+ normalized="$(printf '%s' "$output" | tr -d '\r\n')"
+ [[ -z "$normalized" || "$normalized" == "ok" ]]
+}
+
+if ! command -v jq >/dev/null 2>&1; then
+ dispatch_ok fullscreen 1 >/dev/null 2>&1 || true
+ exit 0
+fi
+
+run_layoutmsg() {
+ local msg="$1"
+ dispatch_ok layoutmsg "$msg"
+}
+toggle_maximize() {
+ local active_window_json="$1"
+ local fullscreen_state=""
+ fullscreen_state="$(jq -r '
+ (.fullscreen // .fullscreenClient // 0) as $value
+ | if ($value | type) == "boolean" then
+ (if $value then 1 else 0 end)
+ elif ($value | type) == "number" then
+ $value
+ elif ($value | type) == "string" then
+ ($value | tonumber? // 0)
+ else
+ 0
+ end
+ ' <<<"$active_window_json" 2>/dev/null || true)"
+ if [[ -n "$fullscreen_state" && "$fullscreen_state" != "null" ]] && awk -v v="$fullscreen_state" 'BEGIN { exit !(v > 0) }'; then
+ dispatch_ok fullscreen 1 >/dev/null 2>&1 || true
+ return 0
+ fi
+ return 1
+}
+
+workspace_json="$(hyprctl -j activeworkspace 2>/dev/null || true)"
+layout_name="$(jq -r '.tiledLayout // .tiled_layout // empty' <<<"$workspace_json")"
+
+if [[ "$layout_name" != "scrolling" ]]; then
+ dispatch_ok fullscreen 1 >/dev/null 2>&1 || true
+ exit 0
+fi
+
+window_json="$(hyprctl -j activewindow 2>/dev/null || true)"
+if [[ -z "$window_json" || "$window_json" == "null" ]]; then
+ exit 0
+fi
+if toggle_maximize "$window_json"; then
+ exit 0
+fi
+
+window_address="$(jq -r '.address // empty' <<<"$window_json")"
+window_width="$(jq -r '.size[0] // empty' <<<"$window_json")"
+column_width="$(jq -r '
+ .layout.column as $col
+ | if ($col | type) == "number" then $col
+ elif ($col | type) == "object" then ($col.width // empty)
+ elif ($col | type) == "string" then ($col | tonumber? // empty)
+ else empty
+ end
+' <<<"$window_json")"
+if [[ -n "$column_width" && "$column_width" != "null" ]]; then
+ if ! awk -v v="$column_width" 'BEGIN { exit !(v > 0 && v <= 1.0) }'; then
+ column_width=""
+ fi
+fi
+
+if [[ -z "$window_address" || -z "$window_width" || "$window_width" == "null" ]]; then
+ dispatch_ok fullscreen 1 >/dev/null 2>&1 || true
+ exit 0
+fi
+
+runtime_dir="${XDG_RUNTIME_DIR:-/tmp}"
+state_dir="${runtime_dir}/hypr"
+state_file="${state_dir}/scrolling-maximize-state.json"
+mkdir -p "$state_dir"
+
+if [[ ! -s "$state_file" ]]; then
+ printf '{}\n' > "$state_file"
+elif ! jq -e . "$state_file" >/dev/null 2>&1; then
+ printf '{}\n' > "$state_file"
+fi
+
+saved_width="$(jq -r --arg key "$window_address" '
+ .[$key] as $saved
+ | if ($saved | type) == "number" then $saved
+ elif ($saved | type) == "object" then ($saved.width // empty)
+ elif ($saved | type) == "string" then ($saved | tonumber? // empty)
+ else empty
+ end
+' "$state_file" 2>/dev/null || true)"
+tmp_file="$(mktemp "${state_file}.XXXXXX")"
+cleanup() {
+ rm -f "$tmp_file"
+}
+trap cleanup EXIT
+
+if [[ -n "$saved_width" && "$saved_width" != "null" ]]; then
+ restored=0
+ if run_layoutmsg "colresize ${saved_width}"; then
+ restored=1
+ elif run_layoutmsg "colresize exact ${saved_width}"; then
+ restored=1
+ fi
+ if [[ "$restored" -eq 1 ]]; then
+ jq --arg key "$window_address" 'del(.[$key])' "$state_file" > "$tmp_file"
+ mv "$tmp_file" "$state_file"
+ fi
+ trap - EXIT
+ exit 0
+fi
+if [[ -z "$column_width" || "$column_width" == "null" ]]; then
+ if run_layoutmsg "colresize 1.0"; then
+ max_width=""
+ for _ in 1 2 3 4 5 6; do
+ candidate_width="$(hyprctl -j activewindow 2>/dev/null | jq -r '.size[0] // empty')"
+ if [[ -n "$candidate_width" && "$candidate_width" != "null" ]] && awk -v v="$candidate_width" 'BEGIN { exit !(v > 0) }'; then
+ if [[ -z "$max_width" ]] || awk -v c="$candidate_width" -v m="$max_width" 'BEGIN { exit !(c > m) }'; then
+ max_width="$candidate_width"
+ fi
+ fi
+ sleep 0.05
+ done
+ if [[ -n "$max_width" ]]; then
+ column_width="$(awk -v w="$window_width" -v mw="$max_width" 'BEGIN { if (w > 0 && mw > 0) printf "%.6f", (w / mw); }')"
+ fi
+ else
+ dispatch_ok fullscreen 1 >/dev/null 2>&1 || true
+ trap - EXIT
+ exit 0
+ fi
+ if [[ -z "$column_width" || "$column_width" == "null" ]]; then
+ trap - EXIT
+ exit 0
+ fi
+ jq --arg key "$window_address" --argjson value "$column_width" '. + {($key): $value}' "$state_file" > "$tmp_file"
+ mv "$tmp_file" "$state_file"
+ trap - EXIT
+ exit 0
+fi
+
+jq --arg key "$window_address" --argjson value "$column_width" '. + {($key): $value}' "$state_file" > "$tmp_file"
+mv "$tmp_file" "$state_file"
+trap - EXIT
+
+run_layoutmsg "colresize 1.0" >/dev/null 2>&1 || dispatch_ok fullscreen 1 >/dev/null 2>&1 || true
diff --git a/config/hypr/scripts/Sounds.sh b/config/hypr/scripts/Sounds.sh
index 3af4944f..e763475c 100755
--- a/config/hypr/scripts/Sounds.sh
+++ b/config/hypr/scripts/Sounds.sh
@@ -10,7 +10,7 @@
theme="freedesktop" # Set the theme for the system sounds.
mute=false # Set to true to mute the system sounds.
-directSoundDir="$HOME/.config/hypr/sounds"
+directSoundDir="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/sounds"
# Mute individual sounds here.
muteScreenshots=false
diff --git a/config/hypr/scripts/Tak0-Autodispatch.sh b/config/hypr/scripts/Tak0-Autodispatch.sh
index cabe1672..8eea93ad 100755
--- a/config/hypr/scripts/Tak0-Autodispatch.sh
+++ b/config/hypr/scripts/Tak0-Autodispatch.sh
@@ -72,7 +72,7 @@ fi
echo "=== Deploy '$CMD' → WS $TARGET_WS @ $(date) ===" >>"$LOGFILE"
# Detect active Hyprland config mode
-config_home="${XDG_CONFIG_HOME:-$HOME/.config}"
+config_home="${XDG_CONFIG_HOME:-${XDG_CONFIG_HOME:-$HOME/.config}}"
hypr_dir="$config_home/hypr"
lua_entry="$hypr_dir/hyprland.lua"
legacy_lua_entry="$config_home/hyprland.lua"
diff --git a/config/hypr/scripts/Tak0-Per-Window-Switch.sh b/config/hypr/scripts/Tak0-Per-Window-Switch.sh
index eba3b380..cc878615 100755
--- a/config/hypr/scripts/Tak0-Per-Window-Switch.sh
+++ b/config/hypr/scripts/Tak0-Per-Window-Switch.sh
@@ -19,12 +19,12 @@
##################################################################
MAP_FILE="$HOME/.cache/kb_layout_per_window"
-ICON="$HOME/.config/swaync/images/ja.png"
+ICON="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images/ja.png"
SCRIPT_NAME="$(basename "$0")"
SCRIPT_PATH="$(readlink -f "$0")"
# Detect active Hyprland config mode
-config_home="${XDG_CONFIG_HOME:-$HOME/.config}"
+config_home="${XDG_CONFIG_HOME:-${XDG_CONFIG_HOME:-$HOME/.config}}"
hypr_dir="$config_home/hypr"
lua_entry="$hypr_dir/hyprland.lua"
legacy_lua_entry="$config_home/hyprland.lua"
diff --git a/config/hypr/scripts/ThemeChanger.sh b/config/hypr/scripts/ThemeChanger.sh
index c19908e4..f592300c 100755
--- a/config/hypr/scripts/ThemeChanger.sh
+++ b/config/hypr/scripts/ThemeChanger.sh
@@ -9,8 +9,8 @@ set -euo pipefail
# Wallust v3/v4 compatibility
wallust_args=()
# shellcheck source=/dev/null
-if [ -f "$HOME/.config/hypr/scripts/WallustConfig.sh" ]; then
- . "$HOME/.config/hypr/scripts/WallustConfig.sh"
+if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/WallustConfig.sh" ]; then
+ . "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/WallustConfig.sh"
fi
# SPDX-FileCopyrightText: 2025-present Ahum Maitra theahummaitra@gmail.com
@@ -32,8 +32,12 @@ require rofi
# notify-send is optional
have_notify() { command -v notify-send >/dev/null 2>&1; }
capture_current_layout() {
+ if [ -x "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/ChangeLayout.sh" ]; then
+ "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/ChangeLayout.sh" --no-notify current 2>/dev/null | awk 'NF {print; exit}'
+ return 0
+ fi
if command -v jq >/dev/null 2>&1; then
- hyprctl -j getoption general:layout 2>/dev/null | jq -r '.str // empty'
+ hyprctl -j activeworkspace 2>/dev/null | jq -r '.tiledLayout // .tiled_layout // empty'
else
hyprctl getoption general:layout 2>/dev/null | awk 'NR==1 {print $2}'
fi
@@ -42,13 +46,9 @@ restore_layout_after_reload() {
local layout="$1"
[ -n "$layout" ] || return 0
- if [ -x "$HOME/.config/hypr/scripts/ChangeLayout.sh" ]; then
- if "$HOME/.config/hypr/scripts/ChangeLayout.sh" --no-notify "$layout" >/dev/null 2>&1; then
- return 0
- fi
+ if [ -x "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/ChangeLayout.sh" ]; then
+ "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/ChangeLayout.sh" --no-notify "$layout" >/dev/null 2>&1 || true
fi
-
- hyprctl keyword general:layout "$layout" >/dev/null 2>&1 || true
}
reload_hypr_preserve_layout() {
command -v hyprctl >/dev/null 2>&1 || return 0
@@ -91,9 +91,9 @@ if [ ! -s "$theme_cache" ] || [ "$cache_age" -gt "$cache_max_age" ]; then
fi
ensure_wallust_waybar_style() {
- local waybar_style="$HOME/.config/waybar/style.css"
- local colors_file="$HOME/.config/waybar/wallust/colors-waybar.css"
- local styles_dir="$HOME/.config/waybar/style"
+ local waybar_style="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/style.css"
+ local colors_file="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/wallust/colors-waybar.css"
+ local styles_dir="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/style"
[ -f "$colors_file" ] || return 0
if [ -f "$waybar_style" ] && grep -q 'colors-waybar.css' "$waybar_style"; then
return 0
@@ -119,7 +119,7 @@ reload_running_cava_colors() {
fi
}
-wallust_hypr_colors="$HOME/.config/hypr/wallust/wallust-hyprland.conf"
+wallust_hypr_colors="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallust/wallust-hyprland.conf"
extract_wallust_hex() {
local key="$1"
awk -v key="$key" '
@@ -180,16 +180,16 @@ if wallust "${wallust_args[@]}" theme -- "${choice}" >"$wallust_log" 2>&1; then
# Wait until template targets exist, are newer than start_ts, and are stable (size/mtime stops changing)
# Ensure Ghostty directory exists so Wallust can write target even if Ghostty isn't installed
- mkdir -p "$HOME/.config/ghostty" || true
+ mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/ghostty" || true
targets=(
- "$HOME/.config/waybar/wallust/colors-waybar.css"
- "$HOME/.config/rofi/wallust/colors-rofi.rasi"
- "$HOME/.config/hypr/wallust/wallust-hyprland.conf"
+ "${XDG_CONFIG_HOME:-$HOME/.config}/waybar/wallust/colors-waybar.css"
+ "${XDG_CONFIG_HOME:-$HOME/.config}/rofi/wallust/colors-rofi.rasi"
+ "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallust/wallust-hyprland.conf"
)
# Normalize Ghostty palette syntax in case upstream templates or older targets used ':'
- ghostty_conf="$HOME/.config/ghostty/wallust.conf"
+ ghostty_conf="${XDG_CONFIG_HOME:-$HOME/.config}/ghostty/wallust.conf"
if [ -f "$ghostty_conf" ]; then
sed -i -E 's/^(\s*palette\s*=\s*)([0-9]{1,2}):/\1\2=/' "$ghostty_conf" 2>/dev/null || true
fi
@@ -239,7 +239,7 @@ if wallust "${wallust_args[@]}" theme -- "${choice}" >"$wallust_log" 2>&1; then
# Small cushion before refresh to mirror wallpaper flow
sleep 0.2
# Normalize Rofi selection colors to use the palette's accent (color12)
- rofi_colors="$HOME/.config/rofi/wallust/colors-rofi.rasi"
+ rofi_colors="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/wallust/colors-rofi.rasi"
if [ -f "$rofi_colors" ]; then
accent_hex=$(sed -n 's/^\s*color12:\s*\(#[0-9A-Fa-f]\{6\}\).*/\1/p' "$rofi_colors" | head -n1)
[ -z "$accent_hex" ] && accent_hex=$(sed -n 's/^\s*color13:\s*\(#[0-9A-Fa-f]\{6\}\).*/\1/p' "$rofi_colors" | head -n1)
@@ -258,8 +258,8 @@ if wallust "${wallust_args[@]}" theme -- "${choice}" >"$wallust_log" 2>&1; then
reload_running_cava_colors
# Refresh bars/menus after files are ready
- if [ -x "$HOME/.config/hypr/scripts/Refresh.sh" ]; then
- "$HOME/.config/hypr/scripts/Refresh.sh" >/dev/null 2>&1 || true
+ if [ -x "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/Refresh.sh" ]; then
+ "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/Refresh.sh" >/dev/null 2>&1 || true
else
if command -v waybar-msg >/dev/null 2>&1; then
waybar-msg cmd reload >/dev/null 2>&1 || true
diff --git a/config/hypr/scripts/Toggle-Active-Window-Audio.sh b/config/hypr/scripts/Toggle-Active-Window-Audio.sh
index c954541f..42d63217 100755
--- a/config/hypr/scripts/Toggle-Active-Window-Audio.sh
+++ b/config/hypr/scripts/Toggle-Active-Window-Audio.sh
@@ -7,7 +7,7 @@
# ==================================================
set -euo pipefail
-XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
+XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-${XDG_CONFIG_HOME:-$HOME/.config}}"
swayIconDir="${XDG_CONFIG_HOME}/swaync/icons"
#// Credits to sl1ng for the orginal script. Rewritten by Vyle.
diff --git a/config/hypr/scripts/Toggle-weather-waybar-units.sh b/config/hypr/scripts/Toggle-weather-waybar-units.sh
index abc089ff..bf0b102e 100755
--- a/config/hypr/scripts/Toggle-weather-waybar-units.sh
+++ b/config/hypr/scripts/Toggle-weather-waybar-units.sh
@@ -7,7 +7,7 @@
# ==================================================
# Toggle waybar-weather units between metric and imperial
-CONFIG_FILE="$HOME/.config/waybar-weather/config.toml"
+CONFIG_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/waybar-weather/config.toml"
if [ ! -f "$CONFIG_FILE" ]; then
notify-send "Weather units" "Config not found: $CONFIG_FILE"
diff --git a/config/hypr/scripts/ToggleWaybarTime.sh b/config/hypr/scripts/ToggleWaybarTime.sh
new file mode 100755
index 00000000..2273c3af
--- /dev/null
+++ b/config/hypr/scripts/ToggleWaybarTime.sh
@@ -0,0 +1,101 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Toggle Waybar clock format between 12H and 24H
+
+MODULES_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/Modules"
+notify_swaync() {
+ command -v notify-send >/dev/null 2>&1 || return 0
+ export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
+ local icon="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images/note.png"
+ if [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]; then
+ local bus_path="${XDG_RUNTIME_DIR}/bus"
+ if [ -S "$bus_path" ]; then
+ export DBUS_SESSION_BUS_ADDRESS="unix:path=$bus_path"
+ fi
+ fi
+ DBUS_SESSION_BUS_ADDRESS="$DBUS_SESSION_BUS_ADDRESS" XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" \
+ notify-send -a "Waybar Time" -u low -t 2000 -i "$icon" "$@" >/dev/null 2>&1 || true
+}
+
+if [ ! -f "$MODULES_FILE" ]; then
+ notify_swaync "Modules file not found: $MODULES_FILE"
+ exit 1
+fi
+
+is_12h_active() {
+ grep -qE '^[[:space:]]*"format":[[:space:]]*" {:%I:%M %p}"' "$MODULES_FILE"
+}
+
+apply_12h() {
+ sed -i 's#^\([[:space:]]*\)//\("format": " {:%I:%M %p}".*\)#\1\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)\("format": " {:%H:%M:%S}".*\)#\1//\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)\("format": " {:%H:%M}".*\)#\1//\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)//\("format": "{:%I:%M %p - %d/%b}".*\)#\1\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)\("format": "{:%H:%M - %d/%b}".*\)#\1//\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)//\("format": "{:%B | %a %d, %Y | %I:%M %p}".*\)#\1\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)\("format": "{:%B | %a %d, %Y | %H:%M}".*\)#\1//\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)//\("format": "{:%A, %I:%M %P}".*\)#\1\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)\("format": "{:%a %d | %H:%M}".*\)#\1//\2#' "$MODULES_FILE"
+}
+
+apply_24h() {
+ sed -i 's#^\([[:space:]]*\)\("format": " {:%I:%M %p}".*\)#\1//\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)//\("format": " {:%H:%M:%S}".*\)#\1\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)//\("format": " {:%H:%M}".*\)#\1\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)\("format": "{:%I:%M %p - %d/%b}".*\)#\1//\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)//\("format": "{:%H:%M - %d/%b}".*\)#\1\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)\("format": "{:%B | %a %d, %Y | %I:%M %p}".*\)#\1//\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)//\("format": "{:%B | %a %d, %Y | %H:%M}".*\)#\1\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)\("format": "{:%A, %I:%M %P}".*\)#\1//\2#' "$MODULES_FILE"
+ sed -i 's#^\([[:space:]]*\)//\("format": "{:%a %d | %H:%M}".*\)#\1\2#' "$MODULES_FILE"
+}
+
+restart_waybar() {
+ local manage_with_systemd=0
+
+ if command -v systemctl >/dev/null 2>&1; then
+ if systemctl --user --quiet is-active waybar.service 2>/dev/null || systemctl --user --quiet is-enabled waybar.service 2>/dev/null; then
+ manage_with_systemd=1
+ fi
+ fi
+
+ if [ "$manage_with_systemd" -eq 1 ]; then
+ systemctl --user stop waybar.service >/dev/null 2>&1 || true
+ fi
+
+ pkill -x waybar >/dev/null 2>&1 || true
+ pkill -x '.waybar-wrapped' >/dev/null 2>&1 || true
+ sleep 0.2
+ if pgrep -x waybar >/dev/null 2>&1 || pgrep -x '.waybar-wrapped' >/dev/null 2>&1; then
+ pkill -9 -x waybar >/dev/null 2>&1 || true
+ pkill -9 -x '.waybar-wrapped' >/dev/null 2>&1 || true
+ fi
+ sleep 0.2
+
+ if [ "$manage_with_systemd" -eq 1 ]; then
+ if ! systemctl --user start waybar.service >/dev/null 2>&1; then
+ waybar >/dev/null 2>&1 &
+ fi
+ else
+ waybar >/dev/null 2>&1 &
+ fi
+}
+
+if is_12h_active; then
+ apply_24h
+ mode="24H"
+else
+ apply_12h
+ mode="12H"
+fi
+
+restart_waybar
+sleep 0.3
+
+notify_swaync "Switched to ${mode} format"
+printf 'Waybar Time: switched to %s format\n' "$mode"
diff --git a/config/hypr/scripts/TouchPad.sh b/config/hypr/scripts/TouchPad.sh
index 1042a652..73cbfb46 100755
--- a/config/hypr/scripts/TouchPad.sh
+++ b/config/hypr/scripts/TouchPad.sh
@@ -6,14 +6,14 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# ==================================================
# For disabling touchpad.
-# Edit the Touchpad_Device on ~/.config/hypr/UserConfigs/Laptops.conf according to your system
+# Edit the Touchpad_Device on ${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserConfigs/Laptops.conf according to your system
# use hyprctl devices to get your system touchpad device name
# source https://github.com/hyprwm/Hyprland/discussions/4283?sort=new#discussioncomment-8648109
set -euo pipefail
-notif="$HOME/.config/swaync/images/ja.png"
-laptops_conf="$HOME/.config/hypr/UserConfigs/Laptops.conf"
+notif="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images/ja.png"
+laptops_conf="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserConfigs/Laptops.conf"
touchpad_device="${TOUCHPAD_DEVICE:-}"
if [[ -z "$touchpad_device" && -f "$laptops_conf" ]]; then
diff --git a/config/hypr/scripts/UserConfigsSwitcher.sh b/config/hypr/scripts/UserConfigsSwitcher.sh
index 7d9968a6..6259f363 100755
--- a/config/hypr/scripts/UserConfigsSwitcher.sh
+++ b/config/hypr/scripts/UserConfigsSwitcher.sh
@@ -7,7 +7,7 @@
# ==================================================
# Script to manage UserConfigs and UserConfigsBak
-HYPR_CONFIG_DIR="$HOME/.config/hypr"
+HYPR_CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr"
USER_CONFIGS="$HYPR_CONFIG_DIR/UserConfigs"
USER_CONFIGS_BAK="$HYPR_CONFIG_DIR/UserConfigsBak"
diff --git a/config/hypr/scripts/Volume.sh b/config/hypr/scripts/Volume.sh
index dec7837c..c6ef8873 100755
--- a/config/hypr/scripts/Volume.sh
+++ b/config/hypr/scripts/Volume.sh
@@ -7,8 +7,8 @@
# ==================================================
# Scripts for volume controls for audio and mic
-iDIR="$HOME/.config/swaync/icons"
-sDIR="$HOME/.config/hypr/scripts"
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/icons"
+sDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
# Get Volume
get_volume() {
diff --git a/config/hypr/scripts/WallpaperAutoChange.sh b/config/hypr/scripts/WallpaperAutoChange.sh
new file mode 100755
index 00000000..a12e90d8
--- /dev/null
+++ b/config/hypr/scripts/WallpaperAutoChange.sh
@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# source https://wiki.archlinux.org/title/Hyprland#Using_a_script_to_change_wallpaper_every_X_minutes
+
+# This script will randomly go through the files of a directory, setting it
+# up as the wallpaper at regular intervals
+#
+# NOTE: this script uses bash (not POSIX shell) for the RANDOM variable
+
+wallust_refresh=${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/RefreshNoWaybar.sh
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
+# shellcheck source=/dev/null
+. "$SCRIPTSDIR/WallpaperCmd.sh"
+
+focused_monitor=$(hyprctl monitors | awk '/^Monitor/{name=$2} /focused: yes/{print name}')
+wallpaper_base="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_base_${focused_monitor}"
+
+if [[ $# -lt 1 ]] || [[ ! -d $1 ]]; then
+ echo "Usage:
+ $0 <dir containing images>"
+ exit 1
+fi
+
+# Edit below to control the images transition (swww/awww)
+export SWWW_TRANSITION_FPS=60
+export SWWW_TRANSITION_TYPE=simple
+
+# This controls (in seconds) when to switch to the next image
+INTERVAL=1800
+
+while true; do
+ find "$1" \
+ | while read -r img; do
+ echo "$((RANDOM % 1000)):$img"
+ done \
+ | sort -n | cut -d':' -f2- \
+ | while read -r img; do
+ resize_mode="$(wallpaper_resize_mode "$img" "$focused_monitor")"
+ "$WWW_CMD" img -o "$focused_monitor" --resize "$resize_mode" "$img"
+ mkdir -p "$(dirname "$wallpaper_base")"
+ cp -f "$img" "$wallpaper_base" || true
+ # Regenerate colors from the exact image path to avoid cache races
+ ${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/WallustSwww.sh "$img"
+ # Refresh UI components that depend on wallust output
+ $wallust_refresh
+ sleep $INTERVAL
+
+ done
+done
diff --git a/config/hypr/scripts/WallpaperDaemon.sh b/config/hypr/scripts/WallpaperDaemon.sh
index 60c35a6d..aeb6c397 100755
--- a/config/hypr/scripts/WallpaperDaemon.sh
+++ b/config/hypr/scripts/WallpaperDaemon.sh
@@ -7,7 +7,7 @@
# ==================================================
# Start wallpaper daemon, preferring awww with swww fallback
-SCRIPTSDIR="$HOME/.config/hypr/scripts"
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
# shellcheck source=/dev/null
. "$SCRIPTSDIR/WallpaperCmd.sh"
@@ -21,8 +21,8 @@ for _ in {1..50}; do
sleep 0.1
done
-wallpaper_link="$HOME/.config/rofi/.current_wallpaper"
-wallpaper_current="$HOME/.config/hypr/wallpaper_effects/.wallpaper_current"
+wallpaper_link="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/.current_wallpaper"
+wallpaper_current="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_current"
read_cached_wallpaper() {
local cache_file="$1"
@@ -40,8 +40,8 @@ get_monitors() {
apply_wallpaper_for_monitor() {
local monitor="$1"
- local per_monitor_link="$HOME/.config/rofi/.current_wallpaper_${monitor}"
- local per_monitor_current="$HOME/.config/hypr/wallpaper_effects/.wallpaper_current_${monitor}"
+ local per_monitor_link="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/.current_wallpaper_${monitor}"
+ local per_monitor_current="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_current_${monitor}"
local wallpaper_path=""
# Prefer per-monitor symlink target if valid
diff --git a/config/hypr/scripts/WallpaperEffects.sh b/config/hypr/scripts/WallpaperEffects.sh
new file mode 100755
index 00000000..fc88ba1e
--- /dev/null
+++ b/config/hypr/scripts/WallpaperEffects.sh
@@ -0,0 +1,140 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Wallpaper Effects using ImageMagick (SUPER SHIFT W)
+
+# Variables
+terminal=kitty
+wallpaper_current="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_current"
+wallpaper_output="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_modified"
+wallpaper_base="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_base"
+wallpaper_link="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/.current_wallpaper"
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
+# shellcheck source=/dev/null
+. "$SCRIPTSDIR/WallpaperCmd.sh"
+focused_monitor=$(hyprctl monitors -j | jq -r '.[] | select(.focused) | .name')
+per_monitor_wallpaper_base="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_base_${focused_monitor}"
+per_monitor_wallpaper_current="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_current_${focused_monitor}"
+per_monitor_wallpaper_link="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/.current_wallpaper_${focused_monitor}"
+rofi_theme="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-wallpaper-effect.rasi"
+
+# Directory for swaync
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images"
+iDIRi="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/icons"
+
+# swww/awww transition config
+FPS=60
+TYPE="wipe"
+DURATION=2
+BEZIER=".43,1.19,1,.4"
+if [[ "$WWW_CMD" == "swww" || "$WWW_CMD" == "awww" ]]; then
+ SWWW_PARAMS=(--transition-fps "$FPS" --transition-type "$TYPE" --transition-duration "$DURATION" --transition-bezier "$BEZIER")
+else
+ SWWW_PARAMS=()
+fi
+
+# Define ImageMagick effects
+declare -A effects=(
+ ["No Effects"]="no-effects"
+ ["Black & White"]="magick $wallpaper_base -colorspace gray -sigmoidal-contrast 10,40% $wallpaper_output"
+ ["Blurred"]="magick $wallpaper_base -blur 0x10 $wallpaper_output"
+ ["Charcoal"]="magick $wallpaper_base -charcoal 0x5 $wallpaper_output"
+ ["Edge Detect"]="magick $wallpaper_base -edge 1 $wallpaper_output"
+ ["Emboss"]="magick $wallpaper_base -emboss 0x5 $wallpaper_output"
+ ["Frame Raised"]="magick $wallpaper_base +raise 150 $wallpaper_output"
+ ["Frame Sunk"]="magick $wallpaper_base -raise 150 $wallpaper_output"
+ ["Negate"]="magick $wallpaper_base -negate $wallpaper_output"
+ ["Oil Paint"]="magick $wallpaper_base -paint 4 $wallpaper_output"
+ ["Posterize"]="magick $wallpaper_base -posterize 4 $wallpaper_output"
+ ["Polaroid"]="magick $wallpaper_base -polaroid 0 $wallpaper_output"
+ ["Sepia Tone"]="magick $wallpaper_base -sepia-tone 65% $wallpaper_output"
+ ["Solarize"]="magick $wallpaper_base -solarize 80% $wallpaper_output"
+ ["Sharpen"]="magick $wallpaper_base -sharpen 0x5 $wallpaper_output"
+ ["Vignette"]="magick $wallpaper_base -vignette 0x3 $wallpaper_output"
+ ["Vignette-black"]="magick $wallpaper_base -background black -vignette 0x3 $wallpaper_output"
+ ["Zoomed"]="magick $wallpaper_base -gravity Center -extent 1:1 $wallpaper_output"
+)
+persist_wallpaper_state() {
+ local source_wallpaper="$1"
+ [ -n "$source_wallpaper" ] && [ -f "$source_wallpaper" ] || return 0
+
+ mkdir -p "$(dirname "$wallpaper_current")" "$(dirname "$wallpaper_link")"
+ cp -f "$source_wallpaper" "$wallpaper_current" || true
+ ln -sf "$source_wallpaper" "$wallpaper_link" || true
+
+ if [[ -n "$focused_monitor" ]]; then
+ cp -f "$source_wallpaper" "$per_monitor_wallpaper_current" || true
+ ln -sf "$source_wallpaper" "$per_monitor_wallpaper_link" || true
+ fi
+}
+
+# Function to apply no effects
+no-effects() {
+ local resize_mode
+ resize_mode="$(wallpaper_resize_mode "$wallpaper_base" "$focused_monitor")"
+ "$WWW_CMD" img -o "$focused_monitor" --resize "$resize_mode" "$wallpaper_base" "${SWWW_PARAMS[@]}" || return 1
+ persist_wallpaper_state "$wallpaper_base"
+
+ notify-send -u low -i "$iDIR/ja.png" "No wallpaper" "effects applied"
+ # copying wallpaper for rofi menu
+ cp "$wallpaper_base" "$wallpaper_output"
+}
+
+# Function to run rofi menu
+main() {
+ # Populate rofi menu options
+ options=("No Effects")
+ for effect in "${!effects[@]}"; do
+ [[ "$effect" != "No Effects" ]] && options+=("$effect")
+ done
+
+ choice=$(printf "%s\n" "${options[@]}" | LC_COLLATE=C sort | rofi -dmenu -i -config $rofi_theme)
+
+ # Process user choice
+ if [[ -n "$choice" ]]; then
+ if [[ -f "$per_monitor_wallpaper_base" ]]; then
+ wallpaper_base="$per_monitor_wallpaper_base"
+ fi
+ if [[ ! -f "$wallpaper_base" ]]; then
+ mkdir -p "$(dirname "$wallpaper_base")"
+ cp -f "$wallpaper_current" "$wallpaper_base" || true
+ fi
+ if [[ "$choice" == "No Effects" ]]; then
+ no-effects
+ elif [[ "${effects[$choice]+exists}" ]]; then
+ # Apply selected effect
+ notify-send -u normal -i "$iDIR/ja.png" "Applying:" "$choice effects"
+ if ! eval "${effects[$choice]}"; then
+ notify-send -u critical -i "$iDIR/error.png" "Wallpaper effect failed" "$choice could not be applied"
+ return 1
+ fi
+
+ # intial kill process
+ for pid in swaybg mpvpaper; do
+ killall -SIGUSR1 "$pid" 2>/dev/null || true
+ done
+
+ sleep 1
+ local resize_mode
+ resize_mode="$(wallpaper_resize_mode "$wallpaper_output" "$focused_monitor")"
+ "$WWW_CMD" img -o "$focused_monitor" --resize "$resize_mode" "$wallpaper_output" "${SWWW_PARAMS[@]}"
+ persist_wallpaper_state "$wallpaper_output"
+ notify-send -u low -i "$iDIR/ja.png" "$choice" "effects applied"
+ else
+ echo "Effect '$choice' not recognized."
+ fi
+ fi
+}
+
+# Check if rofi is already running and kill it
+if pidof rofi > /dev/null; then
+ pkill rofi
+fi
+
+main
+
+sleep 1
diff --git a/config/hypr/scripts/WallpaperRandom.sh b/config/hypr/scripts/WallpaperRandom.sh
new file mode 100755
index 00000000..8480295c
--- /dev/null
+++ b/config/hypr/scripts/WallpaperRandom.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Script for Random Wallpaper ( CTRL ALT W)
+
+PICTURES_DIR="$(xdg-user-dir PICTURES 2>/dev/null || echo "$HOME/Pictures")"
+wallDIR="$PICTURES_DIR/wallpapers"
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
+# shellcheck source=/dev/null
+. "$SCRIPTSDIR/WallpaperCmd.sh"
+
+focused_monitor=$(hyprctl monitors -j | jq -r '.[] | select(.focused) | .name')
+wallpaper_base="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_base_${focused_monitor}"
+
+PICS=($(find -L "${wallDIR}" -type f \( -name "*.jpg" -o -name "*.jpeg" -o -name "*.png" -o -name "*.pnm" -o -name "*.tga" -o -name "*.tiff" -o -name "*.webp" -o -name "*.bmp" -o -name "*.farbfeld" -o -name "*.gif" \)))
+RANDOMPICS=${PICS[ $RANDOM % ${#PICS[@]} ]}
+
+
+# Transition config (swww/awww)
+FPS=30
+TYPE="random"
+DURATION=1
+BEZIER=".43,1.19,1,.4"
+if [[ "$WWW_CMD" == "swww" || "$WWW_CMD" == "awww" ]]; then
+ SWWW_PARAMS=(--transition-fps "$FPS" --transition-type "$TYPE" --transition-duration "$DURATION" --transition-bezier "$BEZIER")
+else
+ SWWW_PARAMS=()
+fi
+if ! "$WWW_CMD" query >/dev/null 2>&1; then
+ "$WWW_DAEMON" "${WWW_DAEMON_ARGS[@]}" &
+fi
+resize_mode="$(wallpaper_resize_mode "$RANDOMPICS" "$focused_monitor")"
+"$WWW_CMD" img -o "$focused_monitor" --resize "$resize_mode" "$RANDOMPICS" "${SWWW_PARAMS[@]}"
+
+wait $!
+mkdir -p "$(dirname "$wallpaper_base")"
+cp -f "$RANDOMPICS" "$wallpaper_base" || true
+if ! "$SCRIPTSDIR/WallustSwww.sh" "$RANDOMPICS"; then
+ notify-send -u critical "Wallust failed" "Wallpaper theme not refreshed"
+ exit 1
+fi
+
+wait $!
+sleep 0.5
+"$SCRIPTSDIR/Refresh.sh"
+
diff --git a/config/hypr/scripts/WallpaperSelect.sh b/config/hypr/scripts/WallpaperSelect.sh
new file mode 100755
index 00000000..a1684798
--- /dev/null
+++ b/config/hypr/scripts/WallpaperSelect.sh
@@ -0,0 +1,267 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# This script for selecting wallpapers (SUPER W)
+
+# WALLPAPERS PATH
+terminal=kitty
+PICTURES_DIR="$(xdg-user-dir PICTURES 2>/dev/null || echo "$HOME/Pictures")"
+wallDIR="$PICTURES_DIR/wallpapers"
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
+# shellcheck source=/dev/null
+. "$SCRIPTSDIR/WallpaperCmd.sh"
+wallpaper_current="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_current"
+wallpaper_link="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/.current_wallpaper"
+wallpaper_base="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_base"
+
+# Directory for swaync
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images"
+iDIRi="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/icons"
+
+# swww/awww transition config
+FPS=60
+TYPE="any"
+DURATION=2
+BEZIER=".43,1.19,1,.4"
+if [[ "$WWW_CMD" == "swww" || "$WWW_CMD" == "awww" ]]; then
+ SWWW_PARAMS=(--transition-fps "$FPS" --transition-type "$TYPE" --transition-duration "$DURATION" --transition-bezier "$BEZIER")
+else
+ SWWW_PARAMS=()
+fi
+
+
+# Check if package bc exists
+if ! command -v bc &>/dev/null; then
+ notify-send -i "$iDIR/error.png" "bc missing" "Install package bc first"
+ exit 1
+fi
+
+# Variables
+rofi_theme="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-wallpaper.rasi"
+focused_monitor=$(hyprctl monitors -j | jq -r '.[] | select(.focused) | .name')
+
+per_monitor_wallpaper_current="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_current_${focused_monitor}"
+per_monitor_wallpaper_link="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/.current_wallpaper_${focused_monitor}"
+per_monitor_wallpaper_base="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_base_${focused_monitor}"
+
+# Ensure focused_monitor is detected
+if [[ -z "$focused_monitor" ]]; then
+ notify-send -i "$iDIR/error.png" "E-R-R-O-R" "Could not detect focused monitor"
+ exit 1
+fi
+
+# Monitor details
+scale_factor=$(hyprctl monitors -j | jq -r --arg mon "$focused_monitor" '.[] | select(.name == $mon) | .scale')
+monitor_height=$(hyprctl monitors -j | jq -r --arg mon "$focused_monitor" '.[] | select(.name == $mon) | .height')
+
+icon_size=$(echo "scale=1; ($monitor_height * 3) / ($scale_factor * 150)" | bc)
+adjusted_icon_size=$(echo "$icon_size" | awk '{if ($1 < 15) $1 = 20; if ($1 > 25) $1 = 25; print $1}')
+rofi_override="element-icon{size:${adjusted_icon_size}%;}"
+
+# Kill existing wallpaper daemons for video on the focused monitor only
+kill_wallpaper_for_video() {
+ pkill -f "mpvpaper.*$focused_monitor" 2>/dev/null
+}
+
+# Kill existing wallpaper daemons for image on the focused monitor only
+kill_wallpaper_for_image() {
+ pkill -f "mpvpaper.*$focused_monitor" 2>/dev/null
+}
+
+# Retrieve wallpapers (both images & videos)
+mapfile -d '' PICS < <(find -L "${wallDIR}" -type f \( \
+ -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.gif" -o \
+ -iname "*.bmp" -o -iname "*.tiff" -o -iname "*.webp" -o \
+ -iname "*.mp4" -o -iname "*.mkv" -o -iname "*.mov" -o -iname "*.webm" \) -print0)
+
+RANDOM_PIC="${PICS[$((RANDOM % ${#PICS[@]}))]}"
+RANDOM_PIC_NAME="$(basename "$RANDOM_PIC")"
+
+CURRENT_MON_PIC_PATH=$("$WWW_CMD" query 2>/dev/null | grep "$focused_monitor" | awk '{print $NF}')
+if [[ -z "$CURRENT_MON_PIC_PATH" ]]; then
+ if [[ -L "$wallpaper_link" ]]; then
+ CURRENT_MON_PIC_PATH="$(readlink -f "$wallpaper_link")"
+ elif [[ -f "$wallpaper_link" ]]; then
+ CURRENT_MON_PIC_PATH="$wallpaper_link"
+ elif [[ -f "$wallpaper_current" ]]; then
+ CURRENT_MON_PIC_PATH="$wallpaper_current"
+ fi
+fi
+CURRENT_MON_PIC_NAME=$(basename "$CURRENT_MON_PIC_PATH")
+
+# Rofi command
+rofi_command="rofi -i -show -dmenu -config $rofi_theme -theme-str $rofi_override"
+
+# Sorting Wallpapers
+menu() {
+ IFS=$'\n' sorted_options=($(sort <<<"${PICS[*]}"))
+
+ printf "%s\x00icon\x1f%s\n" "Random: $RANDOM_PIC_NAME" "$RANDOM_PIC"
+ if [[ -n "$CURRENT_MON_PIC_PATH" ]]; then
+ printf "%s\x00icon\x1f%s\n" "Current: $CURRENT_MON_PIC_NAME" "$CURRENT_MON_PIC_PATH"
+ fi
+
+ for pic_path in "${sorted_options[@]}"; do
+ pic_name=$(basename "$pic_path")
+ if [[ "$pic_name" =~ \.gif$ ]]; then
+ cache_gif_image="$HOME/.cache/gif_preview/${pic_name}.png"
+ if [[ ! -f "$cache_gif_image" ]]; then
+ mkdir -p "$HOME/.cache/gif_preview"
+ magick "$pic_path[0]" -resize 1920x1080 "$cache_gif_image"
+ fi
+ printf "%s\x00icon\x1f%s\n" "$pic_name" "$cache_gif_image"
+ elif [[ "$pic_name" =~ \.(mp4|mkv|mov|webm|MP4|MKV|MOV|WEBM)$ ]]; then
+ cache_preview_image="$HOME/.cache/video_preview/${pic_name}.png"
+ if [[ ! -f "$cache_preview_image" ]]; then
+ mkdir -p "$HOME/.cache/video_preview"
+ ffmpeg -v error -y -i "$pic_path" -ss 00:00:01.000 -vframes 1 "$cache_preview_image"
+ fi
+ printf "%s\x00icon\x1f%s\n" "$pic_name" "$cache_preview_image"
+ else
+ printf "%s\x00icon\x1f%s\n" "$pic_name" "$pic_path"
+ fi
+ done
+}
+
+
+modify_startup_config() {
+ local selected_file="$1"
+ local startup_config="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserConfigs/Startup_Apps.conf"
+
+ # Check if it's a live wallpaper (video)
+ if [[ "$selected_file" =~ \.(mp4|mkv|mov|webm)$ ]]; then
+ # For video wallpapers:
+ sed -i '/^\s*exec-once\s*=\s*\$scriptsDir\/WallpaperDaemon\.sh\s*$/s/^/\#/' "$startup_config"
+ sed -i '/^\s*exec-once\s*=\s*swww-daemon\s*--format\s*xrgb\s*$/s/^/\#/' "$startup_config"
+ sed -i '/^\s*#\s*exec-once\s*=\s*mpvpaper\s*.*$/s/^#\s*//;' "$startup_config"
+
+ # Update the livewallpaper variable with the selected video path (using $HOME)
+ selected_file="${selected_file/#$HOME/\$HOME}" # Replace /home/user with $HOME
+ sed -i "s|^\$livewallpaper=.*|\$livewallpaper=\"$selected_file\"|" "$startup_config"
+
+ echo "Configured for live wallpaper (video)."
+ else
+ # For image wallpapers:
+ sed -i '/^\s*#\s*exec-once\s*=\s*\$scriptsDir\/WallpaperDaemon\.sh\s*$/s/^\s*#\s*//;' "$startup_config"
+ sed -i '/^\s*#\s*exec-once\s*=\s*swww-daemon\s*--format\s*xrgb\s*$/s/^\s*#\s*//;' "$startup_config"
+
+ sed -i '/^\s*exec-once\s*=\s*mpvpaper\s*.*$/s/^/\#/' "$startup_config"
+
+ echo "Configured for static wallpaper (image)."
+ fi
+}
+
+# Apply Image Wallpaper
+apply_image_wallpaper() {
+ local image_path="$1"
+
+ kill_wallpaper_for_image
+
+ if ! pgrep -x "$WWW_DAEMON" >/dev/null; then
+ echo "Starting $WWW_DAEMON..."
+ "$WWW_DAEMON" "${WWW_DAEMON_ARGS[@]}" &
+ fi
+ # Wait for daemon to be ready before applying
+ for _ in {1..20}; do
+ "$WWW_CMD" query >/dev/null 2>&1 && break
+ sleep 0.1
+ done
+ local resize_mode
+ resize_mode="$(wallpaper_resize_mode "$image_path" "$focused_monitor")"
+ "$WWW_CMD" img -o "$focused_monitor" --resize "$resize_mode" "$image_path" "${SWWW_PARAMS[@]}" || {
+ sleep 0.2
+ "$WWW_CMD" img -o "$focused_monitor" --resize "$resize_mode" "$image_path" "${SWWW_PARAMS[@]}"
+ }
+ "$WWW_CMD" img -o "$focused_monitor" --resize "$resize_mode" "$image_path" "${SWWW_PARAMS[@]}"
+
+ # Persist per-monitor wallpaper selection
+ mkdir -p "$(dirname "$per_monitor_wallpaper_current")" "$(dirname "$per_monitor_wallpaper_link")"
+ ln -sf "$image_path" "$per_monitor_wallpaper_link" || true
+ cp -f "$image_path" "$per_monitor_wallpaper_current" || true
+ mkdir -p "$(dirname "$per_monitor_wallpaper_base")"
+ cp -f "$image_path" "$per_monitor_wallpaper_base" || true
+ cp -f "$image_path" "$wallpaper_base" || true
+
+ # Run additional scripts (pass the image path to avoid cache race conditions)
+ if ! "$SCRIPTSDIR/WallustSwww.sh" "$image_path"; then
+ notify-send -i "$iDIR/error.png" "Wallust failed" "Wallpaper theme not refreshed"
+ return 1
+ fi
+ sleep 0.5
+ "$SCRIPTSDIR/Refresh.sh"
+ sleep 0.3
+
+}
+
+apply_video_wallpaper() {
+ local video_path="$1"
+
+ # Check if mpvpaper is installed
+ if ! command -v mpvpaper &>/dev/null; then
+ notify-send -i "$iDIR/error.png" "E-R-R-O-R" "mpvpaper not found"
+ return 1
+ fi
+ kill_wallpaper_for_video
+
+ # Apply video wallpaper only to the focused monitor
+ mpvpaper "$focused_monitor" -o "load-scripts=no no-audio --loop" "$video_path" &
+}
+
+# Main function
+main() {
+ choice=$(menu | $rofi_command)
+ choice=$(echo "$choice" | xargs)
+ RANDOM_PIC_NAME=$(echo "$RANDOM_PIC_NAME" | xargs)
+ raw_choice="$choice"
+ choice="${choice#Random: }"
+ choice="${choice#Current: }"
+
+ if [[ -z "$choice" ]]; then
+ echo "No choice selected. Exiting."
+ exit 0
+ fi
+
+ # Resolve selection directly when using Random/Current entries
+ if [[ "$raw_choice" == Random:\ * ]]; then
+ selected_file="$RANDOM_PIC"
+ elif [[ "$raw_choice" == Current:\ * && -n "$CURRENT_MON_PIC_PATH" ]]; then
+ selected_file="$CURRENT_MON_PIC_PATH"
+ elif [[ -f "$choice" ]]; then
+ selected_file="$choice"
+ else
+ # Handle random selection by name when needed
+ if [[ "$choice" == "$RANDOM_PIC_NAME" ]]; then
+ choice=$(basename "$RANDOM_PIC")
+ fi
+ choice_basename=$(basename "$choice" | sed 's/\(.*\)\.[^.]*$/\1/')
+
+ # Search for the selected file in the wallpapers directory, including subdirectories
+ selected_file=$(find "$wallDIR" -iname "$choice_basename.*" -print -quit)
+ fi
+
+ if [[ -z "$selected_file" ]]; then
+ echo "File not found. Selected choice: $choice"
+ exit 1
+ fi
+
+ # Modify the Startup_Apps.conf file based on wallpaper type
+ modify_startup_config "$selected_file"
+
+ # **CHECK FIRST** if it's a video or an image **before calling any function**
+ if [[ "$selected_file" =~ \.(mp4|mkv|mov|webm|MP4|MKV|MOV|WEBM)$ ]]; then
+ apply_video_wallpaper "$selected_file"
+ else
+ apply_image_wallpaper "$selected_file"
+ fi
+}
+
+# Check if rofi is already running
+if pidof rofi >/dev/null; then
+ pkill rofi
+fi
+
+main \ No newline at end of file
diff --git a/config/hypr/scripts/WallustConfig.sh b/config/hypr/scripts/WallustConfig.sh
index 44ddff0b..6605a084 100755
--- a/config/hypr/scripts/WallustConfig.sh
+++ b/config/hypr/scripts/WallustConfig.sh
@@ -8,7 +8,7 @@
# Wallust version compatibility helpers
#
# Purpose:
-# - Wallust v3 reads ~/.config/wallust/wallust.toml (this repo ships a v3 config)
+# - Wallust v3 reads ${XDG_CONFIG_HOME:-$HOME/.config}/wallust/wallust.toml (this repo ships a v3 config)
# - Wallust v4 alpha uses a different config schema; users frequently install it
# via wallust-git, which will fail to parse the v3 config.
#
@@ -31,8 +31,8 @@ wallust_prepare_args() {
# Wallust v4 supports -C/--config-file.
if [ -n "$major" ] && [ "$major" -ge 4 ]; then
- local v4_cfg="$HOME/.config/wallust/wallust-v4.toml"
- local v4_kitty_cfg="$HOME/.config/wallust/wallust-kitty-v4.toml"
+ local v4_cfg="${XDG_CONFIG_HOME:-$HOME/.config}/wallust/wallust-v4.toml"
+ local v4_kitty_cfg="${XDG_CONFIG_HOME:-$HOME/.config}/wallust/wallust-kitty-v4.toml"
if [ -f "$v4_cfg" ]; then
wallust_args=(-C "$v4_cfg")
diff --git a/config/hypr/scripts/WallustSwww.sh b/config/hypr/scripts/WallustSwww.sh
index 3472d519..7807cf4c 100755
--- a/config/hypr/scripts/WallustSwww.sh
+++ b/config/hypr/scripts/WallustSwww.sh
@@ -13,15 +13,19 @@ set -euo pipefail
wallust_args=()
wallust_kitty_args=()
# shellcheck source=/dev/null
-if [ -f "$HOME/.config/hypr/scripts/WallustConfig.sh" ]; then
- . "$HOME/.config/hypr/scripts/WallustConfig.sh"
+if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/WallustConfig.sh" ]; then
+ . "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/WallustConfig.sh"
fi
have_notify() { command -v notify-send >/dev/null 2>&1; }
wallust_log="${XDG_CACHE_HOME:-$HOME/.cache}/wallust/wallust-swww.log"
mkdir -p "$(dirname "$wallust_log")"
capture_current_layout() {
+ if [ -x "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/ChangeLayout.sh" ]; then
+ "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/ChangeLayout.sh" --no-notify current 2>/dev/null | awk 'NF {print; exit}'
+ return 0
+ fi
if command -v jq >/dev/null 2>&1; then
- hyprctl -j getoption general:layout 2>/dev/null | jq -r '.str // empty'
+ hyprctl -j activeworkspace 2>/dev/null | jq -r '.tiledLayout // .tiled_layout // empty'
else
hyprctl getoption general:layout 2>/dev/null | awk 'NR==1 {print $2}'
fi
@@ -30,13 +34,9 @@ restore_layout_after_reload() {
local layout="$1"
[ -n "$layout" ] || return 0
- if [ -x "$HOME/.config/hypr/scripts/ChangeLayout.sh" ]; then
- if "$HOME/.config/hypr/scripts/ChangeLayout.sh" --no-notify "$layout" >/dev/null 2>&1; then
- return 0
- fi
+ if [ -x "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/ChangeLayout.sh" ]; then
+ "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/ChangeLayout.sh" --no-notify "$layout" >/dev/null 2>&1 || true
fi
-
- hyprctl keyword general:layout "$layout" >/dev/null 2>&1 || true
}
reload_hypr_preserve_layout() {
command -v hyprctl >/dev/null 2>&1 || return 0
@@ -49,11 +49,11 @@ reload_hypr_preserve_layout() {
restore_layout_after_reload "$active_layout"
}
ensure_wallust_waybar_style() {
- local waybar_style="$HOME/.config/waybar/style.css"
- local colors_file="$HOME/.config/waybar/wallust/colors-waybar.css"
- local styles_dir="$HOME/.config/waybar/style"
+ local waybar_style="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/style.css"
+ local colors_file="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/wallust/colors-waybar.css"
+ local styles_dir="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/style"
[ -f "$colors_file" ] || return 0
- if [ -f "$waybar_style" ] && grep -q 'colors-waybar.css' "$waybar_style"; then
+ if [ -f "$waybar_style" ]; then
return 0
fi
local candidates=(
@@ -88,8 +88,8 @@ else
cache_dir="$HOME/.cache/swww/"
cache_dir_fallback="$HOME/.cache/awww/"
fi
-rofi_link="$HOME/.config/rofi/.current_wallpaper"
-wallpaper_current="$HOME/.config/hypr/wallpaper_effects/.wallpaper_current"
+rofi_link="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/.current_wallpaper"
+wallpaper_current="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_current"
read_cached_wallpaper() {
local cache_file="$1"
if [[ -f "$cache_file" ]]; then
@@ -163,7 +163,7 @@ mkdir -p "$(dirname "$wallpaper_current")"
cp -f "$wallpaper_path" "$wallpaper_current" || true
# Ensure Ghostty directory exists so Wallust can write target even if Ghostty isn't installed
-mkdir -p "$HOME/.config/ghostty" || true
+mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/ghostty" || true
wait_for_templates() {
local start_ts="$1"
shift
@@ -188,7 +188,7 @@ wait_for_templates() {
return 1
}
-# Run wallust (silent) to regenerate templates defined in ~/.config/wallust/wallust.toml
+# Run wallust (silent) to regenerate templates defined in ${XDG_CONFIG_HOME:-$HOME/.config}/wallust/wallust.toml
# -s is used in this repo to keep things quiet and avoid extra prompts
start_ts=$(date +%s)
if ! wallust "${wallust_args[@]}" run -s "$wallpaper_path" >"$wallust_log" 2>&1; then
@@ -197,9 +197,9 @@ if ! wallust "${wallust_args[@]}" run -s "$wallpaper_path" >"$wallust_log" 2>&1;
exit 1
fi
wallust_targets=(
- "$HOME/.config/waybar/wallust/colors-waybar.css"
- "$HOME/.config/rofi/wallust/colors-rofi.rasi"
- "$HOME/.config/hypr/wallust/wallust-hyprland.conf"
+ "${XDG_CONFIG_HOME:-$HOME/.config}/waybar/wallust/colors-waybar.css"
+ "${XDG_CONFIG_HOME:-$HOME/.config}/rofi/wallust/colors-rofi.rasi"
+ "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallust/wallust-hyprland.conf"
)
if ! wait_for_templates "$start_ts" "${wallust_targets[@]}"; then
have_notify && notify-send -u critical -a WallustSwww \
@@ -210,7 +210,7 @@ ensure_wallust_waybar_style
reload_running_cava_colors
# Normalize Rofi selection colors to a brighter accent and readable foreground
-rofi_colors="$HOME/.config/rofi/wallust/colors-rofi.rasi"
+rofi_colors="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/wallust/colors-rofi.rasi"
if [ -f "$rofi_colors" ]; then
accent_hex=$(sed -n 's/^\s*color13:\s*\(#[0-9A-Fa-f]\{6\}\).*/\1/p' "$rofi_colors" | head -n1)
[ -z "$accent_hex" ] && accent_hex=$(sed -n 's/^\s*color12:\s*\(#[0-9A-Fa-f]\{6\}\).*/\1/p' "$rofi_colors" | head -n1)
@@ -244,7 +244,7 @@ run_wallust_with_config() {
# Legacy fallback for builds that still honor env-based config override.
WALLUST_CONFIG="$cfg" wallust run -s "$wallpaper_path" || true
}
-wallust_hypr_colors="$HOME/.config/hypr/wallust/wallust-hyprland.conf"
+wallust_hypr_colors="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallust/wallust-hyprland.conf"
extract_wallust_hex() {
local key="$1"
awk -v key="$key" '
@@ -274,7 +274,7 @@ apply_hypr_border_fallback() {
}
apply_hypr_gap_fallback() {
- local decorations_lua="$HOME/.config/hypr/UserConfigs/user_decorations.lua"
+ local decorations_lua="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserConfigs/user_decorations.lua"
[ -s "$decorations_lua" ] || return 0
local gaps_in gaps_out border_size
gaps_in="$(sed -n 's/^[[:space:]]*gaps_in[[:space:]]*=[[:space:]]*\([0-9]\+\).*/\1/p' "$decorations_lua" | head -n1)"
@@ -289,9 +289,9 @@ apply_hypr_gap_fallback() {
# Apply Hyprland updates immediately to avoid delayed border/gap changes.
reload_hypr_preserve_layout
-kitty_cfg="$HOME/.config/wallust/wallust-kitty.toml"
+kitty_cfg="${XDG_CONFIG_HOME:-$HOME/.config}/wallust/wallust-kitty.toml"
if [ "${#wallust_kitty_args[@]}" -gt 0 ]; then
- kitty_cfg="$HOME/.config/wallust/wallust-kitty-v4.toml"
+ kitty_cfg="${XDG_CONFIG_HOME:-$HOME/.config}/wallust/wallust-kitty-v4.toml"
fi
(
if [ -f "$kitty_cfg" ]; then
@@ -300,7 +300,7 @@ fi
# Reload kitty colors when wallpaper-based theme is active.
# Use SIGUSR1 directly to avoid extra latency from kitty remote-control calls.
- kitty_wallust_theme="$HOME/.config/kitty/kitty-themes/01-Wallust.conf"
+ kitty_wallust_theme="${XDG_CONFIG_HOME:-$HOME/.config}/kitty/kitty-themes/01-Wallust.conf"
if [ -s "$kitty_wallust_theme" ]; then
if pidof kitty >/dev/null 2>&1; then
for pid in $(pidof kitty); do
@@ -310,13 +310,13 @@ fi
fi
# Normalize Ghostty palette syntax in case ':' was used by older files
- if [ -f "$HOME/.config/ghostty/wallust.conf" ]; then
- sed -i -E 's/^(\s*palette\s*=\s*)([0-9]{1,2}):/\1\2=/' "$HOME/.config/ghostty/wallust.conf" 2>/dev/null || true
+ if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/ghostty/wallust.conf" ]; then
+ sed -i -E 's/^(\s*palette\s*=\s*)([0-9]{1,2}):/\1\2=/' "${XDG_CONFIG_HOME:-$HOME/.config}/ghostty/wallust.conf" 2>/dev/null || true
fi
# Light wait for Ghostty colors file to be present then signal Ghostty to reload (SIGUSR2)
for _ in 1 2 3; do
- [ -s "$HOME/.config/ghostty/wallust.conf" ] && break
+ [ -s "${XDG_CONFIG_HOME:-$HOME/.config}/ghostty/wallust.conf" ] && break
sleep 0.1
done
if pidof ghostty >/dev/null; then
diff --git a/config/hypr/scripts/WaybarLayout.sh b/config/hypr/scripts/WaybarLayout.sh
index 66d45a07..51e93bb3 100755
--- a/config/hypr/scripts/WaybarLayout.sh
+++ b/config/hypr/scripts/WaybarLayout.sh
@@ -10,10 +10,10 @@
IFS=$'\n\t'
# Define directories
-waybar_layouts="$HOME/.config/waybar/configs"
-waybar_config="$HOME/.config/waybar/config"
-SCRIPTSDIR="$HOME/.config/hypr/scripts"
-rofi_config="$HOME/.config/rofi/config-waybar-layout.rasi"
+waybar_layouts="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/configs"
+waybar_config="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/config"
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
+rofi_config="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-waybar-layout.rasi"
msg=' 🎌 NOTE: Some waybar LAYOUT NOT fully compatible with some STYLES'
# Apply selected configuration
diff --git a/config/hypr/scripts/WaybarScripts.sh b/config/hypr/scripts/WaybarScripts.sh
index afb55712..dfd175f1 100755
--- a/config/hypr/scripts/WaybarScripts.sh
+++ b/config/hypr/scripts/WaybarScripts.sh
@@ -5,10 +5,10 @@
# License: GNU GPLv3
# SPDX-License-Identifier: GPL-3.0-or-later
# ==================================================
-# This file used on waybar modules sourcing defaults set in $HOME/.config/hypr/UserConfigs/01-UserDefaults.conf
+# This file used on waybar modules sourcing defaults set in ${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserConfigs/01-UserDefaults.conf
# Define the path to the config file
-config_file=$HOME/.config/hypr/UserConfigs/01-UserDefaults.conf
+config_file=${XDG_CONFIG_HOME:-$HOME/.config}/hypr/UserConfigs/01-UserDefaults.conf
# Check if the config file exists
if [[ ! -f "$config_file" ]]; then
@@ -31,7 +31,7 @@ fi
# Execute accordingly based on the passed argument
launch_files() {
if [[ -z "$files" ]]; then
- notify-send -u low -i "$HOME/.config/swaync/images/error.png" "Waybar: files" "Set \$files in 01-UserDefaults.conf or install a default file manager."
+ notify-send -u low -i "${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images/error.png" "Waybar: files" "Set \$files in 01-UserDefaults.conf or install a default file manager."
return 1
fi
eval "$files &"
diff --git a/config/hypr/scripts/WaybarStyles.sh b/config/hypr/scripts/WaybarStyles.sh
index 611e0a12..ab951e22 100755
--- a/config/hypr/scripts/WaybarStyles.sh
+++ b/config/hypr/scripts/WaybarStyles.sh
@@ -10,10 +10,10 @@
IFS=$'\n\t'
# Define directories
-waybar_styles="$HOME/.config/waybar/style"
-waybar_style="$HOME/.config/waybar/style.css"
-SCRIPTSDIR="$HOME/.config/hypr/scripts"
-rofi_config="$HOME/.config/rofi/config-waybar-style.rasi"
+waybar_styles="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/style"
+waybar_style="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/style.css"
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
+rofi_config="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-waybar-style.rasi"
msg=' 🎌 NOTE: Some waybar STYLES NOT fully compatible with some LAYOUTS'
# Apply selected style
diff --git a/config/hypr/scripts/ZshChangeTheme.sh b/config/hypr/scripts/ZshChangeTheme.sh
new file mode 100755
index 00000000..21049317
--- /dev/null
+++ b/config/hypr/scripts/ZshChangeTheme.sh
@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Script for Oh my ZSH theme ( CTRL SHIFT O)
+
+# preview of theme can be view here: https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
+# after choosing theme, TTY need to be closed and re-open
+
+# Variables
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images"
+rofi_theme="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-zsh-theme.rasi"
+
+if [ -n "$(grep -i nixos < /etc/os-release)" ]; then
+ notify-send -i "$iDIR/note.png" "NOT Supported" "Sorry NixOS does not support this KooL feature"
+ exit 1
+fi
+
+themes_dir="$HOME/.oh-my-zsh/themes"
+file_extension=".zsh-theme"
+
+
+themes_array=($(find -L "$themes_dir" -type f -name "*$file_extension" -exec basename {} \; | sed -e "s/$file_extension//"))
+
+# Add "Random" option to the beginning of the array
+themes_array=("Random" "${themes_array[@]}")
+
+rofi_command="rofi -i -dmenu -config $rofi_theme"
+
+menu() {
+ for theme in "${themes_array[@]}"; do
+ echo "$theme"
+ done
+}
+
+main() {
+ choice=$(menu | ${rofi_command})
+
+ # if nothing selected, script won't change anything
+ if [ -z "$choice" ]; then
+ exit 0
+ fi
+
+ zsh_path="$HOME/.zshrc"
+ var_name="ZSH_THEME"
+
+ if [[ "$choice" == "Random" ]]; then
+ # Pick a random theme from the original themes_array (excluding "Random")
+ random_theme=${themes_array[$((RANDOM % (${#themes_array[@]} - 1) + 1))]}
+ theme_to_set="$random_theme"
+ notify-send -i "$iDIR/ja.png" "Random theme:" "selected: $random_theme"
+ else
+ # Set theme to the selected choice
+ theme_to_set="$choice"
+ notify-send -i "$iDIR/ja.png" "Theme selected:" "$choice"
+ fi
+
+ if [ -f "$zsh_path" ]; then
+ sed -i "s/^$var_name=.*/$var_name=\"$theme_to_set\"/" "$zsh_path"
+ notify-send -i "$iDIR/ja.png" "OMZ theme" "applied. restart your terminal"
+ else
+ notify-send -i "$iDIR/error.png" "E-R-R-O-R" "~.zshrc file not found!"
+ fi
+}
+
+# Check if rofi is already running
+if pidof rofi > /dev/null; then
+ pkill rofi
+fi
+
+main
diff --git a/config/hypr/scripts/fastfetch-wrapper.sh b/config/hypr/scripts/fastfetch-wrapper.sh
index ad5f7873..ea76afff 100755
--- a/config/hypr/scripts/fastfetch-wrapper.sh
+++ b/config/hypr/scripts/fastfetch-wrapper.sh
@@ -6,7 +6,7 @@ SPECIFIC_ID=$ID
FAMILY_ID=$ID_LIKE
# 2. Define your asset directory
-ASSET_DIR="$HOME/.config/fastfetch/images"
+ASSET_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/fastfetch/images"
# 3. Selection Logic
if [ -f "$ASSET_DIR/$SPECIFIC_ID.png" ]; then
diff --git a/config/hypr/scripts/kooldots-add-ssh-agent.sh b/config/hypr/scripts/kooldots-add-ssh-agent.sh
new file mode 100755
index 00000000..56a62437
--- /dev/null
+++ b/config/hypr/scripts/kooldots-add-ssh-agent.sh
@@ -0,0 +1,310 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Adds a user ssh-agent systemd service and wires SSH_AUTH_SOCK into Hyprland.
+
+set -euo pipefail
+
+SCRIPT_NAME="$(basename "$0")"
+CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
+HYPR_DIR="$CONFIG_HOME/hypr"
+USER_CONFIGS_DIR="$HYPR_DIR/UserConfigs"
+ENV_CONF="$USER_CONFIGS_DIR/ENVariables.conf"
+ENV_LUA="$USER_CONFIGS_DIR/user_env.lua"
+SYSTEMD_USER_DIR="$CONFIG_HOME/systemd/user"
+SERVICE_NAME="ssh-agent"
+SERVICE_FILE="$SYSTEMD_USER_DIR/${SERVICE_NAME}.service"
+SSH_CONFIG="$HOME/.ssh/config"
+
+DRY_RUN=0
+ACTION="status"
+SHOW_SYSTEMD_STATUS=0
+SHOW_HELP=0
+
+info() { printf '[INFO] %s\n' "$*"; }
+warn() { printf '[WARN] %s\n' "$*"; }
+step() { printf '[STEP] %s\n' "$*"; }
+
+usage() {
+ cat <<USAGE
+Usage: $SCRIPT_NAME [options]
+
+Options:
+ -h, --help Show help.
+ -d, --dry-run Show what would change without writing files or running systemctl.
+ -s, --status Show installed/config status and systemctl status output.
+ -e, --enable Install/enable the user service.
+ -D, --disable Stop/disable the user service.
+ -r, --remove Disable and remove the user service file.
+
+Notes:
+ --disable has a short flag -D to avoid clashing with -d (dry-run).
+ Set HYPR_CONFIG_MODE=lua|conf|hyprlang|auto to override detection.
+ Keys must be loaded separately (e.g. ssh-add ~/.ssh/id_ed25519). AddKeysToAgent only auto-adds after first use.
+USAGE
+}
+
+ORIGINAL_ARGS=$#
+if [ "$ORIGINAL_ARGS" -eq 0 ]; then
+ SHOW_HELP=1
+ SHOW_SYSTEMD_STATUS=1
+fi
+
+while [ "$#" -gt 0 ]; do
+ case "$1" in
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ -d|--dry-run)
+ DRY_RUN=1
+ ;;
+ -s|--status)
+ ACTION="status"
+ SHOW_SYSTEMD_STATUS=1
+ ;;
+ -e|--enable)
+ ACTION="enable"
+ ;;
+ -D|--disable|--disable-service|--disable)
+ ACTION="disable"
+ ;;
+ -r|--remove)
+ ACTION="remove"
+ ;;
+ *)
+ warn "Unknown option: $1"
+ usage
+ exit 1
+ ;;
+ esac
+ shift
+done
+
+run_cmd() {
+ if [ "$DRY_RUN" -eq 1 ]; then
+ printf '[DRY-RUN] %s\n' "$*"
+ return 0
+ fi
+ "$@"
+}
+
+detect_hypr_config_mode() {
+ local lua_entry="$HYPR_DIR/hyprland.lua"
+ local legacy_lua_entry="$CONFIG_HOME/hyprland.lua"
+ local mode="${HYPR_CONFIG_MODE:-}"
+ if [ -n "$mode" ]; then
+ case "${mode,,}" in
+ lua) echo "lua"; return ;;
+ conf|hyprlang) echo "conf"; return ;;
+ auto) ;;
+ *) ;;
+ esac
+ fi
+ if [ -f "$lua_entry" ] || [ -f "$legacy_lua_entry" ]; then
+ echo "lua"
+ else
+ echo "conf"
+ fi
+}
+
+service_exists() {
+ [ -f "$SERVICE_FILE" ]
+}
+
+systemctl_user() {
+ if ! command -v systemctl >/dev/null 2>&1; then
+ warn "systemctl not found; cannot manage the user service."
+ return 1
+ fi
+ run_cmd systemctl --user "$@"
+}
+
+service_status_summary() {
+ local enabled="unknown"
+ local active="unknown"
+ if command -v systemctl >/dev/null 2>&1; then
+ enabled="$(systemctl --user is-enabled "$SERVICE_NAME" 2>/dev/null || true)"
+ active="$(systemctl --user is-active "$SERVICE_NAME" 2>/dev/null || true)"
+ fi
+ if service_exists; then
+ info "Service file exists: $SERVICE_FILE"
+ else
+ warn "Service file missing: $SERVICE_FILE"
+ fi
+ info "Service enabled: ${enabled:-unknown}"
+ info "Service active: ${active:-unknown}"
+}
+
+env_present_conf() {
+ [ -f "$ENV_CONF" ] && grep -Eq '^[[:space:]]*env[[:space:]]*=[[:space:]]*SSH_AUTH_SOCK,' "$ENV_CONF"
+}
+
+env_present_lua() {
+ [ -f "$ENV_LUA" ] && grep -Eq 'hl\.env\([[:space:]]*["'\'']SSH_AUTH_SOCK["'\'']' "$ENV_LUA"
+}
+
+ensure_env_conf() {
+ if env_present_conf; then
+ info "Hyprland ENV already set in $ENV_CONF"
+ return 0
+ fi
+ step "Adding SSH_AUTH_SOCK to $ENV_CONF"
+ if [ "$DRY_RUN" -eq 1 ]; then
+ printf '[DRY-RUN] append SSH_AUTH_SOCK to %s\n' "$ENV_CONF"
+ return 0
+ fi
+ mkdir -p "$(dirname "$ENV_CONF")"
+ touch "$ENV_CONF"
+ printf '\n# SSH agent socket\nenv = SSH_AUTH_SOCK,$XDG_RUNTIME_DIR/ssh-agent.socket\n' >> "$ENV_CONF"
+}
+
+ensure_env_lua() {
+ if env_present_lua; then
+ info "Hyprland ENV already set in $ENV_LUA"
+ return 0
+ fi
+ step "Adding SSH_AUTH_SOCK to $ENV_LUA"
+ if [ "$DRY_RUN" -eq 1 ]; then
+ printf '[DRY-RUN] append SSH_AUTH_SOCK to %s\n' "$ENV_LUA"
+ return 0
+ fi
+ mkdir -p "$(dirname "$ENV_LUA")"
+ touch "$ENV_LUA"
+ cat <<'LUA' >> "$ENV_LUA"
+
+-- SSH agent socket
+hl.env("SSH_AUTH_SOCK", (os.getenv("XDG_RUNTIME_DIR") or "") .. "/ssh-agent.socket")
+LUA
+}
+
+ensure_ssh_config() {
+ if [ ! -f "$SSH_CONFIG" ]; then
+ warn "$SSH_CONFIG not found; skipping AddKeysToAgent check."
+ return 0
+ fi
+ if grep -Eq '^[[:space:]]*AddKeysToAgent[[:space:]]+yes' "$SSH_CONFIG"; then
+ info "AddKeysToAgent already set in $SSH_CONFIG"
+ return 0
+ fi
+ step "Adding AddKeysToAgent to $SSH_CONFIG"
+ if [ "$DRY_RUN" -eq 1 ]; then
+ printf '[DRY-RUN] append AddKeysToAgent to %s\n' "$SSH_CONFIG"
+ return 0
+ fi
+ printf '\n# Automatically add keys to ssh-agent\nAddKeysToAgent yes\n' >> "$SSH_CONFIG"
+}
+
+create_service_file() {
+ if service_exists; then
+ info "Service file already exists: $SERVICE_FILE"
+ return 0
+ fi
+ step "Creating systemd user service file"
+ if [ "$DRY_RUN" -eq 1 ]; then
+ printf '[DRY-RUN] create service file %s\n' "$SERVICE_FILE"
+ return 0
+ fi
+ mkdir -p "$SYSTEMD_USER_DIR"
+ cat <<'EOF' > "$SERVICE_FILE"
+[Unit]
+Description=SSH key agent
+
+[Service]
+Type=simple
+Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
+ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK
+
+[Install]
+WantedBy=default.target
+EOF
+}
+
+enable_service() {
+ step "Enabling ssh-agent user service"
+ systemctl_user daemon-reload
+ systemctl_user enable --now "$SERVICE_NAME"
+}
+
+disable_service() {
+ step "Disabling ssh-agent user service"
+ systemctl_user disable --now "$SERVICE_NAME"
+}
+
+remove_service() {
+ step "Removing ssh-agent user service"
+ if service_exists; then
+ disable_service || true
+ if [ "$DRY_RUN" -eq 1 ]; then
+ printf '[DRY-RUN] remove service file %s\n' "$SERVICE_FILE"
+ else
+ rm -f "$SERVICE_FILE"
+ fi
+ systemctl_user daemon-reload
+ else
+ warn "Service file not found; nothing to remove."
+ fi
+}
+
+show_status() {
+ info "Detected Hyprland config mode: $(detect_hypr_config_mode)"
+ service_status_summary
+ info "SSH_AUTH_SOCK in ENVariables.conf: $(env_present_conf && echo yes || echo no)"
+ info "SSH_AUTH_SOCK in user_env.lua: $(env_present_lua && echo yes || echo no)"
+ if [ -f "$SSH_CONFIG" ]; then
+ info "AddKeysToAgent in ~/.ssh/config: $(grep -Eq '^[[:space:]]*AddKeysToAgent[[:space:]]+yes' "$SSH_CONFIG" && echo yes || echo no)"
+ else
+ warn "~/.ssh/config not found."
+ fi
+ if [ "$SHOW_SYSTEMD_STATUS" -eq 1 ] && command -v systemctl >/dev/null 2>&1; then
+ systemctl --user status "$SERVICE_NAME" || true
+ fi
+}
+
+apply_hypr_env() {
+ local mode
+ mode="$(detect_hypr_config_mode)"
+ if [ "$mode" = "lua" ]; then
+ ensure_env_lua
+ else
+ ensure_env_conf
+ fi
+}
+
+if [ "$SHOW_HELP" -eq 1 ]; then
+ usage
+fi
+
+case "$ACTION" in
+ status)
+ show_status
+ ;;
+ enable)
+ step "Step 1/4: Ensure service file"
+ create_service_file
+ step "Step 2/4: Enable user service"
+ enable_service
+ step "Step 3/4: Update Hyprland environment"
+ apply_hypr_env
+ step "Step 4/4: Update SSH config"
+ ensure_ssh_config
+ show_status
+ ;;
+ disable)
+ disable_service
+ show_status
+ ;;
+ remove)
+ remove_service
+ show_status
+ ;;
+ *)
+ warn "Unknown action: $ACTION"
+ usage
+ exit 1
+ ;;
+esac
diff --git a/config/hypr/scripts/rofi-emacs-keybinds b/config/hypr/scripts/rofi-emacs-keybinds
index bee1a54d..6617d3b0 100755
--- a/config/hypr/scripts/rofi-emacs-keybinds
+++ b/config/hypr/scripts/rofi-emacs-keybinds
@@ -2,7 +2,7 @@
set -u
set -o pipefail
-ROFI_CONFIG="${HOME}/.config/rofi/config-emacs-keybinds.rasi"
+ROFI_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-emacs-keybinds.rasi"
CACHE_FILE="${HOME}/.cache/rofi-emacs-keybinds.txt"
if [[ ! -s "${CACHE_FILE}" ]]; then
diff --git a/config/hypr/scripts/rofi-ssh-menu.sh b/config/hypr/scripts/rofi-ssh-menu.sh
index d1640c66..1b058f59 100755
--- a/config/hypr/scripts/rofi-ssh-menu.sh
+++ b/config/hypr/scripts/rofi-ssh-menu.sh
@@ -10,7 +10,7 @@
set -euo pipefail
SSH_CONFIG="${HOME}/.ssh/config"
-ROFI_CONFIG="${HOME}/.config/rofi/config.rasi"
+ROFI_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config.rasi"
MSG='Select a host to connect via SSH'
notify() {
diff --git a/config/hypr/scripts/sddm_wallpaper.sh b/config/hypr/scripts/sddm_wallpaper.sh
index deee938c..f30bac9b 100755
--- a/config/hypr/scripts/sddm_wallpaper.sh
+++ b/config/hypr/scripts/sddm_wallpaper.sh
@@ -7,69 +7,409 @@
# ==================================================
# SDDM Wallpaper and Wallust Colors Setter
-# for the upcoming changes on the simple_sddm_theme
-
# variables
terminal=kitty
PICTURES_DIR="$(xdg-user-dir PICTURES 2>/dev/null || echo "$HOME/Pictures")"
wallDIR="$PICTURES_DIR/wallpapers"
-SCRIPTSDIR="$HOME/.config/hypr/scripts"
-wallpaper_current="$HOME/.config/hypr/wallpaper_effects/.wallpaper_current"
-wallpaper_modified="$HOME/.config/hypr/wallpaper_effects/.wallpaper_modified"
+SCRIPTSDIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts"
+wallpaper_link="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/.current_wallpaper"
+wallpaper_current="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_current"
+wallpaper_modified="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_modified"
+rofi_theme="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/config-wallpaper.rasi"
+# Directory for swaync
+iDIR="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/images"
+iDIRi="${XDG_CONFIG_HOME:-$HOME/.config}/swaync/icons"
+video_preview_cache="$HOME/.cache/video_preview"
+sddm_video_cache="$HOME/.cache/sddm_preview"
+# shellcheck source=/dev/null
+. "$SCRIPTSDIR/WallpaperCmd.sh" 2>/dev/null || true
+
+find_notify_send() {
+ local candidate=""
+ if candidate="$(command -v notify-send 2>/dev/null)"; then
+ if [[ -n "$candidate" && -x "$candidate" ]]; then
+ printf '%s\n' "$candidate"
+ return 0
+ fi
+ fi
+ for candidate in /usr/bin/notify-send /usr/sbin/notify-send /bin/notify-send /sbin/notify-send; do
+ if [[ -x "$candidate" ]]; then
+ printf '%s\n' "$candidate"
+ return 0
+ fi
+ done
+ return 1
+}
+
+NOTIFY_SEND_BIN="$(find_notify_send || true)"
+
+notify_err() {
+ if [[ -n "$NOTIFY_SEND_BIN" ]]; then
+ if [[ -f "$iDIR/error.png" ]]; then
+ "$NOTIFY_SEND_BIN" -i "$iDIR/error.png" "SDDM" "$1"
+ else
+ "$NOTIFY_SEND_BIN" "SDDM" "$1"
+ fi
+ fi
+}
+
+notify_ok() {
+ if [[ -n "$NOTIFY_SEND_BIN" ]]; then
+ if [[ -f "$iDIR/ja.png" ]]; then
+ "$NOTIFY_SEND_BIN" -i "$iDIR/ja.png" "SDDM" "$1"
+ else
+ "$NOTIFY_SEND_BIN" "SDDM" "$1"
+ fi
+ fi
+}
+
+read_cached_wallpaper() {
+ local cache_file="$1"
+ [[ -f "$cache_file" ]] || return 1
+ awk 'NF && $0 !~ /^filter/ {print; exit}' "$cache_file"
+}
+
+read_wallpaper_from_query() {
+ local monitor="$1"
+ [[ -n "$monitor" ]] || return 1
+ [[ -n "${WWW_CMD:-}" ]] || return 1
+ command -v "$WWW_CMD" >/dev/null 2>&1 || return 1
+ "$WWW_CMD" query 2>/dev/null | awk -v mon="$monitor" '
+ {
+ line=$0
+ sub(/^Monitor[[:space:]]+/, "", line)
+ sub(/^:[[:space:]]*/, "", line)
+ mon_name=line
+ sub(/:.*/, "", mon_name)
+ gsub(/^[[:space:]]+|[[:space:]]+$/, "", mon_name)
+ if (mon_name != mon) next
+ path=line
+ sub(/^.*image:[[:space:]]*/, "", path)
+ gsub(/^[[:space:]]+|[[:space:]]+$/, "", path)
+ if (path != line && length(path) > 0) {
+ print path
+ exit
+ }
+ }
+ '
+}
+
+read_wallpaper_from_cache() {
+ local monitor="$1"
+ local cache_root="${WWW_CACHE_DIR:-$HOME/.cache/awww}"
+ local cache_file="$cache_root/$monitor"
+ local fallback_cache=""
+ local path=""
+
+ case "$cache_root" in
+ "$HOME/.cache/awww")
+ fallback_cache="$HOME/.cache/swww/$monitor"
+ ;;
+ "$HOME/.cache/swww")
+ fallback_cache="$HOME/.cache/awww/$monitor"
+ ;;
+ esac
+
+ path="$(read_cached_wallpaper "$cache_file" 2>/dev/null || true)"
+ if [[ -z "$path" && -n "$fallback_cache" ]]; then
+ path="$(read_cached_wallpaper "$fallback_cache" 2>/dev/null || true)"
+ fi
+
+ [[ -n "$path" && -f "$path" ]] || return 1
+ printf '%s\n' "$path"
+}
+
+calculate_rofi_icon_size() {
+ local monitor="$1"
+ local scale_factor=""
+ local monitor_height=""
+ local icon_size=""
+ local adjusted_icon_size=""
+
+ if [[ -z "$monitor" ]]; then
+ monitor="$(get_focused_monitor 2>/dev/null || true)"
+ fi
+
+ if [[ -z "$monitor" ]]; then
+ printf '22\n'
+ return 0
+ fi
+
+ if command -v hyprctl >/dev/null 2>&1 && command -v jq >/dev/null 2>&1 && command -v bc >/dev/null 2>&1; then
+ scale_factor="$(hyprctl monitors -j 2>/dev/null | jq -r --arg mon "$monitor" '.[] | select(.name == $mon) | .scale' | head -n1)"
+ monitor_height="$(hyprctl monitors -j 2>/dev/null | jq -r --arg mon "$monitor" '.[] | select(.name == $mon) | .height' | head -n1)"
+ if [[ -n "$scale_factor" && -n "$monitor_height" && "$scale_factor" != "null" && "$monitor_height" =~ ^[0-9]+$ ]]; then
+ icon_size="$(echo "scale=1; ($monitor_height * 3) / ($scale_factor * 150)" | bc 2>/dev/null || true)"
+ adjusted_icon_size="$(echo "$icon_size" | awk '{if ($1 < 15) $1 = 20; if ($1 > 25) $1 = 25; print int($1)}')"
+ if [[ "$adjusted_icon_size" =~ ^[0-9]+$ ]]; then
+ printf '%s\n' "$adjusted_icon_size"
+ return 0
+ fi
+ fi
+ fi
+
+ printf '22\n'
+}
+
+resolve_link_or_file() {
+ local path="$1"
+ local resolved=""
+ if [[ -L "$path" ]]; then
+ resolved="$(readlink -f "$path" 2>/dev/null || true)"
+ if [[ -n "$resolved" && -f "$resolved" ]]; then
+ printf '%s\n' "$resolved"
+ return 0
+ fi
+ fi
+ if [[ -f "$path" ]]; then
+ printf '%s\n' "$path"
+ return 0
+ fi
+ return 1
+}
+
+get_active_workspace_monitor() {
+ if ! command -v hyprctl >/dev/null 2>&1; then
+ return 1
+ fi
+ if command -v jq >/dev/null 2>&1; then
+ hyprctl activeworkspace -j 2>/dev/null | jq -r '.monitor // empty' | head -n1
+ else
+ hyprctl monitors 2>/dev/null | awk '/^Monitor/{name=$2} /focused: yes/{print name; exit}'
+ fi
+}
+
+get_focused_monitor() {
+ if ! command -v hyprctl >/dev/null 2>&1; then
+ return 1
+ fi
+ if command -v jq >/dev/null 2>&1; then
+ hyprctl monitors -j 2>/dev/null | jq -r '.[] | select(.focused) | .name' | head -n1
+ else
+ hyprctl monitors 2>/dev/null | awk '/^Monitor/{name=$2} /focused: yes/{print name; exit}'
+ fi
+}
+
+monitor_exists() {
+ local monitor="$1"
+ [[ -n "$monitor" ]] || return 1
+ command -v hyprctl >/dev/null 2>&1 || return 1
+ if command -v jq >/dev/null 2>&1; then
+ hyprctl monitors -j 2>/dev/null | jq -r --arg mon "$monitor" '.[] | select(.name == $mon) | .name' | grep -qx "$monitor"
+ else
+ hyprctl monitors 2>/dev/null | awk '/^Monitor/{print $2}' | grep -qx "$monitor"
+ fi
+}
+
+resolve_target_monitor() {
+ local requested="$1"
+ local monitor=""
+ if monitor_exists "$requested"; then
+ printf '%s\n' "$requested"
+ return 0
+ fi
+ monitor="$(get_active_workspace_monitor 2>/dev/null || true)"
+ if monitor_exists "$monitor"; then
+ printf '%s\n' "$monitor"
+ return 0
+ fi
+ monitor="$(get_focused_monitor 2>/dev/null || true)"
+ if [[ -n "$monitor" ]]; then
+ printf '%s\n' "$monitor"
+ return 0
+ fi
+ return 1
+}
+
+resolve_normal_wallpaper() {
+ local monitor="$1"
+ local path=""
+ local per_monitor_rofi_link=""
+ local per_monitor_current=""
+
+ if [[ -n "$monitor" ]]; then
+ per_monitor_rofi_link="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/.current_wallpaper_${monitor}"
+ per_monitor_current="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_current_${monitor}"
+
+ path="$(read_wallpaper_from_query "$monitor" 2>/dev/null || true)"
+ if [[ -z "$path" ]]; then
+ path="$(resolve_link_or_file "$per_monitor_rofi_link" 2>/dev/null || true)"
+ fi
+ if [[ -z "$path" ]]; then
+ path="$(resolve_link_or_file "$per_monitor_current" 2>/dev/null || true)"
+ fi
+ if [[ -z "$path" ]]; then
+ path="$(read_wallpaper_from_cache "$monitor" 2>/dev/null || true)"
+ fi
+ fi
+
+ if [[ -z "$path" ]]; then
+ path="$(resolve_link_or_file "$wallpaper_current" 2>/dev/null || true)"
+ fi
+ if [[ -z "$path" ]]; then
+ path="$(resolve_link_or_file "$wallpaper_link" 2>/dev/null || true)"
+ fi
+
+ [[ -n "$path" && -f "$path" ]] || return 1
+ printf '%s\n' "$path"
+}
+
+resolve_effects_wallpaper() {
+ local monitor="$1"
+ local path=""
+ local per_monitor_modified=""
+
+ if [[ -n "$monitor" ]]; then
+ per_monitor_modified="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpaper_effects/.wallpaper_modified_${monitor}"
+ path="$(resolve_link_or_file "$per_monitor_modified" 2>/dev/null || true)"
+ fi
+
+ if [[ -z "$path" ]]; then
+ path="$(resolve_link_or_file "$wallpaper_modified" 2>/dev/null || true)"
+ fi
+ if [[ -z "$path" ]]; then
+ path="$(resolve_normal_wallpaper "$monitor" 2>/dev/null || true)"
+ fi
+
+ [[ -n "$path" && -f "$path" ]] || return 1
+ printf '%s\n' "$path"
+}
+
+resolve_current_sddm_background() {
+ local sddm_simple="$1"
+ local candidate=""
+ for candidate in "$sddm_simple/Backgrounds/default" "$sddm_simple/Backgrounds/default.jpg" "$sddm_simple/Backgrounds/default.png"; do
+ if [[ -f "$candidate" ]]; then
+ printf '%s\n' "$candidate"
+ return 0
+ fi
+ done
+ return 1
+}
+
+extract_color() {
+ local key="$1"
+ local value
+ value="$(grep -oP "$key:\\s*\\K#[A-Fa-f0-9]+" "$rofi_wallust" | head -n1)"
+ printf '%s\n' "$value"
+}
+
+prepare_sddm_wallpaper() {
+ local selected_file="$1"
+ local target_monitor="$2"
+ local prepared_path="$selected_file"
+
+ if [[ ! -f "$selected_file" ]]; then
+ notify_err "Selected file not found for ${target_monitor:-current context}."
+ return 1
+ fi
+
+ if [[ "$selected_file" =~ \.(mp4|mkv|mov|webm|MP4|MKV|MOV|WEBM)$ ]]; then
+ if ! command -v ffmpeg >/dev/null 2>&1; then
+ notify_err "ffmpeg not found; cannot convert selected video wallpaper."
+ return 1
+ fi
+ mkdir -p "$sddm_video_cache"
+ local video_name
+ video_name="$(basename "$selected_file")"
+ prepared_path="$sddm_video_cache/${video_name}.png"
+ if ! ffmpeg -v error -y -i "$selected_file" -ss 00:00:01.000 -vframes 1 "$prepared_path"; then
+ notify_err "Could not generate preview from selected video wallpaper."
+ return 1
+ fi
+ fi
+
+ printf '%s\n' "$prepared_path"
+}
+
+# Parse arguments
+mode="effects" # default
+requested_monitor="${SDDM_TARGET_MONITOR:-${HYPRLOCK_TARGET_MONITOR:-}}"
+for arg in "$@"; do
+ case "$arg" in
+ --normal)
+ mode="normal"
+ ;;
+ --effects)
+ mode="effects"
+ ;;
+ --monitor=*)
+ requested_monitor="${arg#--monitor=}"
+ ;;
+ --*)
+ ;;
+ *)
+ if [[ -z "$requested_monitor" ]]; then
+ requested_monitor="$arg"
+ fi
+ ;;
+ esac
+done
+
# Resolve SDDM themes directory (standard paths and NixOS path)
sddm_themes_dir="/usr/share/sddm/themes"
-if [ ! -d "$sddm_themes_dir" ] && [ -d "/run/current-system/sw/share/sddm/themes" ]; then
+if [[ ! -d "$sddm_themes_dir" && -d "/run/current-system/sw/share/sddm/themes" ]]; then
sddm_themes_dir="/run/current-system/sw/share/sddm/themes"
fi
sddm_simple="$sddm_themes_dir/simple_sddm_2"
+sddm_theme_conf="$sddm_simple/theme.conf"
# rofi-wallust-sddm colors path
-rofi_wallust="$HOME/.config/rofi/wallust/colors-rofi.rasi"
-sddm_theme_conf="$sddm_simple/theme.conf"
+rofi_wallust="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/wallust/colors-rofi.rasi"
if [[ ! -f "$rofi_wallust" ]]; then
- notify-send -i "$iDIR/error.png" "SDDM" "Wallust colors file not found ($rofi_wallust). Aborting."
+ notify_err "Wallust colors file not found ($rofi_wallust). Aborting."
+ exit 1
+fi
+if [[ ! -d "$sddm_simple/Backgrounds" ]]; then
+ notify_err "SDDM theme backgrounds not found ($sddm_simple/Backgrounds)."
+ exit 1
+fi
+if [[ ! -f "$sddm_theme_conf" ]]; then
+ notify_err "SDDM theme config not found ($sddm_theme_conf)."
+ exit 1
+fi
+if [[ ! -d "$wallDIR" ]]; then
+ notify_err "Wallpaper directory not found ($wallDIR)."
+ exit 1
+fi
+if ! command -v rofi >/dev/null 2>&1; then
+ notify_err "rofi not found."
+ exit 1
+fi
+if ! command -v "$terminal" >/dev/null 2>&1; then
+ notify_err "Terminal '$terminal' not found."
+ exit 1
+fi
+if ! command -v sudo >/dev/null 2>&1; then
+ notify_err "sudo not found."
exit 1
fi
-# Directory for swaync
-iDIR="$HOME/.config/swaync/images"
-iDIRi="$HOME/.config/swaync/icons"
-
-# Parse arguments
-mode="effects" # default
-if [[ "$1" == "--normal" ]]; then
- mode="normal"
-elif [[ "$1" == "--effects" ]]; then
- mode="effects"
+# Abort on NixOS where this repo doesn't manage SDDM and themes are typically read-only
+if hostnamectl 2>/dev/null | grep -q 'Operating System: NixOS'; then
+ notify_err "NixOS detected: skipping SDDM background change."
+ exit 0
fi
# Abort if SDDM is not running (avoid errors on non-SDDM systems)
if command -v systemctl >/dev/null 2>&1; then
if ! systemctl is-active --quiet sddm; then
- notify-send -i "$iDIR/error.png" "SDDM" "SDDM is not running. Skipping SDDM wallpaper update."
+ notify_err "SDDM is not running. Skipping SDDM wallpaper update."
exit 0
fi
elif ! pidof sddm >/dev/null 2>&1; then
- notify-send -i "$iDIR/error.png" "SDDM" "SDDM is not running. Skipping SDDM wallpaper update."
+ notify_err "SDDM is not running. Skipping SDDM wallpaper update."
exit 0
fi
# Extract colors from rofi wallust config
-
-extract_color() {
- local key="$1"
- local value
- value=$(grep -oP "$key:\s*\K#[A-Fa-f0-9]+" "$rofi_wallust" | head -n1)
- echo "$value"
-}
-
-color0=$(extract_color "color1")
-color1=$(extract_color "color0")
-color7=$(extract_color "color14")
-color10=$(extract_color "color10")
-color12=$(extract_color "color12")
-color13=$(extract_color "color13")
-foreground=$(extract_color "foreground")
+color0="$(extract_color "color1")"
+color1="$(extract_color "color0")"
+color7="$(extract_color "color14")"
+color10="$(extract_color "color10")"
+color12="$(extract_color "color12")"
+color13="$(extract_color "color13")"
+foreground="$(extract_color "foreground")"
missing_colors=()
for var in color0 color1 color7 color10 color12 color13 foreground; do
@@ -79,57 +419,172 @@ for var in color0 color1 color7 color10 color12 color13 foreground; do
done
if [[ ${#missing_colors[@]} -gt 0 ]]; then
- notify-send -i "$iDIR/error.png" "SDDM" "Missing color(s): ${missing_colors[*]}. Run Wallust first."
+ notify_err "Missing color(s): ${missing_colors[*]}. Run Wallust first."
exit 1
fi
-#background-color=$(grep -oP 'background:\s*\K#[A-Fa-f0-9]+' "$rofi_wallust")
-# wallpaper to use
+target_monitor="$(resolve_target_monitor "$requested_monitor" 2>/dev/null || true)"
+current_monitor_path=""
if [[ "$mode" == "normal" ]]; then
- wallpaper_path="$wallpaper_current"
+ current_monitor_path="$(resolve_normal_wallpaper "$target_monitor" 2>/dev/null || true)"
else
- wallpaper_path="$wallpaper_modified"
+ current_monitor_path="$(resolve_effects_wallpaper "$target_monitor" 2>/dev/null || true)"
fi
+current_sddm_path="$(resolve_current_sddm_background "$sddm_simple" 2>/dev/null || true)"
-# Abort on NixOS where this repo doesn't manage SDDM and themes are typically read-only
-if hostnamectl 2>/dev/null | grep -q 'Operating System: NixOS'; then
- notify-send -i "$iDIR/error.png" "SDDM" "NixOS detected: skipping SDDM background change."
+current_monitor_label=""
+if [[ -n "$current_monitor_path" && -f "$current_monitor_path" ]]; then
+ if [[ -n "$target_monitor" ]]; then
+ current_monitor_label="Current monitor ($target_monitor): $(basename "$current_monitor_path")"
+ else
+ current_monitor_label="Current monitor wallpaper: $(basename "$current_monitor_path")"
+ fi
+fi
+
+current_sddm_label=""
+if [[ -n "$current_sddm_path" && -f "$current_sddm_path" ]]; then
+ current_sddm_label="Current SDDM background: $(basename "$current_sddm_path")"
+fi
+
+mapfile -d '' WALLPAPERS < <(find -L "$wallDIR" -type f \( \
+ -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.gif" -o \
+ -iname "*.bmp" -o -iname "*.tiff" -o -iname "*.webp" -o \
+ -iname "*.mp4" -o -iname "*.mkv" -o -iname "*.mov" -o -iname "*.webm" \
+\) -print0)
+
+if [[ ${#WALLPAPERS[@]} -eq 0 ]]; then
+ notify_err "No wallpapers found in $wallDIR."
+ exit 1
+fi
+
+random_wallpaper="${WALLPAPERS[$((RANDOM % ${#WALLPAPERS[@]}))]}"
+random_label="Random: $(basename "$random_wallpaper")"
+
+has_ffmpeg=0
+if command -v ffmpeg >/dev/null 2>&1; then
+ has_ffmpeg=1
+fi
+
+menu_message="Select SDDM wallpaper"
+if [[ -n "$target_monitor" ]]; then
+ menu_message="Select SDDM wallpaper for $target_monitor"
+fi
+rofi_icon_size="$(calculate_rofi_icon_size "$target_monitor")"
+rofi_override="element-icon{size:${rofi_icon_size}%;}"
+
+menu() {
+ local -a sorted_options=()
+ local pic_path pic_name cache_preview_image
+
+ mapfile -t sorted_options < <(printf '%s\n' "${WALLPAPERS[@]}" | sort)
+
+ printf "%s\x00icon\x1f%s\n" "$random_label" "$random_wallpaper"
+ if [[ -n "$current_monitor_label" && -n "$current_monitor_path" ]]; then
+ printf "%s\x00icon\x1f%s\n" "$current_monitor_label" "$current_monitor_path"
+ fi
+ if [[ -n "$current_sddm_label" && -n "$current_sddm_path" ]]; then
+ printf "%s\x00icon\x1f%s\n" "$current_sddm_label" "$current_sddm_path"
+ fi
+
+ for pic_path in "${sorted_options[@]}"; do
+ pic_name="$(basename "$pic_path")"
+ if [[ "$pic_name" =~ \.(mp4|mkv|mov|webm|MP4|MKV|MOV|WEBM)$ ]]; then
+ cache_preview_image="$video_preview_cache/${pic_name}.png"
+ if [[ ! -f "$cache_preview_image" && "$has_ffmpeg" -eq 1 ]]; then
+ mkdir -p "$video_preview_cache"
+ ffmpeg -v error -y -i "$pic_path" -ss 00:00:01.000 -vframes 1 "$cache_preview_image" >/dev/null 2>&1 || true
+ fi
+ if [[ -f "$cache_preview_image" ]]; then
+ printf "%s\x00icon\x1f%s\n" "$pic_name" "$cache_preview_image"
+ else
+ printf "%s\n" "$pic_name"
+ fi
+ else
+ printf "%s\x00icon\x1f%s\n" "$pic_name" "$pic_path"
+ fi
+ done
+}
+
+rofi_cmd=(rofi -i -show -dmenu -mesg "$menu_message" -theme-str "$rofi_override")
+if [[ -f "$rofi_theme" ]]; then
+ rofi_cmd+=(-config "$rofi_theme")
+fi
+
+choice="$(menu | "${rofi_cmd[@]}")"
+choice="${choice#"${choice%%[![:space:]]*}"}"
+choice="${choice%"${choice##*[![:space:]]}"}"
+
+if [[ -z "$choice" ]]; then
exit 0
fi
-# Launch terminal and apply changes
-$terminal -e bash -c "
-echo 'Enter your password to update SDDM wallpapers and colors';
+selected_file=""
+if [[ "$choice" == "$random_label" ]]; then
+ selected_file="$random_wallpaper"
+elif [[ -n "$current_monitor_label" && "$choice" == "$current_monitor_label" ]]; then
+ selected_file="$current_monitor_path"
+elif [[ -n "$current_sddm_label" && "$choice" == "$current_sddm_label" ]]; then
+ selected_file="$current_sddm_path"
+elif [[ -f "$choice" ]]; then
+ selected_file="$choice"
+else
+ choice_basename="$(basename "$choice" | sed 's/\(.*\)\.[^.]*$/\1/')"
+ selected_file="$(find -L "$wallDIR" -type f -iname "$choice_basename.*" -print -quit)"
+fi
-# Update the colors in the SDDM config
-sudo sed -i \"s/HeaderTextColor=\\\"#.*\\\"/HeaderTextColor=\\\"$color13\\\"/\" \"$sddm_theme_conf\"
-sudo sed -i \"s/DateTextColor=\\\"#.*\\\"/DateTextColor=\\\"$color13\\\"/\" \"$sddm_theme_conf\"
-sudo sed -i \"s/TimeTextColor=\\\"#.*\\\"/TimeTextColor=\\\"$color13\\\"/\" \"$sddm_theme_conf\"
-sudo sed -i \"s/DropdownSelectedBackgroundColor=\\\"#.*\\\"/DropdownSelectedBackgroundColor=\\\"$color13\\\"/\" \"$sddm_theme_conf\"
-sudo sed -i \"s/SystemButtonsIconsColor=\\\"#.*\\\"/SystemButtonsIconsColor=\\\"$color13\\\"/\" \"$sddm_theme_conf\"
-sudo sed -i \"s/SessionButtonTextColor=\\\"#.*\\\"/SessionButtonTextColor=\\\"$color13\\\"/\" \"$sddm_theme_conf\"
-sudo sed -i \"s/VirtualKeyboardButtonTextColor=\\\"#.*\\\"/VirtualKeyboardButtonTextColor=\\\"$color13\\\"/\" \"$sddm_theme_conf\"
-sudo sed -i \"s/HighlightBackgroundColor=\\\"#.*\\\"/HighlightBackgroundColor=\\\"$color12\\\"/\" \"$sddm_theme_conf\"
-sudo sed -i \"s/LoginFieldTextColor=\\\"#.*\\\"/LoginFieldTextColor=\\\"$color12\\\"/\" \"$sddm_theme_conf\"
-sudo sed -i \"s/PasswordFieldTextColor=\\\"#.*\\\"/PasswordFieldTextColor=\\\"$color12\\\"/\" \"$sddm_theme_conf\"
+if [[ -z "$selected_file" || ! -f "$selected_file" ]]; then
+ notify_err "Selected wallpaper not found: $choice"
+ exit 1
+fi
-sudo sed -i \"s/DropdownBackgroundColor=\\\"#.*\\\"/DropdownBackgroundColor=\\\"$color1\\\"/\" \"$sddm_theme_conf\"
-sudo sed -i \"s/HighlightTextColor=\\\"#.*\\\"/HighlightTextColor=\\\"$color10\\\"/\" \"$sddm_theme_conf\"
+wallpaper_path="$(prepare_sddm_wallpaper "$selected_file" "$target_monitor" 2>/dev/null || true)"
+if [[ -z "$wallpaper_path" || ! -f "$wallpaper_path" ]]; then
+ notify_err "Could not prepare selected wallpaper for SDDM."
+ exit 1
+fi
+
+# Launch terminal and apply changes
+if ! "$terminal" -e bash -c '
+set -e
+theme_conf="$1"
+wallpaper_path="$2"
+sddm_simple="$3"
+color13="$4"
+color12="$5"
+color1="$6"
+color10="$7"
+color7="$8"
-sudo sed -i \"s/PlaceholderTextColor=\\\"#.*\\\"/PlaceholderTextColor=\\\"$color7\\\"/\" \"$sddm_theme_conf\"
-sudo sed -i \"s/UserIconColor=\\\"#.*\\\"/UserIconColor=\\\"$color7\\\"/\" \"$sddm_theme_conf\"
-sudo sed -i \"s/PasswordIconColor=\\\"#.*\\\"/PasswordIconColor=\\\"$color7\\\"/\" \"$sddm_theme_conf\"
+echo "Enter your password to update SDDM wallpapers and colors"
+
+# Update the colors in the SDDM config
+sudo sed -i "s/HeaderTextColor=\"#.*\"/HeaderTextColor=\"$color13\"/" "$theme_conf"
+sudo sed -i "s/DateTextColor=\"#.*\"/DateTextColor=\"$color13\"/" "$theme_conf"
+sudo sed -i "s/TimeTextColor=\"#.*\"/TimeTextColor=\"$color13\"/" "$theme_conf"
+sudo sed -i "s/DropdownSelectedBackgroundColor=\"#.*\"/DropdownSelectedBackgroundColor=\"$color13\"/" "$theme_conf"
+sudo sed -i "s/SystemButtonsIconsColor=\"#.*\"/SystemButtonsIconsColor=\"$color13\"/" "$theme_conf"
+sudo sed -i "s/SessionButtonTextColor=\"#.*\"/SessionButtonTextColor=\"$color13\"/" "$theme_conf"
+sudo sed -i "s/VirtualKeyboardButtonTextColor=\"#.*\"/VirtualKeyboardButtonTextColor=\"$color13\"/" "$theme_conf"
+sudo sed -i "s/HighlightBackgroundColor=\"#.*\"/HighlightBackgroundColor=\"$color12\"/" "$theme_conf"
+sudo sed -i "s/LoginFieldTextColor=\"#.*\"/LoginFieldTextColor=\"$color12\"/" "$theme_conf"
+sudo sed -i "s/PasswordFieldTextColor=\"#.*\"/PasswordFieldTextColor=\"$color12\"/" "$theme_conf"
+sudo sed -i "s/DropdownBackgroundColor=\"#.*\"/DropdownBackgroundColor=\"$color1\"/" "$theme_conf"
+sudo sed -i "s/HighlightTextColor=\"#.*\"/HighlightTextColor=\"$color10\"/" "$theme_conf"
+sudo sed -i "s/PlaceholderTextColor=\"#.*\"/PlaceholderTextColor=\"$color7\"/" "$theme_conf"
+sudo sed -i "s/UserIconColor=\"#.*\"/UserIconColor=\"$color7\"/" "$theme_conf"
+sudo sed -i "s/PasswordIconColor=\"#.*\"/PasswordIconColor=\"$color7\"/" "$theme_conf"
# Copy wallpaper to SDDM theme
-# Primary: set Backgrounds/default (no extension) for simple_sddm_2
-sudo cp -f \"$wallpaper_path\" \"$sddm_simple/Backgrounds/default\" || true
-# Fallbacks: if theme ships default.jpg or default.png, update those too
-if [ -e \"$sddm_simple/Backgrounds/default.jpg\" ]; then
- sudo cp -f \"$wallpaper_path\" \"$sddm_simple/Backgrounds/default.jpg\"
+sudo cp -f "$wallpaper_path" "$sddm_simple/Backgrounds/default"
+if [ -e "$sddm_simple/Backgrounds/default.jpg" ]; then
+ sudo cp -f "$wallpaper_path" "$sddm_simple/Backgrounds/default.jpg"
fi
-if [ -e \"$sddm_simple/Backgrounds/default.png\" ]; then
- sudo cp -f \"$wallpaper_path\" \"$sddm_simple/Backgrounds/default.png\"
+if [ -e "$sddm_simple/Backgrounds/default.png" ]; then
+ sudo cp -f "$wallpaper_path" "$sddm_simple/Backgrounds/default.png"
+fi
+' _ "$sddm_theme_conf" "$wallpaper_path" "$sddm_simple" "$color13" "$color12" "$color1" "$color10" "$color7"; then
+ notify_err "Failed to update SDDM for ${target_monitor:-current context}: $(basename "$wallpaper_path")."
+ exit 1
fi
-notify-send -i \"$iDIR/ja.png\" \"SDDM\" \"Background SET\"
-" \ No newline at end of file
+notify_ok "Set for ${target_monitor:-current context}: $(basename "$wallpaper_path")."
diff --git a/config/hypr/scripts/set-default-thunar-terminal.sh b/config/hypr/scripts/set-default-thunar-terminal.sh
index fd50eb6c..cf5107cf 100755
--- a/config/hypr/scripts/set-default-thunar-terminal.sh
+++ b/config/hypr/scripts/set-default-thunar-terminal.sh
@@ -11,7 +11,7 @@ setup_default_terminal() {
# 1. Configure XFCE/Exo (Thunar's primary helper)
# This handles "Open Terminal Here" and "Open with [CLI App]"
- HELPER_DIR="$HOME/.config/xfce4"
+ HELPER_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/xfce4"
mkdir -p "$HELPER_DIR"
KITTY_PATH="$(command -v kitty 2>/dev/null || true)"
if [ -z "$KITTY_PATH" ]; then
diff --git a/config/hypr/scripts/update_WindowRules.sh b/config/hypr/scripts/update_WindowRules.sh
index 293b14e9..d9cb08e4 100755
--- a/config/hypr/scripts/update_WindowRules.sh
+++ b/config/hypr/scripts/update_WindowRules.sh
@@ -7,7 +7,7 @@
# ==================================================
# Script to update WindowRules config if Hyprland version is >= 0.53
-CONFIGS_DIR="$HOME/.config/hypr/configs"
+CONFIGS_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/configs"
TARGET_FILE="$CONFIGS_DIR/WindowRules.conf"
get_hyprland_version() {
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage