3

I'm pretty sure my question is just a general syntax question, but including specific context in case it's relevant:

There's a Mac app called SwitchResX which lets you do cool things like create and use custom resolutions on Mac monitors. It has a background process called "SwitchResX Daemon" which is AppleScriptable.

Among other things:

  • application (class) has one or more display elements
  • display (class) has one or more mode elements
  • mode (class) has properties like height, width (integers), frequency (real), valid (boolean), etc.

I'm having two related problems:

Problem 1: whose/where X is in {...}

tell application "SwitchResX Daemon"
    set theDisplay to the second display
    
    set theModes1 to theDisplay's every mode where it is valid and ((its width is 3008) or (its width is 2560)) --> {mode 8 of display 2, mode 12 of display 2} = expected and desired result
    
    set theModes2 to theDisplay's every mode where it is valid and (its width is in {3008, 2560}) --> …error: Can’t make {3008, 2560} into type specifier.
    
end tell

I use if statements like if width is in {3008,2560} then ... a lot. Can the is in {...} condition not be used in a whose/where clause, or do I just the syntax wrong?

Problem 2: I have a need to split the filtering in at least one situation. So...

tell application "SwitchResX Daemon"
    set theDisplay to the second display
    
    set theModesAllValid to theDisplay's every mode where it is valid --> {……, mode 8 of display 2, mode 12 of display 2, ……} = expected and desired result
    
    set someModes1 to theModesAllValid's first item where ((its width is 3008) or (its width is 2560)) --> mode 8 of display 2 = expected and desired result
    set someModes2 to theModesAllValid's first item where (its width is in {3008, 2560}) --> same error as problem 1 above
    set someModes3 to theModesAllValid's every item where ((its width is 3008) or (its width is 2560)) --> error noted below**
    set someModes4 to theModesAllValid's every item where (its width is in {3008, 2560}) --> error noted below**
end tell

-- **error = "Can’t get {……, mode 8 of display 2 of application "SwitchResX Daemon", mode 12 of display 2 of application "SwitchResX Daemon", ……} whose width of it = 3008 or width of it = 2560."

So someModes1 (using first item instead of every item) works -- similar to theModes1 in Problem 1 (except item instead of list, as expected). And someModes2 gives the same error as theModes2 (so, consistent at least).

But then I would expect someModes3 and someModes4 to give the same results as Problem 1, but here the every breaks it somehow. Why is that? And even if there's no solution to Problem 1 (meaning someModes4 won't work), is there some way to break the filtering up into two steps for some derivative of someModes3 to work?

Thanks in advance for any help!

1 Answer 1

0

It's been 15 years since I messed with AppleScript and I don't have SwitchResX, but here are some clues:

  1. "Can’t make {3008, 2560} into type specifier."
set theModes2 to theDisplay's every mode where it is valid and (its width is in {3008, 2560})

AppleScript is weird because you can never quite tell if it is normally expected to work, if it could work if the developers used heroic efforts, or if it's totally impossible. App developers have a decent amount of leeway in how they implement and also half-implement their application dictionaries.

So, it's always a bunch of trial-and-error to make an AppleScript work.

The is in construct works differently inside a tell. LOL! You expected it would detect the presence of an item in a list, as it does outside a tell.

Inside a tell, I don't think is in usually works the way you expect here. I'm not sure if it could be made to work this way if an app developer put in enough elbow grease. I used to wish it worked that way, as I recall.

Here's an example of how is in works inside tell:

tell application "Google Chrome"
    get first window where "Apple" is in its tabs's title
end tell
  1. Two-part operation

I don't really know what you're trying to do here ultimately, but maybe the previous fragment can give you some clues on how you can achieve it in one or two statements.

Regardless, this looks like a bug in the app:

set someModes3 to theModesAllValid's every item where ((its width is 3008) or (its width is 2560))

C.f.:

tell application "Google Chrome"
    tell first window
        every tab where its title is "Google" or its title is "Apple"
    end tell
end tell

Anyway, even though every isn't working you can just loop through each condition instead. One big disaster in writing AppleScript is spending any time whatsoever caring about efficiency. You're using AppleScript! Just get it working and move on. :)

Let me know if I can clarify anything else.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .