I'm trying to create a launch agent, which launches an AppleScript whenever a mouse is connected. Similar to these two questions:

However, once I load my launch agent (via launchctl load), it keeps getting started every 5-or-so seconds. How do I ensure that the agent runs only once, when the mouse is connected?

Here is my agent (plist):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>com.automations.switchscrolldirection</string>
    <key>ProgramArguments</key>
    <array>
        <string>osascript</string>
        <string>/Users/lirik/Documents/Automation/SwitchScrollDirectionOnMouseEvent.scpt</string>
    </array>
    <key>LaunchEvents</key>
    <dict>
        <key>com.apple.iokit.matching</key>
        <dict>
            <key>com.apple.device-attach</key>
            <dict>
                <key>idProduct</key>
                <integer>49277</integer>
                <key>idVendor</key>
                <integer>1133</integer>
                <key>IOProviderClass</key>
                <string>IOUSBDevice</string>
                <key>IOMatchStream</key>
                <true/>
                <key>IOMatchLaunchStream</key>
                <true/>
            </dict>
        </dict>
    </dict>
</dict>
</plist>

The AppleScript in question:

on gamingMouseIsAttached()
    tell application "System Preferences"
        activate
        set current pane to pane "com.apple.preference.mouse"
    end tell
    tell application "System Events" to tell process "System Preferences"
        repeat until exists checkbox 1 of window "Mouse"
        end repeat
        tell checkbox 1 of window "Mouse" to if value is 1 then click
    end tell
    tell application "System Preferences" to quit
end gamingMouseIsAttached

on TrackpadIsAttached()
    tell application "System Preferences"
        activate
        set current pane to pane "com.apple.preference.trackpad"
    end tell
    tell application "System Events" to tell application process "System Preferences"
        repeat until exists checkbox 1 of tab group 1 of window "Trackpad"
        end repeat
        tell checkbox 1 of tab group 1 of window 1 to if value is 0 then click
    end tell
    tell application "System Preferences" to quit
end TrackpadIsAttached

tell current application
    delay 15
    set internalTrackpad to (do shell script "system_profiler SPUSBDataType | awk '/Trackpad:/ { print \"Internal Trackpad\" }'")
    set gamingMouse to (do shell script "system_profiler SPUSBDataType | awk '/Gaming Mouse G502:/ { print \"Gaming Mouse\" }'")

    if gamingMouse is equal to "" then
        if internalTrackpad is equal to "Internal Trackpad" then
            my TrackpadIsAttached()
            return
        end if
    end if

    if gamingMouse is equal to "Gaming Mouse" then
        my gamingMouseIsAttached()
        return
    end if
end tell
  • Can you add a delay at the end of your script of something like 15 seconds and test again? launchd may be restarting your script after exiting too fast (which can be associated with erroneous execution needing a restart). – Randy Marsh Jan 9 '17 at 21:11
  • @RandyMarsh I'll give that a shot, however, I need the script to execute fairly fast after the USB device is connected. – Kiril Jan 10 '17 at 5:39
  • @RandyMarsh I added a delay of 15 seconds, but the script still got restarted. I am noticing something strange: the script is designed to open the system preferences, reverse the scroll direction (when the mouse is connected), and then exit the system preferences. It works as expected when I run it manually. However, when launchd runs the script, it doesn't exit the system preference window. – Kiril Jan 10 '17 at 7:57
  • The <Keep Alive> directive will reload your script once it finishes; this is what's causing it to continually reload. – Allan Mar 6 at 17:01
  • @Allan: Isn't KeepAlive false? – seaturtle Mar 6 at 17:02

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.