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…
…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.
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.
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.
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.