Created
February 4, 2025 14:16
-
-
Save Nyaacinth/8693b8cb003f94c8f0a59ffd81152a7b to your computer and use it in GitHub Desktop.
macOS - Automatically close inactive apps with a grace period
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Original: https://github.com/Jeffrey-Fazal/close_apps | |
while true; do | |
echo "Starting script to close apps without windows..." | |
osascript <<'EOF' | |
use framework "Foundation" | |
use framework "AppKit" | |
use scripting additions | |
-- Variables | |
set gracefullyClosedApps to {} | |
set failedToCloseApps to {} | |
set systemApps to {"Finder", "Dock", "System Settings", "System Events", "loginwindow", "Terminal", "iTerm2", "iTerm"} | |
-- Get detailed info about running apps using NSWorkspace | |
set runningAppsInfo to {} | |
set nsRunningApps to current application's NSWorkspace's sharedWorkspace()'s runningApplications() as list | |
repeat with rApp in nsRunningApps | |
set nsName to (rApp's localizedName()) as text | |
if nsName is missing value then | |
set nsName to "UnknownAppName" | |
end if | |
set nsBundleID to rApp's bundleIdentifier() | |
if nsBundleID is missing value then | |
set nsBundleID to "UnknownBundleID" | |
else | |
set nsBundleID to nsBundleID as text | |
end if | |
set end of runningAppsInfo to {appName:nsName, bundleID:nsBundleID} | |
end repeat | |
-- Lookup app info by name | |
on lookupAppInfo(appName, appList) | |
repeat with itemRecord in appList | |
if appName is (itemRecord's appName) then | |
return itemRecord | |
end if | |
end repeat | |
return {appName:appName, bundleID:"UnknownBundleID"} | |
end lookupAppInfo | |
-- Process running processes | |
tell application "System Events" | |
set runningProcesses to every process whose background only is false | |
end tell | |
set windowCountZeroApps to {} | |
repeat with proc in runningProcesses | |
try | |
set appName to name of proc as text | |
if systemApps does not contain appName then | |
set appInfo to lookupAppInfo(appName, runningAppsInfo) | |
set bundleID to (appInfo's bundleID) | |
tell application "System Events" | |
try | |
set windowCount to count of windows of process appName | |
on error | |
set windowCount to 0 | |
end try | |
end tell | |
if windowCount is 0 then | |
set end of windowCountZeroApps to appName | |
end if | |
end if | |
end try | |
end repeat | |
if length of windowCountZeroApps is not 0 then | |
delay 2 | |
end if | |
repeat with appName in windowCountZeroApps | |
try | |
tell application "System Events" | |
try | |
set windowCount to count of windows of process appName | |
on error | |
set windowCount to 0 | |
end try | |
end tell | |
if windowCount is 0 then | |
-- Attempt graceful quit | |
try | |
tell application appName to quit | |
on error | |
set end of failedToCloseApps to appName | |
end try | |
end if | |
end try | |
end repeat | |
-- Summary | |
log " | |
Summary: | |
---------" | |
if (count of gracefullyClosedApps) > 0 then | |
log "Gracefully closed apps: " & gracefullyClosedApps | |
else | |
log "Gracefully closed apps: None" | |
end if | |
if (count of failedToCloseApps) > 0 then | |
log "Failed to close apps: " & failedToCloseApps | |
else | |
log "Failed to close apps: None" | |
end if | |
tell application "System Events" | |
set remainingApps to name of every process whose background only is false | |
set remainingNonSystemApps to {} | |
repeat with rApp in remainingApps | |
set rAppName to rApp as text | |
if systemApps does not contain rAppName then | |
set end of remainingNonSystemApps to rAppName | |
end if | |
end repeat | |
end tell | |
if (count of remainingNonSystemApps) > 0 then | |
log "Remaining open apps: " & remainingNonSystemApps | |
else | |
log "No non-system apps remaining open" | |
end if | |
log "Script completed." | |
EOF | |
echo "Script finished execution." | |
sleep 2 | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment