Search code examples
objective-ccmacosapplescript

Sending requests to System Events from Objective-C/C?


Is there any way to convert the following applescript to Objective-C/C?

tell application "System Events" to set visible of process "Safari" to false

I know I could execute this applescript in Objective-C using the NSAppleScript class or calling system("osascript -e '...'"), however isn't there another way?

How does applescript do this?

Alternatively can I hide a window from another application from Objective-C/C?

Update:

I have found out that you can use SBApplication class to do this:

SBApplication *SystemEvents = [SBApplication applicationWithBundleIdentifier:@"com.apple.systemevents"];
/*SystemEventsApplicationProcess*/ id Safari = [[SystemEvents performSelector:@selector(applicationProcesses)] objectWithName:@"Safari"];
[Safari setVisible:NO]; // Doesn't work!

However this doesn't work as setVisible probably doesn't do what I think.

This is the class hierarchy of SystemEventsApplicationProcess:

SystemEventsApplicationProcess : SystemEventsProcess : SystemEventsUIElement : SystemEventsItem : SBObject : NSObject

And here are the methods available for these SystemEventsXXX classes:

SystemEventsApplicationProcess
    applicationFile

SystemEventsProcess
    setVisible:
    visible
    unixId
    totalPartitionSize
    shortName
    partitionSpaceUsed
    name
    id
    hasScriptingTerminology
    setFrontmost:
    frontmost
    fileType
    file
    displayedName
    creatorType
    Classic
    bundleIdentifier
    backgroundOnly
    architecture
    acceptsRemoteEvents
    acceptsHighLevelEvents
    windows
    menuBars

SystemEventsUIElement
    select
    clickAt:
    setValue:
    value
    title
    subrole
    setSize:
    size
    setSelected:
    selected
    roleDescription
    role
    setPosition:
    position
    orientation
    name
    minimumValue
    maximumValue
    help
    setFocused:
    focused
    entireContents
    enabled
    objectDescription
    objectClass
    accessibilityDescription
    windows
    valueIndicators
    UIElements
    toolBars
    textFields
    textAreas
    tables
    tabGroups
    staticTexts
    splitterGroups
    splitters
    sliders
    sheets
    scrollBars
    scrollAreas
    rows
    relevanceIndicators
    radioGroups
    radioButtons
    progressIndicators
    popUpButtons
    popOvers
    outlines
    menuItems
    menuButtons
    menuBarItems
    menuBars
    menus
    lists
    incrementors
    images
    growAreas
    groups
    drawers
    comboBoxes
    columns
    colorWells
    checkboxes
    buttons
    busyIndicators
    browsers
    attributes
    actions

SystemEventsItem
    setName:
    name
    id
    removeActionFromUsingActionName:usingActionNumber:
    pick
    keyUp
    keyDown
    increment
    editActionOfUsingActionName:usingActionNumber:
    doScript
    doFolderActionFolderActionCode:withItemList:withWindowSize:
    decrement
    confirm
    cancel
    attachedScripts
    attachActionToUsing:
    stop
    start
    saveAs:in:
    moveTo:
    exists
    duplicateTo:withProperties:
    delete
    closeSaving:savingIn:
    setProperties:
    properties
    objectClass

SBObject
    // ...
NSObject
    // ...

Solution

  • You can use NSRunningApplication, which represents (as its name implies) a running application, and has a -hide method.

    NSWorkspace will give you a list of all the running apps: [[NSWorkspace sharedWorkspace] runningApplications], which you can filter, or you can get the object representing Safari using its bundle identifier: +[NSRunningApplication runningApplicationsWithBundleIdentifier:] (note that actually returns an array in case there are multiple running instances of the same app).