A simple "Please wait" message

I’ve seen many complex methods for creating a “Please wait” message that can display while an AppleScript does something that takes a long time while showing no activity on screen. I asked Claude Code to come up with something, and it produced the linked code (after a few failed attempts which it managed to fix when prompted to do so):

I think you might want “progress.”

As for Claude, I’ve been using CHAT GPT with better results, but I have set up a GPT specifically for AppleScript. ChatGPT - AppleScript Expert

Prompt:

Can you show me how to show a please wait message that displays when an applescript is taking a long time to execute?

Here’s one of three scripts it generated on first pass without editing:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions


property debugMode : true

set currentStage to "Starting"

try
	
	-- INITIALIZE PROGRESS
	set currentStage to "Initializing progress"
	
	set progress total steps to 100
	set progress completed steps to 0
	set progress description to "Processing Files"
	set progress additional description to "Preparing..."
	
	-- SIMULATED LONG TASK
	repeat with i from 1 to 100
		
		set currentStage to "Processing item " & i
		
		-- Update progress UI
		set progress completed steps to i
		set progress additional description to "Working on item " & i & " of 100"
		
		-- Simulate work
		delay 0.1
		
	end repeat
	
	-- RESET PROGRESS
	set currentStage to "Cleaning up"
	
	set progress description to ""
	set progress additional description to ""
	set progress completed steps to 0
	
	display notification "Completed successfully" with title "AppleScript"
	
on error errMsg number errNum
	
	log "ERROR"
	log "Stage: " & currentStage
	log "Error Number: " & errNum
	log "Error Message: " & errMsg
	
	display dialog "Error during: " & currentStage & return & return & errMsg buttons {"OK"} default button 1
	
end try

This is the second method, but it didn’t compile and at runtime complained that the status window wasn’t showing in main thread. With a little back and forth I think it could get it right.


use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions

property statusWindow : missing value
property statusField : missing value

property debugMode : true

set currentStage to "Starting"

try
	
	my ShowStatusWindow("Please wait...", "Processing data...")
	
	set currentStage to "Running long task"
	
	repeat with i from 1 to 10
		
		my UpdateStatusText("Processing item " & i & " of 10")
		
		delay 1
		
	end repeat
	
	my CloseStatusWindow()
	
	display notification "Finished" with title "AppleScript"
	
on error errMsg number errNum
	
	my CloseStatusWindow()
	
	log "ERROR"
	log "Stage: " & currentStage
	log "Error Number: " & errNum
	log "Error Message: " & errMsg
	
	display dialog errMsg buttons {"OK"}
	
end try

on ShowStatusWindow(windowTitle, messageText)
	
	set windowRect to current application's NSMakeRect(0, 0, 420, 120)
	
	set statusWindow to current application's NSWindow's alloc()'s initWithContentRect:windowRect styleMask:1 backing:2 defer:true
	
	statusWindow's setTitle:windowTitle
	
	set statusField to current application's NSTextField's alloc()'s initWithFrame:(current application's NSMakeRect(20, 40, 380, 24))
	
	statusField's setStringValue:messageText
	statusField's setBezeled:false
	statusField's setDrawsBackground:false
	statusField's setEditable:false
	statusField's setSelectable:false
	
	(statusWindow's contentView()'s addSubview:statusField)
	
	statusWindow's center()
	statusWindow's makeKeyAndOrderFront:me
	
end ShowStatusWindow

on UpdateStatusText(messageText)
	statusField's setStringValue:messageText
end UpdateStatusText

on CloseStatusWindow()
	if statusWindow is not missing value then
		statusWindow's close()
	end if
end CloseStatusWindow

First, now I regret letting my ChatGPT subscription lapse - I’ll renew and start using your expert. Thank you. But Claude Code did a very good job sorting out errors in a few of my AppleScript apps and solved a problem in a script that I had running in Mac OS 9 in the SheepShaver emulator.

Meanwhile, for my purposes, I didn’t need or want a “progress” indicator, because I wanted to use a simple “please wait” while copying an enormous file from one place to another. However, your first example seems to do exactly what’s needed for a progress indicator. Thank you for it!

The following works for me:


use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions

property statusWindow : missing value
property statusField : missing value

--property debugMode : true

set currentStage to "Starting"

try
    my performSelectorOnMainThread:"ShowStatusWindow:" withObject:{"Please wait...", "Processing data..."} waitUntilDone:true
	-- my ShowStatusWindow("Please wait...", "Processing data...")
	
	set currentStage to "Running long task"
	
	repeat with i from 1 to 10
		
		my UpdateStatusText("Processing item " & i & " of 10")
		
		delay 1
		
	end repeat
	
	my CloseStatusWindow()
	
	display notification "Finished" with title "AppleScript"
	
on error errMsg number errNum
	
	my CloseStatusWindow()
	
	log "ERROR"
	log "Stage: " & currentStage
	log "Error Number: " & errNum
	log "Error Message: " & errMsg
	
	display dialog errMsg buttons {"OK"}
	
end try

on ShowStatusWindow:theParameters
	
	set {windowTitle, messageText} to theParameters --of sender
	
	set windowRect to current application's NSMakeRect(0, 0, 420, 120)
	
	set statusWindow to current application's NSWindow's alloc()'s initWithContentRect:windowRect styleMask:1 backing:2 defer:true
	
	statusWindow's setTitle:windowTitle
	
	set statusField to current application's NSTextField's alloc()'s initWithFrame:(current application's NSMakeRect(20, 40, 380, 24))
	
	statusField's setStringValue:messageText
	statusField's setBezeled:false
	statusField's setDrawsBackground:false
	statusField's setEditable:false
	statusField's setSelectable:false
	
	(statusWindow's contentView()'s addSubview:statusField)
	
	statusWindow's |center|()
	statusWindow's makeKeyAndOrderFront:me
	
end ShowStatusWindow:

on UpdateStatusText(messageText)
	statusField's setStringValue:messageText
end UpdateStatusText

on CloseStatusWindow()
	if statusWindow is not missing value then
		statusWindow's |close|()
	end if
end CloseStatusWindow

Save as applet.