Problem in Big Sur with Finder object ?

I have a simple code block which works when run with Script Editor in Mojave:

tell application "Finder"
	set window_bounds to bounds of window of desktop
	set screen_width to item 3 of window_bounds as string
	set screen_height to item 4 of window_bounds as string
end tell
display dialog screen_width & return & screen_height

A user of my applet has reported to me that they get an error when they run that code in Big Sur:

I have much the same code in my applet which gives them the same error. They are running macOS version 11.0 Beta (20A5374i). My iMac can’t run Big Sur so I can’t verify the error.

Does anyone know of a change in Big Sur or another reason why that user would be getting the error ?

Thanks.

Hi Neophyte.

I currently have no intention of installing anything beyond Mojave, so I can’t test your code in context.

I think ‘window of desktop’ is a relic from the past which has just happened to work up till now as a way of addressing the desktop screen. Looking at the Finder’s dictionary, neither the desktop object nor the container class from which it inherits has a ‘window’ property. It does have a ‘container window’ property which produces the same result as your code in Mojave. It may be worth trying that as a first step.

For the past three years, I’ve been using an ASObjC method to get the main screen’s dimensions:

use AppleScript version "2.4" -- Mac OS 10.10 (Yosemite) or later.
use framework "Foundation"
use framework "AppKit"
use scripting additions

set screenFrame to current application's class "NSScreen"'s mainScreen()'s frame()

But even this is problematic. Before Mojave, it returned an AppleScript record which looked like this:
{origin:{x:0.0, y:0.0}, |size|:{width:2560.0, height:1440.0}}.

In Mojave (and presumably later), it returns a list which looks like this:
{{0.0, 0.0}, {2560.0, 1440.0}}

I’ve only needed the screen height and I’ve been able to get this on both my Mojave and El Capitan machines by adding the following line to the code above:

set screenHeight to current application's NSHeight(screenFrame) as integer

This works whether screenFrame is a list or a record — or did until last week! Since the latest Mojave security update, invoking the NSHeight() function has caused the script to quit silently — but only when it’s run directly from the system script menu. It still works perfectly when run in a script editor or as an application in its own right and another script using a library containing exactly the same code has no problem when run from the script menu. Don’t ask me if this is a bug or another security precaution! Rather than turn the problem script into an application, I’ve replaced the NSHeight() line with good old vanilla AS:

if (screenFrame's class is record) then
	set screenHeight to screenFrame's |size|'s height as integer
else if (screenFrame's class is list) then
	set screenHeight (item 2 of item 2 of screenFrame) as integer
end if

FWIW, it doesn’t seem to happen in Catalina, but it does in Big Sur beta. And it happens there with all the functions related to structs I’ve tested (eg, NSMakeRect()), and in editors as well.

That said, there’s been a “supplemental” 10.14.6 update this evening which appears to have fixed the issue in Mojave. frame() still returns a list, but NSHeight() doesn’t crash the script reading it when the script’s run from the script menu. However I think I’ll stick with the vanilla alternative for now. :wink:

And it looks like it’s fixed in the latest Big Sur beta, too.

For some time now I’ve been using “bounds of desktop’s window” to get screen dimensions and I hope they continue this in Big Sur or replace it with something similar… The Finder dictionary defines various window classes including desktop window but it returns no properties. The alternatives appear to be ASObjC or the system_profiler shell command but both of these are less desirable IMO in a simple AppleScript.

Interestingly, though, in Mojave, if you get the properties of ‘window of desktop’, the class shown is ‘desktop window’. However not all the other properties match those shown for a ‘desktop window’ in the Finder’s dictionary and the ‘target’ property is a only property of the ‘properties’ list, not of the window itself! Both the Finder’s scripting implementation and its dictionary are long overdue for an overhaul — that is if it’s being kept in Big Sur. :confused:

tell application "Finder"
	properties of window of desktop
	--> {class:desktop window, id:45, name:"", position:{0, 0}, bounds:{0, 0, 2560, 1440}, index:missing value, zoomed:false, closeable:false, titled:false, floating:false, modal:false, resizable:false, zoomable:false, visible:true, collapsed:false, target:desktop of application "Finder", current view:icon view, icon view options:icon view options of window of desktop of application "Finder"}
	target of (get properties of window of desktop)
	--> desktop of application "Finder"
	target of (get window of desktop)
	--> error "Finder got an error: Can’t get target of window of desktop." number -1728 from target of window of desktop
end tell

The fact that it works is arguably a bug. You’re asking for the bounds of whatever is returned by the desktop-object’s window property, but the desktop-object has no such property. Using “desktop’s window” is not the same as “desktop window” – the latter class seems completely broken (at least it does here).

According to the dictionary, you should be able to use “bounds of desktop’s container window”, and that does seem to work.

But both versions are useless if you have more than one screen.

Thanks Shane and Nigel. I tested my scripts with “bounds of desktop’s container window” and with “bounds of container window of desktop” under Catalina. Both worked fine. I’m going to upgrade to Big Sur when released and will retest then.

Sorry I’ve not responded recently (busy with family matters).

As I’d like my applet to work better on dual monitor setups I’ve switched to using system_profiler to get screen bounds. It is slower than getting Finder properties but produces an unambiguous result. Currently, to keep things somewhat simple, I’m positioning dialogs on the main display.

Cheers.

I wondered if display resolution might be an issue with some of the solutions and tested them with my 4K monitor. First, system_profiler:

do shell script "system_profiler SPDisplaysDataType"

Then Finder solution one:

tell application "Finder"
	bounds of desktop's window
end tell

And, Finder solution two:

tell application "Finder"
	bounds of desktop's container window
end tell

Then Nigel’s ASObjC solution:

use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions
set screenFrame to current application's class "NSScreen"'s mainScreen()'s frame()

For dual monitors, Shane’s solution in the following thread seems to work well (though I don’t have dual monitors for testing). It does return the looks-like resolution, which is necessary for many AppleScript uses with a 4K monitor.

https://forum.latenightsw.com/t/get-sizes-of-monitor-s-via-applescript/1351/3