Unexpected "On Open" Behavior

I’ve discovered that when a combination of files and folders are dropped on an On Open applet, the items are processed twice. First, the folders are processed, then the handler executes again, processing the files. This makes it difficult (impossible?) to get a single list of all the items dropped, regardless of type.

For example:

on open droppedItems
	say (count droppedItems)
end open

If the following five items are dropped…

2024-11-17_17-21-33

…the script will say “Two Three”, not “Five”. It runs twice: first for the folders, then for the files.

I can’t figure out a way to combine the two passes into a single list before passing it on for further processing. For various reasons having to do with my actual app, handling the items in two separate batches is undesirable.

For what it’s worth, it says ‘five’ to me.

I tested the OP’s code on my Sequoia computer and it said five. I also substitued a dialog for the say command, and all five files were returned in one dialog.

The OP posted the same question in the Late Night Software forum, and I’ve included Shane’s response below. I did not know this was an issue.

There’s never been any guarantee that all items will be passed together, although that certainly used to be the case in practice. The splitting into batches began happening with the introduction of Gatekeeper and file quarantining. As that’s grown more complex, split batches seem to have become more common.

It can be worked around but it requires AppleScriptObjC code, which has side-effects not everyone is happy about.

On Ventura, I get “on open” run twice

I have a workaround using the “on idle” handler, but it works immediately when dropped on the app when it is closed. If it is dropped on the app while it is already open, it has a long pause till the next idle event.

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

property didOpen : false
property droppedItems : {}

on open droppedStuff
	set didOpen to true
	set droppedItems to droppedItems & droppedStuff
end open

on idle
	if didOpen then
		say (count droppedItems)
		set didOpen to false
	end if
end idle

One way to avoid this is to not have the app be a stay-open app.

** EDIT ** - occasionally still not working, depending on the delay between successive runs of the “on open” handler.

It’s interesting that different testers get different results under Sequoia 15.1. I wonder what the determining factor might be, but it doesn’t really matter if it isn’t controllable.

I’m rewriting the app to drop some convenient but not crucial functionality which will avoid the problem.

Thanks for the notes.

This behavior is simply erratic and inconsistent. As @Shane_Stanley has already mentioned, some convoluted workarounds for this issue are available in Objective-C; I don’t know if it’s possible to replicate them in AppleScript.

The dropped file behavior works on some releases of macOS and does not on others.

Understanding that dropped items must be placed on a dragged items clipboard before they actually drop on an application, I decided to write an AppleScript/Objective-C solution to get the count of the items while on the dragged items clipboard and use that count in the application.

use framework "Foundation"
use scripting additions

property NSPasteboard : a reference to current application's NSPasteboard
property NSURL : a reference to current application's NSURL

on open these_items
	
	# get the dragged files and folders off of the dragged items clipboard before we get to the droplet
	set pbdrag to NSPasteboard's pasteboardWithName:(current application's NSPasteboardNameDrag)
	if pbdrag's types()'s containsObject:(current application's NSPasteboardTypeFileURL) then
		set dragged_items to (pbdrag's readObjectsForClasses:{NSURL's class} options:(missing value)) as list
	end if
	
	display dialog (count of dragged_items) as text
	
	set {TID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, return}
	display dialog (items of dragged_items) as text
	set AppleScript's text item delimiters to TID
	
end open

When I drag and drop 9 files onto a compiled application of the above, the count is correctly returned as 9 when performed on Sequoia v15.1.1, or earlier releases of macOS.

Alas, I get

type {} of «class ocid» id «data optr00000000809F680300600000» doesn’t understand the “containsObject_” message

at line 12. AS ObjC being a bit above my pay grade, I’m clueless. If you’ve time and are in the mood, line-by-line comments would be much appreciated.

Try changing types()'s to |types|()'s.

Thanks Shane.

I should have tested this in both Script Editor and Script Debugger and only did the former which was lax in its acceptance of types()'s.

Your recommendation for |types|()'s resolves things in Script Debugger v8.08 on macOS v15.1.1.