Starting with Mac OS 10.9 Mavericks, Apple requires that Assistive Access must be enabled explicitly for each application that wants to use it.
I have written the following AppleScript function to deal with this, for a given application. The script works for me but it has 2 flaws:
When the operating system is running in a language other than English, the hard-coded button names will be wrong, and the script will fail. How can I discover what language the OS is running in, and what names the "Click the lock to make changes." button will have in that language? Alternatively, is there a way to determine whether this button is in the
locked
,authenticating
orunlocked
state, without reading the name of the button?The script uses a tight repeat loop while it is waiting for the user to enter an admin username and password. Is there a better strategy I can use to wait until the dialog has been been successfully dismissed?
====
set output to allowAssistiveAccessFor("Skype")
if (the |quitWhenDone| of output) then
tell application "System Preferences" to quit
end if
on allowAssistiveAccessFor(applicationName)
set quitWhenDone to not (application "System Preferences" is running)
set output to {quitWhenDone:quitWhenDone}
tell application "System Preferences"
activate
reveal anchor "Privacy_Accessibility" of pane id "com.apple.preference.security"
tell application "System Events"
tell process "System Preferences"
-- Find the table that contains the application icons and checkboxes
try
set appTable to table 1 of scroll area 1 of group 1 of tab group 1 of window "Security & Privacy"
on error errorMessage
return output & {state:-1, message:errorMessage}
end try
set total to the number of rows of appTable
-- Find the row that refers to applicationName
repeat with rowNumber from 1 to total
if (name of UI element 1 of row rowNumber of appTable = applicationName) then
set appCheckbox to checkbox 1 of UI element 1 of row rowNumber of appTable
if (value of appCheckbox as boolean) then
-- Assistive access is already enabled for this application
return output & {state:0, message:"Already enabled"}
else
-- Click the “Click the lock to make changes.” button.
if exists button "Click the lock to make changes." of window "Security & Privacy" then
click button "Click the lock to make changes." of window "Security & Privacy"
-- The user will now have to enter an admin password. This can take some time.
-- The name of the button will change to "Authenticating"...
set unlocking to button "Authenticating…" of window "Security & Privacy"
repeat while exists unlocking
end repeat
-- ... and then to "Click the lock to prevent further changes." ... unless the user cancelled
if exists button "Click the lock to make changes." of window "Security & Privacy" then
return output & {state:-1, message:"User cancelled"}
end if
end if
-- Click the <applicationName> checkbox.
-- If we had to unlock the Security & Privacy pane, then an immediate click might not have
-- an effect. Try as many times as possible for 1 second, and give up if unsuccessful
set failMessage to "Cannot allow the " & applicationName & " application to control your computer"
set endDate to (current date) + 1.0 -- 1 second from now
repeat
try
if ((current date) > endDate) then
-- Time's up
return output & {state:-1, message:failMessage}
end if
click appCheckbox
if (value of appCheckbox as boolean) then
return output & {state:0, message:"Success"}
end if
on error errorMessage
-- Something dreadful happened. Keep trying until time is up
end try
end repeat
end if
end if
end repeat
end tell
end tell
end tell
return output & {state:-1, message:"Application " & applicationName & " not found"}
end allowAssistiveAccessFor