Isaac Isaac - 2 months ago 14
AppleScript Question

Simulated key command not working since OS upgrade

I considered posting this to Ask Different but I thought it belonged here due to being mainly focused on code.

I have created a macro on my mac for switching spaces, and since upgrading to Sierra the following AppleScript is no longer working. Does anyone know if something has changed?

tell application "System Events" to key code 124 using control down


and

tell application "System Events" to key code 123 using control down


This is the output when running in terminal (note the
^[[1;5D
):

14:16 isaac@Isaac ~ $ osascript -e 'tell application "System Events" to key code 123 using control down'
^[[1;5D14:18 isaac@Isaac ~ $ ;5D


And when running via AppleScript Editor, nothing happens.

Answer Source

Yes, it's a bug.

To simulate some global shortcut with the Control key, the command needs the fn key (a workaround for Sierra).

It's not possible to use the fn key with the AppleScript's key code command, but it's possible with the methods of the Core Graphics framework in a Python script.


Here's the script to simulate this shortcut --> (Right Arrow + Control), you can run the script in the Terminal (in a sh, bash or any similar shell)

/usr/bin/python -c 'import time; import Quartz.CoreGraphics as QCG; e = QCG.CGEventCreateKeyboardEvent(None, 124, True); QCG.CGEventSetFlags(e, (QCG.kCGEventFlagMaskControl | QCG.kCGEventFlagMaskSecondaryFn)); QCG.CGEventPost(QCG.kCGHIDEventTap, e); time.sleep(0.1); QCG.CGEventSetType(e, QCG.kCGEventKeyUp); QCG.CGEventPost(QCG.kCGHIDEventTap, e)'

Here's an AppleScript to test in the "Script Editor" application:

--  For switching spaces, 124 = the Right Arrow key, use 123 for the Left Arrow key
do shell script "/usr/bin/python -c 'import time; import Quartz.CoreGraphics as QCG; e = QCG.CGEventCreateKeyboardEvent(None, 124, True); QCG.CGEventSetFlags(e, (QCG.kCGEventFlagMaskControl | QCG.kCGEventFlagMaskSecondaryFn)); QCG.CGEventPost(QCG.kCGHIDEventTap, e); time.sleep(0.1); QCG.CGEventSetType(e, QCG.kCGEventKeyUp); QCG.CGEventPost(QCG.kCGHIDEventTap, e)'"