pkamb
pkamb

Reputation: 34983

AppleScript `activate` from Sandboxed app does not bring window to foreground

I am attempting to open System Preferences from a Sandboxed macOS application, so that the user can manually enable a certain preference.

AppleScript activate

Brings an application to the front, launching it if necessary.

I am running macOS 10.13.6 and Xcode 10.0. The Deployment Target is set to OS X 10.11.

I run the following AppleScript from a sandboxed app:

let script = """
             tell application "System Preferences"
                 activate
                 set current pane to pane id "com.apple.preferences.extensions"
             end tell
             """
let appleScript = NSAppleScript(source: script)
var errorInfo: NSDictionary? = nil
appleScript?.executeAndReturnError(&errorInfo)

I also add a scripting targets Sandbox Entitlement enabling System Preferences to reveal panes:

<key>com.apple.security.scripting-targets</key>
<dict>
    <key>com.apple.systempreferences</key>
    <array>
        <string>preferencepane.reveal</string>
    </array>
</dict>

This somewhat works, once I add the Entitlement. The Systems Preferences app launches if closed and opens the correct pane.

The errorInfo dictionary is nil and presents no error info.

In the console I see a message, which is perhaps unrelated log spam:

AppleEvents: received mach msg which wasn't complex type as expected in getMemoryReference.

System Preferences window does not activate or come to foreground.

However, the app does not activate. The System Preferences window does not come to the front. The app navigates to the correct tab, but does not come to the foreground as the docs for activate state. It remains behind any other foreground windows.

In the case where System Preferences is closed, the app does launch. But the window is not added to the screen in the foreground or background until you click the dock icon. The window then appears, already navigated to the correct pane.

Why does the app not activate?

Are there any other needed Sandbox Entitlements that will allow for activation of the System Preferences window?

Upvotes: 5

Views: 839

Answers (2)

danielpunkass
danielpunkass

Reputation: 17587

It seems like a bug to me that the activate command is not allowed from your script. However, I confirmed in a simple test application that even though I reproduce the behavior you described, the problem can be worked around by using NSWorkspace to launch System Preferences instead. This procedure has a side effect of activating the app if it is already launched. So, add code like this before your AppleScript executes:

NSWorkspace.shared.launchApplication(withBundleIdentifier: "com.apple.systempreferences", options: [], additionalEventParamDescriptor: nil, launchIdentifier: nil)

Something else weird: if you leave the "activate" in the script it seems to cause the running app to reactivate. So the complete workaround seems to require adding something like the above in code and removing the 'activate' from the script.

Upvotes: 1

jvarela
jvarela

Reputation: 3847

I suggest that you do the following (this was tested by me on macOS Mojave and works as intended).

  1. Open Script Editor
  2. Paste your script code into it (without the external quotes, of course)
  3. Save it as an app
  4. Go to the place in Finder where you saved it and with the right button click on "Show Package Contents".
  5. Go to Contents and the open Info.plist in Xcode
  6. Check the entitlements this app used, in particular the Privacy - AppleEvents Sending Usage Description (NSAppleEventsUsageDescription).
  7. Replicate that in your app, but please do not use all the entitlements this Applescript app uses by default, only the ones you really need.

Upvotes: 1

Related Questions