Suspend/Reanimate Applications [Fully Working Code]

This is a fully working finished script. You can copypasta the code below into Script Editor or from bitbucket (https://bitbucket.org/martindeering/applescript-suspend-or-reanimate-application).

Description:
Some applications do not have a pause button. They take CPU processing power and will not let it go until their job is finished. Other applications (particularly browsers) tend to have pages that will continue to process or refresh in the background, even when the browser is hidden. Apart from quitting these applications, there is another solution: Using the kill -STOP command via the Terminal.
If you open Activity Monitor, you will notice that the suspended application is now taking 0% CPU power, freeing up the CPU.

How to Use:
Run the script. Enter the full name of the application (as it appears in the Applications folder). Pressing OK will hide and suspend the application.
At this point, clicking the application icon in the dock will not do anything. The application will be unresponsive until it is re-animated.
To reanimate, run the script and enter the full name of the application that is suspended.

Modifications:
The app has one entry method: A dialog box asking for the name of the application. The script itself has the option of three different input methods. Text entry, choose from buttons, choose from list. Basically, if you are regularly suspending one or more applications the second or third inputs will be quicker, with no need for typing. You can then save that configuration as an application, or put it in the scripts folder in the menu bar (which is where I put it).

Other Notes/Warning:
¢ As with any Applescript app, sometimes the dialog box gets hidden behind other windows.
¢ More info in the comments in the script.
¢ The script will warn you if you try to suspend the Finder or the Dock. Use this at your own risk. I’ve included error handlers and a ‘copy’ button for the Terminal command should the script fail.
¢ If you suspend an application, and then later try to restart/shut-down, the system will notice the suspended application and see that it is unresponsive. This will throw up the ‘Force Quit’ dialogs. To avoid this, reanimate the application before restarting/shutting-down.

Any questions, suggestions or bugs, reply here.

(*
 * @author: Martin Deering martin.deering+applescript@gmail.com
 * @description: suspend or reanimate applications
 * @date: 20160810_1053
 * @lastupdate: na
 * @license: http://www.apache.org/licenses/LICENSE-2.0
 * AppleScript Version 2.5
 * OSX version: El Capitan 10.11.6
*)

# DESCRIPTION
(*
	Some applications do not have a pause button. They take CPU processing power and will not let it go until their job is finished. Other applications (particularly browsers) tend to have pages that will continue to process or refresh in the background, even when the browser is hidden. Apart from quitting these applications, there is another solution: Using the kill -STOP command via the Terminal.
	If you open Activity Monitor, after an application is suspended, you will notice that the application is taking 0% CPU power.
*)

# WARNING
(*
	1. This script will stop any recognised application. This can result in unexpected results, e.g. suspending the Dock will result in an inability to switch between applications that are not visible on the screen. Use at your own risk.
	2. Trying to log out/restart/shut down will be interrupted by any applications that are suspended (and hence not responding). You will be asked if you want to force quit that application. Doing so will cause unsaved changes to be lost. To combat this, stop the log-out/restart/shut-down process, run the script and reanimate the suspended applications. If you don't remember which applications are suspended, open Activity Monitor and look for applications that say "(not responding)" beside them.
*)

#INPUT METHODS
(*
	This script accepts three different kind of inputs. Only one of the input options should be uncommented at a time.
	¢ If you want to enter the name of the app to manipulate in a dialog box, then comment out input options 02 and 03 (this is the default setting)
	¢ If you have up to three applications that you regularly want to manipulate, then comment out input options 01 and 03, and enter the names of the applications in the buttons field
	¢ If you have more than three applications that you regularly want to suspend/reanimate, then comment out input options 01 and 02, and enter the names of the applications in the list
	¢ To comment/uncomment an input option, add or remove the --  before the (* and after the *)
*)

tell application "System Events"
	
	# DEFINE INPUT METHOD
	-- Start of input option 01. Enter the full name in the dialog box of whatever app you wish to manipulate
	--(*
	set the_application to display dialog "Enter the full name of the application (without the .app suffix)" with title "Suspend/Reanimate a Running Application" default answer ""
	set the_application to text returned of result
	--*)
	-- End of input option 01
	
	-- Start of input option 02. Ask user to choose button from up to 3 apps... replace the buttons with the exact name of the applications (without the .app suffix)
	(*
	display dialog "Choose the application" with title "Suspend/Reanimate a Running Application" buttons {"Safari", "Safari Technology Preview", "Google Chrome"}
	set the_application to button returned of result
	*)
	-- End of input option 02
	
	-- Start of input option 03. Ask user to choose from a list of apps... replace the list with the exact name of the applications (without the .app suffix)
	(*
	set application_list to {"Safari", "Safari Technology Preview", "Google Chrome", "Firefox"}
	set the_application to choose from list application_list with title "Choose App" with prompt "Choose an application to suspend/reanimate:"
	if the_application is false then -- the user clicked 'cancel'
		return
	end if
	*)
	-- End of input option 03
	
	
	# GET THE Process ID (PID) FOR THE CHOSEN APPLICATION
	try
		set the_pid to first process whose name is the_application
	on error error_message number error_number
		if error_number = -1719 then
			display dialog "\"" & the_application & "\" doesn't appear to be a running application." buttons {"Exit"} default button "Exit"
			return
		else
			display dialog "Sorry, error reported. 
Error message returned: " & error_message & "
Error number returned: " & error_number with title "Suspend/Reanimate a Running Application" buttons {"Exit"} default button "Exit"
			return
		end if
	end try
	try
		set the_application to name of the_pid -- Corrects an application name which has been entered with incorrect capitalisation
	on error error_message number error_number
		display dialog "Sorry, error reported. 
Error message returned: " & error_message & "
Error number returned: " & error_number with title "Suspend/Reanimate a Running Application" buttons {"Exit"} default button "Exit"
		return
	end try
	try
		set the_pid to unix id of the_pid
	on error error_message number error_number
		display dialog "Sorry, error reported trying to get the PID of " & the_application & ".
Error message returned: " & error_message & "
Error number returned: " & error_number with title "Suspend/Reanimate a Running Application" buttons {"Exit"} default button "Exit"
		return
	end try
	
	
	# GET THE STATUS OF THE PID
	-- A sample of possible status states codes:
	-- S (process running/sleeping/waiting for an event to complete) (usual response)
	-- T (process traced or stopped) (usual response)
	-- D (uninterruptible sleep, usually IO)
	-- I (marks a process that is idle, sleeping for longer than about 20 seconds)
	-- R (runnable. on run queue)
	-- U (marks a process in uninterruptible wait)
	-- Z (a defunct "zombie" process).
	
	-- For BSD formats and when the "stat" keyword is used, additional letters can be displayed:
	-- W (has no resident pages)
	-- < (high-priority process)
	-- N (low-priority task)
	-- L (has pages locked into memory for real-time and custom IO).
	
	-- run the shell script to find the status of the application
	tell me
		set current_process_status to do shell script ("ps -o stat " & the_pid)
		-- Returns "STAT  S" or "STAT T" etc.
		set current_process_status to word 2 of current_process_status
	end tell
	
	
	# WARN USER ABOUT SUSPENDING FINDER AND DOCK
	if (the_application = "Dock") and ((current_process_status contains "S") or (current_process_status contains "R")) then
		display dialog "Suspending the Dock will result in you being unable to switch between applications not visible on the screen." with title "Suspend/Reanimate a Running Application" buttons {"Cancel", "Continue"} default button "Cancel"
	end if
	if (the_application = "Finder") and ((current_process_status contains "S") or (current_process_status contains "R")) then
		display dialog "Suspending the Finder is not recommended. It may lead to unexpected results." with title "Suspend/Reanimate a Running Application" buttons {"Cancel", "Continue"} default button "Cancel"
	end if
	
	
	# TEST STATUS RETURNED AND TOGGLE THE RESPONSE VARIABLE (CONTinue or STOP)
	if (current_process_status contains "S") or (current_process_status contains "R") or (current_process_status contains "I") then
		set the_command to "-STOP "
		set application_state to "suspended"
		-- Hide the stopped app. If windows are open, then clicking on them will cause the spinning beachball. Better to hide the app
		tell application "System Events"
			set visible of process the_application to false
		end tell
		set application_visible to false
	else if current_process_status contains "T" then
		set the_command to "-CONT "
		set application_state to "running"
		set application_visible to true
		-- deal with other possible returns
	else if current_process_status contains "D" then
		display dialog "This application cannot be interrupted. It is waiting for a read/write command to disk. If it is misbehaving or hung, the only option is to force quit the application or to reboot.
This is the status that was returned: " & current_process_status with title "Suspend/Reanimate a Running Application" buttons {"OK"} default button "OK"
		return
	else if current_process_status contains "Z" then
		display dialog "This application cannot be interrupted. It is waiting for a parent process to query it.
This is the status that was returned: " & current_process_status with title "Suspend/Reanimate a Running Application" buttons {"OK"} default button "OK"
		return
	else -- An unrecognised status was returned
		display dialog "The status that was returned is not recognised: " & current_process_status with title "Suspend/Reanimate a Running Application" buttons {"OK"} default button "OK"
		return
	end if
	
	
	# RUN THE COMMAND TO SUSPEND/REANIMATE
	try
		tell me
			do shell script ("kill " & the_command & the_pid)
		end tell
	on error error_message number error_number
		set button_selection to display dialog "Toggling " & the_application & "'s state failed. 
Error message returned: " & error_message & "
Error number returned: " & error_number & "

If your application is suspended and you want to reanimate it, open Terminal and type (without quotes) \"kill -CONT " & the_pid & "\"" with title "Suspend/Reanimate a Running Application" buttons {"Copy to Clipboard", "Exit"}
		set button_returned to button returned of button_selection
		if button_returned is "Copy to Clipboard" then
			set the clipboard to "kill -CONT " & the_pid & ""
		end if
		return
	end try
	
	
	# VERIFY THE STATUS OF THE APPLICATION AND DISPLAY CONFIRMATION MESSAGE
	-- Get the status of the application pid
	tell me
		set returned_answer to do shell script ("ps -o stat " & the_pid)
	end tell
	set verified_process_status to word 2 of returned_answer
	
	-- Test that status, tell user result
	if verified_process_status contains "T" then
		-- The app was running and is now hidden
		display dialog "Process for " & the_application & " was running, and has now been suspended (and hidden when possible). The application will remain unresponsive until it's reanimated (run this again and enter the name of the application)." with title "Suspend/Reanimate a Running Application" buttons {"OK"} default button "OK"
	else if (verified_process_status contains "S") or (verified_process_status contains "R") or (verified_process_status contains "U") then
		-- The app was suspended and was hidden, so now unhide app
		tell application "System Events"
			set visible of process the_application to true
		end tell
		display dialog "Process for " & the_application & " was previously suspended, and is now running (and visible)." with title "Suspend/Reanimate a Running Application" buttons {"OK"} default button "OK"
	else -- An unrecognised status was returned
		if application_state = "suspended" then
			tell application "System Events"
				set visible of process the_application to true
			end tell
		end if
		set button_selection to display dialog "Could not verify if " & the_application & " has been toggled to " & application_state & ".

If your application is suspended and you want to reanimate it, open Terminal and type (without quotes) \"kill -CONT " & the_pid & "\"" with title "Suspend/Reanimate a Running Application" buttons {"Copy to Clipboard", "Exit"}
		set button_returned to button returned of button_selection
		if button_returned is "Copy to Clipboard" then
			set the clipboard to "kill -CONT " & the_pid & ""
		end if
		return
	end if
	
	
end tell