aboutsummaryrefslogtreecommitdiffstats
path: root/config/hypr/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'config/hypr/scripts')
-rwxr-xr-xconfig/hypr/scripts/Distro_update.sh10
-rwxr-xr-xconfig/hypr/scripts/KooLsDotsUpdate.sh8
-rwxr-xr-xconfig/hypr/scripts/Tak0-Autodispatch.sh277
-rwxr-xr-xconfig/hypr/scripts/Tak0-Per-Window-Switch.sh6
4 files changed, 220 insertions, 81 deletions
diff --git a/config/hypr/scripts/Distro_update.sh b/config/hypr/scripts/Distro_update.sh
index 917f303b..164de7ec 100755
--- a/config/hypr/scripts/Distro_update.sh
+++ b/config/hypr/scripts/Distro_update.sh
@@ -15,23 +15,23 @@ fi
if command -v paru &> /dev/null || command -v yay &> /dev/null; then
# Arch-based
if command -v paru &> /dev/null; then
- kitty -T update paru -Syu
+ kitty -T update -e paru -Syu
notify-send -i "$iDIR/ja.png" -u low 'Arch-based system' 'has been updated.'
else
- kitty -T update yay -Syu
+ kitty -T update -e yay -Syu
notify-send -i "$iDIR/ja.png" -u low 'Arch-based system' 'has been updated.'
fi
elif command -v dnf &> /dev/null; then
# Fedora-based
- kitty -T update sudo dnf update --refresh -y
+ kitty -T update -e sudo dnf update --refresh -y
notify-send -i "$iDIR/ja.png" -u low 'Fedora system' 'has been updated.'
elif command -v apt &> /dev/null; then
# Debian-based (Debian, Ubuntu, etc.)
- kitty -T update bash -c "sudo apt update && sudo apt upgrade -y"
+ kitty -T update -e bash -c "sudo apt update && sudo apt upgrade -y"
notify-send -i "$iDIR/ja.png" -u low 'Debian/Ubuntu system' 'has been updated.'
elif command -v zypper &> /dev/null; then
# openSUSE-based
- kitty -T update sudo zypper dup -y
+ kitty -T update -e sudo zypper dup -y
notify-send -i "$iDIR/ja.png" -u low 'openSUSE system' 'has been updated.'
else
# Unsupported distro
diff --git a/config/hypr/scripts/KooLsDotsUpdate.sh b/config/hypr/scripts/KooLsDotsUpdate.sh
index a49f5430..006d66ed 100755
--- a/config/hypr/scripts/KooLsDotsUpdate.sh
+++ b/config/hypr/scripts/KooLsDotsUpdate.sh
@@ -17,12 +17,18 @@ fi
# GitHub URL - KooL's dots
branch="main"
github_url="https://github.com/JaKooLit/Hyprland-Dots/tree/$branch/config/hypr/"
+# Check for required tools (curl)
+if ! command -v curl &> /dev/null; then
+ notify-send -i "$iDIR/error.png" "Need curl:" "curl not found. Please install curl."
+ exit 1
+fi
# Fetch the version from GitHub URL - KooL's dots
-github_version=$(curl -s "$github_url" | grep -o 'v[0-9]\+\.[0-9]\+\.[0-9]\+' | sort -V | tail -n 1 | sed 's/v//')
+github_version=$(curl -fsSL -A "Mozilla/5.0" "$github_url" | grep -o 'v[0-9]\+\.[0-9]\+\.[0-9]\+' | sort -V | tail -n 1 | sed 's/v//')
# Cant find GitHub URL - KooL's dots version
if [ -z "$github_version" ]; then
+ notify-send -i "$iDIR/error.png" 'KooL Hyprland:' "Unable to determine GitHub version."
exit 1
fi
diff --git a/config/hypr/scripts/Tak0-Autodispatch.sh b/config/hypr/scripts/Tak0-Autodispatch.sh
index 114a3e8e..6ed7ec13 100755
--- a/config/hypr/scripts/Tak0-Autodispatch.sh
+++ b/config/hypr/scripts/Tak0-Autodispatch.sh
@@ -1,90 +1,229 @@
#!/usr/bin/env bash
-# USAGE / ІНСТРУКЦІЯ:
-# 1) Run from terminal:
-# ./dispatch.sh <application_command> <target_workspace_number>
-# Example:
-# ./dispatch.sh discord 2
-#
-# 2) Call from Hyprland config (in hyprland.conf file):
-# exec-once = /path/to/dispatch.sh <application_command> <target_workspace_number>
-#
-# Logs are saved in dispatch.log file next to the script.
-# If the window doesn't appear or is dispatched incorrectly — info will be there.
+
+# ─────────────────────────────────────────────────────────────────────────────
+# Tak0-Autodispatch.sh
+# ─────────────────────────────────────────────────────────────────────────────
+# This script is an "authoritative spawn dispatcher" for Hyprland.
#
-# Notes:
-# - Script waits about ~9 seconds (30 iterations of 0.3 sec) for window to appear.
-# - Uses hyprctl and jq, so these tools must be installed.
+# Its purpose is to FORCE all windows belonging to a single application launch
+# (main window + helpers + Electron / Steam child processes)
+# onto a specific workspace.
#
-# USAGE / ІНСТРУКЦІЯ:
-# 1) Запуск з терміналу:
-# ./dispatch.sh <application_command> <target_workspace_number>
-# Наприклад:
-# ./dispatch.sh discord 2
+# It explicitly ignores:
+# • spawn race conditions
+# • delayed window creation
+# • detached helper processes
+# • Electron / Chromium / Steam madness
#
-# 2) Виклик з конфігурації Hyprland (у файлі hyprland.conf):
-# exec-once = /path/to/dispatch.sh <application_command> <target_workspace_number>
+# Typical use cases:
+# • Launch Steam / Discord / browsers without window leakage
+# • Prevent apps from spawning on the currently focused workspace
+# • Control applications that completely ignore static windowrules
#
-# Логи зберігаються у файлі dispatch.log поруч зі скриптом.
-# Якщо вікно не з'явилось або неправильно диспатчилось — інформація там.
+# Invocation:
+# ./Tak0-Autodispatch.sh <workspace> [rule ...] -- <command>
#
-# Примітки:
-# - Скрипт чекає до ~9 секунд (30 ітерацій по 0.3 сек) поки вікно з'явиться.
-# - Використовує hyprctl і jq, тому ці інструменти мають бути встановлені.
+# Important notes:
+# • All window rules are TEMPORARY
+# • No permanent pollution of Hyprland configuration
+# ─────────────────────────────────────────────────────────────────────────────
+# REQUIREMENTS:
+# - hyprctl → runtime control of Hyprland
+# - jq → JSON client parsing
+# - pgrep/ps → process tree inspection
+
+set -u
LOGFILE="$(dirname "$0")/dispatch.log"
-# Log file path located next to the script.
-# Файл логів розташований поруч зі скриптом.
-APP=$1
-# The application command or window class to launch or match.
-# Команда для запуску аплікації або клас вікна для пошуку.
+# ─────────────────────────────────────────────────────────────────────────────
+# 0️⃣ ARGUMENT PARSING
+# ─────────────────────────────────────────────────────────────────────────────
+# $1 → target workspace
+# Next args → optional capture rules (windowrulev2 syntax)
+# "--" → argument separator
+# After "--" → command to execute (verbatim)
+
+TARGET_WS="$1"
+shift || true
-TARGET_WORKSPACE=$2
-# The target workspace number where the window should be moved.
-# Цільовий номер воркспейсу, куди потрібно перемістити вікно.
+CAPTURE_RULES=()
+while [[ "${1-}" != "--" && -n "${1-}" ]]; do
+ CAPTURE_RULES+=("$1")
+ shift || break
+done
-# Check if required arguments are provided.
-# Перевірка наявності необхідних параметрів.
-if [[ -z "$APP" || -z "$TARGET_WORKSPACE" ]]; then
- echo "Usage: $0 <application_command> <target_workspace_number>" >> "$LOGFILE" 2>&1
- exit 1
+if [[ "${1-}" == "--" ]]; then
+ shift
fi
-echo "Starting dispatch of '$APP' to workspace $TARGET_WORKSPACE at $(date)" >> "$LOGFILE"
-# Starting the dispatch process and logging the event.
-# Початок процесу диспатчу, запис у лог.
+CMD="$*"
+
+if [[ -z "$TARGET_WS" || -z "$CMD" ]]; then
+ echo "Usage: $0 <workspace> [rule rule ...] -- <command>" >>"$LOGFILE"
+ exit 1
+fi
+
+echo "=== Deploy '$CMD' → WS $TARGET_WS @ $(date) ===" >>"$LOGFILE"
+
+# ─────────────────────────────────────────────────────────────────────────────
+# 1️⃣ HYPRLAND READINESS GATE
+# ─────────────────────────────────────────────────────────────────────────────
+# Hyprland may not be fully initialized during early autostart.
+# hyprctl silently fails if called too early.
-# Avoid early workspace focus issues by switching workspace first.
-# Уникаємо проблем з раннім фокусом, спочатку переключаємо воркспейс.
-hyprctl dispatch workspace "$TARGET_WORKSPACE" >> "$LOGFILE" 2>&1
-sleep 0.4
+for _ in {1..50}; do
+ hyprctl -j monitors >/dev/null 2>&1 && break
+ sleep 0.1
+done
+
+# ─────────────────────────────────────────────────────────────────────────────
+# 2️⃣ CLEANUP GUARANTEE
+# ─────────────────────────────────────────────────────────────────────────────
+# Ensures that ALL temporary rules are removed
+# even on crash, SIGTERM, or user interruption.
+
+cleanup() {
+ echo "Cleanup: removing temporary capture rules and initialWorkspace at $(date)" >>"$LOGFILE"
+
+ hyprctl keyword windowrulev2 "unset, initialClass:.*" >>"$LOGFILE" 2>&1 || true
+ for RULE in "${CAPTURE_RULES[@]}"; do
+ echo "Cleanup: removing temporary capture rule: $RULE" >>"$LOGFILE"
+ hyprctl keyword windowrulev2 "unset, $RULE" >>"$LOGFILE" 2>&1 || true
+ done
+}
+
+trap cleanup EXIT INT TERM ERR
-# Launch the application in the background and disown it.
-# Запускаємо аплікацію у фоновому режимі та відв’язуємо від терміналу.
-$APP & disown
-pid=$!
+# ─────────────────────────────────────────────────────────────────────────────
+# 3️⃣ ULTRA-EARLY GLOBAL CAPTURE (NUCLEAR OPTION)
+# ─────────────────────────────────────────────────────────────────────────────
+# Temporarily forces ALL windows (initialClass:.*)
+# onto the target workspace.
+#
+# Protects against ultra-fast helpers:
+# • gpu-process
+# • renderer
+# • steamwebhelper
+
+echo "Applying temporary initialWorkspace capture (initialClass:.*)" >>"$LOGFILE"
+hyprctl keyword windowrulev2 \
+ "initialWorkspace $TARGET_WS silent, initialClass:.*" \
+ >>"$LOGFILE" 2>&1 || true
+
+# ─────────────────────────────────────────────────────────────────────────────
+# 3️⃣.1 OPTIONAL CLASS-BASED PRE-CAPTURE
+# ─────────────────────────────────────────────────────────────────────────────
+# Additional precision rules.
+# Useful for Electron / Steam multi-process hell.
+
+for RULE in "${CAPTURE_RULES[@]}"; do
+ echo "Applying temporary capture rule: $RULE" >>"$LOGFILE"
+ hyprctl keyword windowrulev2 \
+ "initialWorkspace $TARGET_WS silent, $RULE" \
+ >>"$LOGFILE" 2>&1 || true
+done
-echo "Launched '$APP' with PID $pid" >> "$LOGFILE"
-# Log the launched process ID.
-# Лог процесу запуску з PID.
+# ─────────────────────────────────────────────────────────────────────────────
+# 4️⃣ APPLICATION LAUNCH
+# ─────────────────────────────────────────────────────────────────────────────
+# bash -c allows aliases, env vars, wrappers.
+# ROOT_PID is the root of process lineage.
-# Wait for the application window to appear (matching window class).
-# Чекаємо появи вікна аплікації (за класом вікна).
-for i in {1..30}; do
- win=$(hyprctl clients -j | jq -r --arg APP "$APP" '
- .[] | select(.class | test($APP;"i")) | .address' 2>>"$LOGFILE")
+bash -c "$CMD" &
+ROOT_PID=$!
+echo "Root PID: $ROOT_PID" >>"$LOGFILE"
- if [[ -n "$win" ]]; then
- echo "Found window $win for app '$APP', moving to workspace $TARGET_WORKSPACE" >> "$LOGFILE"
- # Move the window to the target workspace.
- # Переміщаємо вікно на цільовий воркспейс.
- hyprctl dispatch movetoworkspace "$TARGET_WORKSPACE,address:$win" >> "$LOGFILE" 2>&1
- exit 0
+# Resolve canonical process name
+APP_NAME=""
+for _ in {1..20}; do
+ if [[ -r "/proc/$ROOT_PID/comm" ]]; then
+ APP_NAME="$(tr -d '\0' </proc/$ROOT_PID/comm 2>/dev/null || true)"
+ break
+ fi
+ sleep 0.05
+done
+
+if [[ -z "$APP_NAME" ]]; then
+ read -r -a __toks <<<"$CMD"
+ APP_NAME="$(basename "${__toks[0]}")"
+fi
+
+echo "App gate name: $APP_NAME" >>"$LOGFILE"
+
+sleep 1.5
+
+#!TO-DO: Release the nuclear option ASAP
+echo "Releasing ultra-early wide capture" >>"$LOGFILE"
+hyprctl keyword windowrulev2 "unset, initialClass:.*" >>"$LOGFILE" 2>&1 || true
+
+# ─────────────────────────────────────────────────────────────────────────────
+# 5️⃣ SUPERVISION LOOP (AUTHORITATIVE PHASE)
+# ─────────────────────────────────────────────────────────────────────────────
+# This loop:
+# • scans ALL Hyprland clients
+# • matches PID lineage
+# • matches detached helpers
+# • matches class rules
+
+get_descendants() {
+ local root="$1"
+ local all=("$root")
+ local changed=1
+
+ while ((changed)); do
+ changed=0
+ for p in "${all[@]}"; do
+ for c in $(pgrep -P "$p" 2>/dev/null || true); do
+ if [[ ! " ${all[*]} " =~ " $c " ]]; then
+ all+=("$c")
+ changed=1
+ fi
+ done
+ done
+ done
+
+ echo "${all[@]}"
+}
+
+pid_matches_app() {
+ local pid="$1"
+ local comm
+ comm="$(ps -p "$pid" -o comm= 2>/dev/null)" || return 1
+ [[ "$comm" == "$APP_NAME" || "$comm" == "$APP_NAME"* ]]
+}
+
+END_TIME=$((SECONDS + 20))
+declare -A SEEN
+
+while ((SECONDS < END_TIME)); do
+ PIDS="$(get_descendants "$ROOT_PID")"
+
+ while IFS=$'\t' read -r PID ADDR CLASS; do
+ MATCH=0
+
+ for TPID in $PIDS; do
+ [[ "$PID" == "$TPID" ]] && MATCH=1 && break
+ done
+
+ pid_matches_app "$PID" && MATCH=1
+
+ for RULE in "${CAPTURE_RULES[@]}"; do
+ if [[ "$RULE" =~ class:\^\((.*)\)\$ ]]; then
+ [[ "$CLASS" =~ ${BASH_REMATCH[1]} ]] && MATCH=1
+ fi
+ done
+
+ if ((MATCH)) && [[ -z "${SEEN[$ADDR]-}" ]]; then
+ echo "Placing window $ADDR (pid $PID, class $CLASS) → WS $TARGET_WS" >>"$LOGFILE"
+ hyprctl dispatch movetoworkspacesilent \
+ "$TARGET_WS,address:$ADDR" >>"$LOGFILE" 2>&1 || true
+ SEEN[$ADDR]=1
fi
- sleep 0.3
+ done < <(hyprctl clients -j | jq -r '.[] | [.pid, .address, .class] | @tsv')
+
+ sleep 0.01
done
-echo "ERROR: Window for '$APP' was NOT found or dispatched properly to workspace $TARGET_WORKSPACE at $(date)" >> "$LOGFILE"
-# Log error if window was not found or dispatched correctly.
-# Запис помилки, якщо вікно не знайдено або неправильно диспатчено.
-exit 1
+echo "=== Deploy finished: '$CMD' ===" >>"$LOGFILE"
+exit 0
diff --git a/config/hypr/scripts/Tak0-Per-Window-Switch.sh b/config/hypr/scripts/Tak0-Per-Window-Switch.sh
index 7cec89a6..d652f0f7 100755
--- a/config/hypr/scripts/Tak0-Per-Window-Switch.sh
+++ b/config/hypr/scripts/Tak0-Per-Window-Switch.sh
@@ -1,16 +1,10 @@
##################################################################
-# #
-# #
# TAK_0'S Per-Window-Switch #
# #
-# #
-# #
# Just a little script that I made to switch keyboard layouts #
# per-window instead of global switching for the more #
# smooth and comfortable workflow. #
-# #
##################################################################
-
# This is for changing kb_layouts. Set kb_layouts in
MAP_FILE="$HOME/.cache/kb_layout_per_window"
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage