diff options
| author | Ja.KooLit <85185940+JaKooLit@users.noreply.github.com> | 2025-07-27 01:26:41 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-27 01:26:41 +0900 |
| commit | e746b136dbc99f1fcaa648e6d14e5e8bb29b3df2 (patch) | |
| tree | f1a9ffc15b538cb8e769fb7ebceb80a51897634e | |
| parent | 7e958b7fdfb233d7c0ebd56aaf1935b7e4c4cba2 (diff) | |
| parent | d5eaaf7b63420f99ef7054623263f141cbbf8cf0 (diff) | |
Merge pull request #778 from tak0dan/Tak0-scripts
QoL scripts (Autodispatch, Keyboard layout switch)
| -rw-r--r-- | config/hypr/UserConfigs/UserKeybinds.conf | 3 | ||||
| -rwxr-xr-x | config/hypr/UserScripts/Tak0-Autodispatch.sh | 90 | ||||
| -rwxr-xr-x | config/hypr/scripts/Tak0-Autodispatch.sh | 90 | ||||
| -rwxr-xr-x | config/hypr/scripts/Tak0-Per-Window-Switch.sh | 123 |
4 files changed, 305 insertions, 1 deletions
diff --git a/config/hypr/UserConfigs/UserKeybinds.conf b/config/hypr/UserConfigs/UserKeybinds.conf index 70202ba4..dd18b971 100644 --- a/config/hypr/UserConfigs/UserKeybinds.conf +++ b/config/hypr/UserConfigs/UserKeybinds.conf @@ -64,7 +64,8 @@ bind = $mainMod CTRL, O, exec, hyprctl setprop active opaque toggle # disable op bind = $mainMod SHIFT, K, exec, $scriptsDir/KeyBinds.sh # search keybinds via rofi bind = $mainMod SHIFT, A, exec, $scriptsDir/Animations.sh #hyprland animations menu bind = $mainMod SHIFT, O, exec, $UserScripts/ZshChangeTheme.sh # Change oh-my-zsh theme -bindln = ALT_L, SHIFT_L, exec, $scriptsDir/SwitchKeyboardLayout.sh # Change keyboard layout +bindln = ALT_L, SHIFT_L, exec, $scriptsDir/SwitchKeyboardLayout.sh # Change keyboard layout globally +bindln = SHIFT_L, ALT_L, exec, $scriptsDir/Tak0-Per-Window-Switch.sh # Change keyboard layout locally for each window bind = $mainMod ALT, C, exec, $UserScripts/RofiCalc.sh # calculator (qalculate) diff --git a/config/hypr/UserScripts/Tak0-Autodispatch.sh b/config/hypr/UserScripts/Tak0-Autodispatch.sh new file mode 100755 index 00000000..a1f72129 --- /dev/null +++ b/config/hypr/UserScripts/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-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 |
