mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 22:07:03 +01:00
620 -> 163, with common.sh staying the single entry point that sources its own three parts - the shape the handoff prescribes for config.sh, so all 49 consumers are untouched. Verified by diffing `declare -F` after sourcing it against the same from a detached worktree at HEAD: an identical 48-function set. For a library this widely sourced that is the check that matters, not a passing lint. The FOCUS_APPS_* arrays moved with is_focus_app_running, the only function that reads them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
154 lines
4.1 KiB
Bash
Executable File
154 lines
4.1 KiB
Bash
Executable File
#!/bin/bash
|
|
# Focus-app detection, command checks and package installation.
|
|
#
|
|
# Sourced by common.sh, which stays the single entry point every script
|
|
# sources -- 49 of them, so the public surface must not change.
|
|
|
|
# Check if any focus app is running (window-based detection)
|
|
# Returns 0 if focus app found, 1 otherwise
|
|
# Echoes the name of the found app
|
|
# =============================================================================
|
|
# FOCUS APP DETECTION (for digital wellbeing scripts)
|
|
# =============================================================================
|
|
|
|
# Default focus apps - can be overridden before calling is_focus_app_running
|
|
FOCUS_APPS_WINDOWS=(
|
|
"Visual Studio Code"
|
|
"VSCodium"
|
|
"Cursor"
|
|
"IntelliJ IDEA"
|
|
"PyCharm"
|
|
"WebStorm"
|
|
"CLion"
|
|
"Rider"
|
|
"Sublime Text"
|
|
"Blender"
|
|
"Godot"
|
|
"Unity"
|
|
"Unreal Editor"
|
|
)
|
|
|
|
FOCUS_APPS_PROCESSES=(
|
|
"steam_app_"
|
|
"gamescope"
|
|
)
|
|
|
|
|
|
is_focus_app_running() {
|
|
# One xdotool call with a combined regex instead of N separate calls
|
|
if command -v xdotool &>/dev/null && [[ ${#FOCUS_APPS_WINDOWS[@]} -gt 0 ]]; then
|
|
local regex wid
|
|
printf -v regex '%s|' "${FOCUS_APPS_WINDOWS[@]}"
|
|
regex="${regex%|}" # strip trailing |
|
|
while IFS= read -r wid; do
|
|
[[ -n $wid ]] || continue
|
|
echo "focus app"
|
|
return 0
|
|
done < <(xdotool search --name "$regex" 2>/dev/null)
|
|
fi
|
|
|
|
# Check specific processes via /proc (no fork)
|
|
local app comm
|
|
for app in "${FOCUS_APPS_PROCESSES[@]}"; do
|
|
for comm in /proc/[0-9]*/comm; do
|
|
[[ -r $comm ]] || continue
|
|
read -r _proc_comm <"$comm" 2>/dev/null || continue
|
|
if [[ $_proc_comm == *"$app"* ]]; then
|
|
echo "$_proc_comm"
|
|
return 0
|
|
fi
|
|
done
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
# =============================================================================
|
|
# COMMAND AVAILABILITY
|
|
# =============================================================================
|
|
|
|
# Check if a command exists
|
|
# Usage: if require_command ffmpeg; then ...
|
|
require_command() {
|
|
local cmd="$1"
|
|
local pkg="${2:-$1}"
|
|
if ! command -v "$cmd" >/dev/null 2>&1; then
|
|
echo "Error: '$cmd' is not installed or not in PATH." >&2
|
|
echo "Install with: sudo pacman -S $pkg" >&2
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# Check for ImageMagick and display helpful installation message
|
|
# Usage: require_imagemagick [optional: "magick" or "convert"]
|
|
# Returns: Sets MAGICK_CMD variable to available command
|
|
require_imagemagick() {
|
|
local preferred="${1:-}"
|
|
|
|
if [[ $preferred == "magick" ]] || [[ -z $preferred ]]; then
|
|
if command -v magick &>/dev/null; then
|
|
MAGICK_CMD="magick"
|
|
export MAGICK_CMD
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
if [[ $preferred == "convert" ]] || [[ -z $preferred ]]; then
|
|
if command -v convert &>/dev/null; then
|
|
MAGICK_CMD="convert"
|
|
export MAGICK_CMD
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
echo "Error: ImageMagick is not installed." >&2
|
|
echo "Install it with:" >&2
|
|
echo " Arch Linux: sudo pacman -S imagemagick" >&2
|
|
echo " Ubuntu/Debian: sudo apt install imagemagick" >&2
|
|
return 1
|
|
}
|
|
|
|
# Install missing pacman packages
|
|
# Usage: install_missing_pacman_packages pkg1 pkg2 pkg3 ...
|
|
# Returns 0 if all packages installed successfully, 1 otherwise
|
|
install_missing_pacman_packages() {
|
|
local packages=("$@")
|
|
local missing=()
|
|
|
|
for pkg in "${packages[@]}"; do
|
|
if ! pacman -Qi "$pkg" >/dev/null 2>&1; then
|
|
missing+=("$pkg")
|
|
fi
|
|
done
|
|
|
|
if [[ ${#missing[@]} -eq 0 ]]; then
|
|
echo "[INFO] All required packages are already installed."
|
|
return 0
|
|
fi
|
|
|
|
echo "[INFO] Installing missing packages: ${missing[*]}"
|
|
if ! sudo pacman -S --needed --noconfirm "${missing[@]}"; then
|
|
echo "[ERROR] Failed to install packages" >&2
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# =============================================================================
|
|
# NOTIFICATION
|
|
# =============================================================================
|
|
|
|
# Send desktop notification (fails silently if notify-send not available)
|
|
# Usage: notify "Title" "Message" [urgency: low/normal/critical] [timeout_ms]
|
|
notify() {
|
|
local title="$1"
|
|
local message="$2"
|
|
local urgency="${3:-normal}"
|
|
local timeout="${4:-5000}"
|
|
|
|
if command -v notify-send &>/dev/null; then
|
|
notify-send -u "$urgency" -t "$timeout" "$title" "$message" 2>/dev/null || true
|
|
fi
|
|
}
|