Attempt to improve the watchdog because it has failed on some systems.
This commit is contained in:
+64
-32
@@ -17,9 +17,40 @@
|
|||||||
checkInterval=3 # Check every 3 seconds
|
checkInterval=3 # Check every 3 seconds
|
||||||
timeoutSeconds=2 # Consider i3 locked if it doesn't respond within 2 seconds
|
timeoutSeconds=2 # Consider i3 locked if it doesn't respond within 2 seconds
|
||||||
pidFile="${HOME}/.config/i3/i3_watchdog.pid"
|
pidFile="${HOME}/.config/i3/i3_watchdog.pid"
|
||||||
|
logFile="/tmp/i38-i3-watchdog-${UID}.log"
|
||||||
|
maxLogBytes=262144
|
||||||
|
|
||||||
|
rotate_log() {
|
||||||
|
local logSize
|
||||||
|
|
||||||
|
[[ -f "$logFile" ]] || return 0
|
||||||
|
logSize=$(wc -c < "$logFile")
|
||||||
|
if ((logSize >= maxLogBytes)); then
|
||||||
|
mv -f -- "$logFile" "${logFile}.old"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
log_message() {
|
log_message() {
|
||||||
echo "[i3-watchdog] $*"
|
local message
|
||||||
|
|
||||||
|
message="[i3-watchdog] $* - $(date '+%Y-%m-%d %H:%M:%S')"
|
||||||
|
|
||||||
|
rotate_log
|
||||||
|
printf '%s\n' "$message"
|
||||||
|
printf '%s\n' "$message" >> "$logFile"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_health() {
|
||||||
|
ipcWorks=0
|
||||||
|
focusWorks=0
|
||||||
|
|
||||||
|
if timeout "$timeoutSeconds" i3-msg -t get_version > /dev/null 2>&1; then
|
||||||
|
ipcWorks=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if timeout 1 xdotool getwindowfocus > /dev/null 2>&1; then
|
||||||
|
focusWorks=1
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Kill any existing watchdog instances
|
# Kill any existing watchdog instances
|
||||||
@@ -50,17 +81,7 @@ while true; do
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Try to communicate with i3 IPC AND check X focus
|
# Try to communicate with i3 IPC AND check X focus
|
||||||
ipcWorks=0
|
check_health
|
||||||
focusWorks=0
|
|
||||||
|
|
||||||
if timeout "$timeoutSeconds" i3-msg -t get_version > /dev/null 2>&1; then
|
|
||||||
ipcWorks=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Also check if X focus is working (use current DISPLAY, not hardcoded)
|
|
||||||
if timeout 1 xdotool getwindowfocus > /dev/null 2>&1; then
|
|
||||||
focusWorks=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Both must work for system to be healthy
|
# Both must work for system to be healthy
|
||||||
if [[ $ipcWorks -eq 1 ]] && [[ $focusWorks -eq 1 ]]; then
|
if [[ $ipcWorks -eq 1 ]] && [[ $focusWorks -eq 1 ]]; then
|
||||||
@@ -101,7 +122,7 @@ while true; do
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Try to get i3 socket info
|
# Try to get i3 socket info
|
||||||
i3Socket=$(i3 --get-socketpath 2>/dev/null)
|
i3Socket=$(timeout "$timeoutSeconds" i3 --get-socketpath 2>/dev/null)
|
||||||
log_message "i3 socket path: $i3Socket"
|
log_message "i3 socket path: $i3Socket"
|
||||||
|
|
||||||
if [[ -n "$i3Socket" ]] && [[ -S "$i3Socket" ]]; then
|
if [[ -n "$i3Socket" ]] && [[ -S "$i3Socket" ]]; then
|
||||||
@@ -112,43 +133,54 @@ while true; do
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if this is a focus issue (Wine keyboard grab bug)
|
# Check if this is a focus issue (Wine keyboard grab bug)
|
||||||
focusCheck=$(xdotool getwindowfocus 2>&1)
|
focusCheck=$(timeout 1 xdotool getwindowfocus 2>&1)
|
||||||
log_message "Focus check result: $focusCheck"
|
log_message "Focus check result: $focusCheck"
|
||||||
|
|
||||||
# Try to reset focus to i3
|
# Try to reset focus to i3
|
||||||
log_message "Attempting to reset X focus..."
|
log_message "Attempting to reset X focus..."
|
||||||
xdotool key --clearmodifiers Super_L 2>/dev/null
|
timeout 1 xdotool key --clearmodifiers Super_L 2>/dev/null
|
||||||
sleep 0.5
|
sleep 0.5
|
||||||
|
|
||||||
# Try to focus on i3's root window
|
# Try to focus on i3's root window
|
||||||
i3RootWindow=$(xdotool search --class "i3" | head -1)
|
i3RootWindow=$(timeout 1 xdotool search --class "i3" 2>/dev/null | head -1)
|
||||||
if [[ -n "$i3RootWindow" ]]; then
|
if [[ -n "$i3RootWindow" ]]; then
|
||||||
log_message "Focusing i3 root window: $i3RootWindow"
|
log_message "Focusing i3 root window: $i3RootWindow"
|
||||||
xdotool windowfocus "$i3RootWindow" 2>/dev/null
|
timeout 1 xdotool windowfocus "$i3RootWindow" 2>/dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Try i3-msg to focus something
|
# Try i3-msg to focus something
|
||||||
log_message "Using i3-msg to focus workspace..."
|
log_message "Using i3-msg to focus workspace..."
|
||||||
i3-msg workspace number 1 >/dev/null 2>&1
|
timeout "$timeoutSeconds" i3-msg workspace number 1 >/dev/null 2>&1
|
||||||
sleep 0.5
|
sleep 0.5
|
||||||
i3-msg focus output primary >/dev/null 2>&1
|
timeout "$timeoutSeconds" i3-msg focus output primary >/dev/null 2>&1
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
# Check if focus is actually fixed now
|
# Recovery is successful only if both i3 IPC and X focus work.
|
||||||
if timeout 1 xdotool getwindowfocus >/dev/null 2>&1; then
|
check_health
|
||||||
log_message "Focus recovery successful!"
|
if [[ $ipcWorks -eq 1 ]] && [[ $focusWorks -eq 1 ]]; then
|
||||||
else
|
log_message "Recovery successful"
|
||||||
log_message "Focus still broken - restarting i3..."
|
|
||||||
i3-msg -t run_command restart
|
|
||||||
log_message "Restart command sent"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Wait for restart to complete
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
# Reset counters
|
|
||||||
lastSuccessTime=$(date +%s)
|
lastSuccessTime=$(date +%s)
|
||||||
consecutiveFailures=0
|
consecutiveFailures=0
|
||||||
|
else
|
||||||
|
log_message "Recovery incomplete - IPC:$ipcWorks Focus:$focusWorks; restarting i3"
|
||||||
|
if timeout "$timeoutSeconds" i3-msg -t run_command restart >/dev/null 2>&1; then
|
||||||
|
log_message "Restart command accepted"
|
||||||
|
else
|
||||||
|
log_message "Restart command failed or timed out"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Wait for restart to complete, then verify it actually recovered.
|
||||||
|
sleep 5
|
||||||
|
check_health
|
||||||
|
if [[ $ipcWorks -eq 1 ]] && [[ $focusWorks -eq 1 ]]; then
|
||||||
|
log_message "i3 healthy after restart"
|
||||||
|
lastSuccessTime=$(date +%s)
|
||||||
|
consecutiveFailures=0
|
||||||
|
else
|
||||||
|
log_message "i3 still unhealthy after restart - IPC:$ipcWorks Focus:$focusWorks"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
Reference in New Issue
Block a user