aboutsummaryrefslogtreecommitdiffstats
path: root/config/hypr/scripts
diff options
context:
space:
mode:
authortak0dan <tmtroshko@gmail.com>2025-07-26 17:20:35 +0200
committertak0dan <tmtroshko@gmail.com>2025-07-26 17:31:14 +0200
commita2651ce31761301b5ac9c1c5915ef16c3f13ce6f (patch)
treeb29dc5737f550b119a853eadd29f207615f2c8ef /config/hypr/scripts
parent7e958b7fdfb233d7c0ebd56aaf1935b7e4c4cba2 (diff)
Small technical additions for keyboard layout and app dispatch fixesSmall technical additions for keyboard layout and app dispatch fixes
This commit introduces two minor but useful scripts aimed at solving specific edge cases in Hyprland usage: 1. Tak0-Per-Window-Switch.sh: Enables per-window keyboard layout switching. This is useful for multilingual workflows where the global layout model becomes inconvenient. The script listens to window focus events and restores the last-used layout for that specific window. 2. Tak0-Autodispatch.sh: Fixes a recurring issue where startup applications are dispatched to incorrect monitors or workspaces, especially in dynamic multi-monitor environments (e.g., a laptop that gets docked/undocked). The original dispatch rules sometimes fail due to race conditions or child process spawning out of focus. This script re-applies correct dispatching logic after startup, reducing manual corrections. Also: - Updated UserKeybinds.conf to run the per-window layout script at startup. - All changes are additive. No existing configs or behavior were overridden or broken. These changes don't introduce any core structural modifications — just small utilities to improve the overall experience when using Hyprland in daily workflows.
Diffstat (limited to 'config/hypr/scripts')
-rwxr-xr-xconfig/hypr/scripts/Tak0-Autodispatch.sh90
-rwxr-xr-xconfig/hypr/scripts/Tak0-Per-Window-Switch.sh123
2 files changed, 213 insertions, 0 deletions
diff --git a/config/hypr/scripts/Tak0-Autodispatch.sh b/config/hypr/scripts/Tak0-Autodispatch.sh
new file mode 100755
index 00000000..a1f72129
--- /dev/null
+++ b/config/hypr/scripts/Tak0-Autodispatch.sh
@@ -0,0 +1,90 @@
+#!/bin/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.
+#
+# 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.
+#
+# USAGE / ІНСТРУКЦІЯ:
+# 1) Запуск з терміналу:
+# ./dispatch.sh <application_command> <target_workspace_number>
+# Наприклад:
+# ./dispatch.sh discord 2
+#
+# 2) Виклик з конфігурації Hyprland (у файлі hyprland.conf):
+# exec-once = /path/to/dispatch.sh <application_command> <target_workspace_number>
+#
+# Логи зберігаються у файлі dispatch.log поруч зі скриптом.
+# Якщо вікно не з'явилось або неправильно диспатчилось — інформація там.
+#
+# Примітки:
+# - Скрипт чекає до ~9 секунд (30 ітерацій по 0.3 сек) поки вікно з'явиться.
+# - Використовує hyprctl і jq, тому ці інструменти мають бути встановлені.
+
+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.
+# Команда для запуску аплікації або клас вікна для пошуку.
+
+TARGET_WORKSPACE=$2
+# The target workspace number where the window should be moved.
+# Цільовий номер воркспейсу, куди потрібно перемістити вікно.
+
+# 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
+fi
+
+echo "Starting dispatch of '$APP' to workspace $TARGET_WORKSPACE at $(date)" >> "$LOGFILE"
+# Starting the dispatch process and logging the event.
+# Початок процесу диспатчу, запис у лог.
+
+# Avoid early workspace focus issues by switching workspace first.
+# Уникаємо проблем з раннім фокусом, спочатку переключаємо воркспейс.
+hyprctl dispatch workspace "$TARGET_WORKSPACE" >> "$LOGFILE" 2>&1
+sleep 0.4
+
+# Launch the application in the background and disown it.
+# Запускаємо аплікацію у фоновому режимі та відв’язуємо від терміналу.
+$APP & disown
+pid=$!
+
+echo "Launched '$APP' with PID $pid" >> "$LOGFILE"
+# Log the launched process ID.
+# Лог процесу запуску з PID.
+
+# 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")
+
+ 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
+ fi
+ sleep 0.3
+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
diff --git a/config/hypr/scripts/Tak0-Per-Window-Switch.sh b/config/hypr/scripts/Tak0-Per-Window-Switch.sh
new file mode 100755
index 00000000..76b6ad2d
--- /dev/null
+++ b/config/hypr/scripts/Tak0-Per-Window-Switch.sh
@@ -0,0 +1,123 @@
+##################################################################
+# #
+# #
+# 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"
+CFG_FILE="$HOME/.config/hypr/UserConfigs/UserSettings.conf"
+ICON="$HOME/.config/swaync/images/ja.png"
+SCRIPT_NAME="$(basename "$0")"
+
+# Ensure map file exists
+touch "$MAP_FILE"
+
+# Read layouts from config
+if ! grep -q 'kb_layout' "$CFG_FILE"; then
+ echo "Error: cannot find kb_layout in $CFG_FILE" >&2
+ exit 1
+fi
+kb_layouts=($(grep 'kb_layout' "$CFG_FILE" | cut -d '=' -f2 | tr -d '[:space:]' | tr ',' ' '))
+count=${#kb_layouts[@]}
+
+# Get current active window ID
+get_win() {
+ hyprctl activewindow -j | jq -r '.address // .id'
+}
+
+# Get available keyboards
+get_keyboards() {
+ hyprctl devices -j | jq -r '.keyboards[].name'
+}
+
+# Save window-specific layout
+save_map() {
+ local W=$1 L=$2
+ grep -v "^${W}:" "$MAP_FILE" > "$MAP_FILE.tmp"
+ echo "${W}:${L}" >> "$MAP_FILE.tmp"
+ mv "$MAP_FILE.tmp" "$MAP_FILE"
+}
+
+# Load layout for window (fallback to default)
+load_map() {
+ local W=$1
+ local E
+ E=$(grep "^${W}:" "$MAP_FILE")
+ [[ -n "$E" ]] && echo "${E#*:}" || echo "${kb_layouts[0]}"
+}
+
+# Switch layout for all keyboards to layout index
+do_switch() {
+ local IDX=$1
+ for kb in $(get_keyboards); do
+ hyprctl switchxkblayout "$kb" "$IDX" 2>/dev/null
+ done
+}
+
+# Toggle layout for current window only
+cmd_toggle() {
+ local W=$(get_win)
+ [[ -z "$W" ]] && return
+ local CUR=$(load_map "$W")
+ local i NEXT
+ for idx in "${!kb_layouts[@]}"; do
+ if [[ "${kb_layouts[idx]}" == "$CUR" ]]; then
+ i=$idx
+ break
+ fi
+ done
+ NEXT=$(( (i+1) % count ))
+ do_switch "$NEXT"
+ save_map "$W" "${kb_layouts[NEXT]}"
+ notify-send -u low -i "$ICON" "kb_layout: ${kb_layouts[NEXT]}"
+}
+
+# Restore layout on focus
+cmd_restore() {
+ local W=$(get_win)
+ [[ -z "$W" ]] && return
+ local LAY=$(load_map "$W")
+ for idx in "${!kb_layouts[@]}"; do
+ if [[ "${kb_layouts[idx]}" == "$LAY" ]]; then
+ do_switch "$idx"
+ break
+ fi
+ done
+}
+
+# Listen to focus events and restore window-specific layouts
+subscribe() {
+ local SOCKET2="$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock"
+ [[ -S "$SOCKET2" ]] || { echo "Error: Hyprland socket not found." >&2; exit 1; }
+
+ socat -u UNIX-CONNECT:"$SOCKET2" - | while read -r line; do
+ [[ "$line" =~ ^activewindow ]] && cmd_restore
+ done
+}
+
+# Ensure only one listener
+if ! pgrep -f "$SCRIPT_NAME.*--listener" >/dev/null; then
+ subscribe --listener &
+fi
+
+# CLI
+case "$1" in
+ toggle|"") cmd_toggle ;;
+ *) echo "Usage: $SCRIPT_NAME [toggle]" >&2; exit 1 ;;
+esac
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage