Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions ahk/GUI/WM.ahk
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ ProcessSetPriority("Normal")
MatchList := ""
ExclusionList := ["ShellExperienceHost.exe", "SearchUI.exe"]
LastSaved := Map() ; Cache for last saved positions to avoid redundant INI writes
LastSaved.CaseSense := "Off"
PendingWrites := Map()
PendingWrites.CaseSense := "Off"

; Build initial list of windows
try {
Expand All @@ -33,6 +36,7 @@ try {

; Main loop - monitor windows and save/restore positions
SetTimer(MonitorWindows, 350)
SetTimer(ProcessPendingWrites, 1000)
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The debounce behavior here can exceed the stated 1000ms: the timer runs every 1000ms and you also require >= 1000 elapsed, so the actual write can happen ~1000–2000ms after the last change depending on timer alignment. If the intent is “write 1000ms after inactivity”, consider using a shorter polling interval (e.g., 250ms) or switching to a one-shot timer that gets reset on each change (e.g., schedule ProcessPendingWrites with a negative period on updates).

Copilot uses AI. Check for mistakes.

MonitorWindows() {
global MatchList, ExclusionList, LastSaved
Expand Down Expand Up @@ -76,7 +80,7 @@ MonitorWindows() {
}

SaveCurrentWindowPosition() {
global ExclusionList, LastSaved
global ExclusionList, LastSaved, PendingWrites

try {
WinGetPos(&X, &Y, &Width, &Height, "A")
Expand All @@ -102,9 +106,27 @@ SaveCurrentWindowPosition() {
; Only write if position/size changed
currentValue := X . "," . Y . "," . Width . "," . Height
if (!LastSaved.Has(active_ProcessName) || LastSaved[active_ProcessName] != currentValue) {
IniWrite(currentValue, A_ScriptDir . "\WindowSizePosLog.ini", "Process Names", active_ProcessName)
LastSaved[active_ProcessName] := currentValue
PendingWrites[active_ProcessName] := A_TickCount
}
}
}
}

ProcessPendingWrites() {
global PendingWrites, LastSaved
currentTime := A_TickCount
keysToDelete := []
for processName, lastChangeTime in PendingWrites {
if (currentTime - lastChangeTime >= 1000) {
if (LastSaved.Has(processName)) {
currentValue := LastSaved[processName]
IniWrite(currentValue, A_ScriptDir . "\WindowSizePosLog.ini", "Process Names", processName)
}
keysToDelete.Push(processName)
Comment on lines +124 to +126
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ProcessPendingWrites() calls IniWrite() without any error handling. If the INI write fails (file locked, permission issues, etc.), the timer thread can throw and potentially stop processing future pending writes. Consider wrapping the write in a try and only removing the entry from PendingWrites after a successful write (or keeping it queued to retry).

Suggested change
IniWrite(currentValue, A_ScriptDir . "\WindowSizePosLog.ini", "Process Names", processName)
}
keysToDelete.Push(processName)
try {
IniWrite(currentValue, A_ScriptDir . "\WindowSizePosLog.ini", "Process Names", processName)
keysToDelete.Push(processName)
} catch e {
OutputDebug("WM.ahk: Failed to write INI for process '" . processName . "': " . e.Message)
}
}

Copilot uses AI. Check for mistakes.
}
}
for key in keysToDelete {
PendingWrites.Delete(key)
}
}
Loading