Assigning Triggers Dynamically, if Possible?

Hi people

There was something I used to use with autohotkey years ago when I was windows user and now wonder is it possible with KM?

So, all keystrokes used by the script were written in one .ini file and linked to certain functions or labels as they are called in AHK, so when they are pressed, the script would know which function or label to run.

As I make accessibility enhancements for blind that is screen reader users, and we all use only keyboard to work on computer, something like that would be really useful if possible in KM.

The way it works currently in the KM is fine, just a bit slow when user wants to change keystrokes for more then a few macros. I'm just curious to hear about some alternatives if there are any.

Thanks in advance

If you are asking if there is some sort of "text" interface to Keyboard Maestro, no, there isn't.

However Keyboard Maestro itself is highly scriptable, including the ability to create or delete macros. For example, see:

So you could, for example, have a text file with your mappings, and then you could have a macro that created the macros for those mappings (deleting any existing macros first presumably).

Hey Peter

Thanks for sharing this, it is sort of thing that would be really useful.

But is there a way to have list of keystrokes linked to already existing macros, so if keystrokes are changed on this list, the triggers would get changed on macros too?

Or maybe it would be better to ask this: Is it possible to assign triggers to a macro through the scripting?

If I understood you correctly, you said that it's possible to create macros through scripting.

So if there's possibility to select macro groups and macros through scripting, and assign or change their triggers through scripting too, then I'd be able to create custom functionality to get what I actually want.


Doable via AppleScript

Add Trigger to Selected Macro
set triggerXML to "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"\">
<plist version=\"1.0\">

tell application "Keyboard Maestro"
   set theMacro to item 1 of (get selected macros)
   tell theMacro
      make new trigger with properties {xml:triggerXML}
   end tell
end tell

Adds the hotkey trigger F1 to the selected macro.


1 Like

This may be exactly what I am looking for, for a totally different purpose. I have questions:

  • When you run that AppleScript, tell application "Keyboard Maestro"
    does it make a permanent change to the KBM macros, or just in the currently running session?

  • It looks like identifying the trigger takes two values: an integer that identifies the main keystroke, KeyCode, and another integer that identifies the combination of modifier keys, Modifiers. Is there a convenient source for a list of both of those, the keystroke codes and the modifier key codes? Or are we left to experiment and compile our own list?

In my usage, I expect to be presenting a User Dialog to set the main key and the modifiers. Most convenient for me would be to use the equivalent of the %TriggerValue% string, which is actually a string of characters, some or all of the characters ⌃⌥⇧⌘, in that order. So I will need to convert between the 16 combinations of modifier keys and the integer code. Should I just create a lookup table, or is there a programmatic way to do it on the fly?

Did you ever send me down a rabbit hole on this question! And I cannot guarantee that my answer is correct. But I did my best. And it all adds up.

There's a human interface device definition from the USB body that defined "USB key codes", which are a logical sorting of all possible keyboard keys. However this is an abstraction. Below that is another layer called "USB scan codes", which tend to number the keys by their physical layout on the keyboard. It is this layer that KM uses to detect keys.

From my reading, the lower level (scan codes) can be different for keyboards from different manufacturers. I found a list of Apple scan codes that differ from the scan codes from IBM. I am including two USB organization's USB links below. The first one is the USB HID guide, the second one is its parent link.

The root of the document is here:

Apple's scan code list is findable online, but my source doesn't come from Apple, other than saying it comes from an Apple file called EVENTS.H:

  kVK_Return                    = 0x24,
  kVK_Tab                       = 0x30,
  kVK_Space                     = 0x31,
  kVK_Delete                    = 0x33,
  kVK_Escape                    = 0x35,
  kVK_Command                   = 0x37,
  kVK_Shift                     = 0x38,
  kVK_CapsLock                  = 0x39,
  kVK_Option                    = 0x3A,
  kVK_Control                   = 0x3B,
  kVK_RightShift                = 0x3C,
  kVK_RightOption               = 0x3D,
  kVK_RightControl              = 0x3E,
  kVK_Function                  = 0x3F,
  kVK_F17                       = 0x40,
  kVK_VolumeUp                  = 0x48,
  kVK_VolumeDown                = 0x49,
  kVK_Mute                      = 0x4A,
  kVK_F18                       = 0x4F,
  kVK_F19                       = 0x50,
  kVK_F20                       = 0x5A,
  kVK_F5                        = 0x60,
  kVK_F6                        = 0x61,
  kVK_F7                        = 0x62,
  kVK_F3                        = 0x63,
  kVK_F8                        = 0x64,
  kVK_F9                        = 0x65,
  kVK_F11                       = 0x67,
  kVK_F13                       = 0x69,
  kVK_F16                       = 0x6A,
  kVK_F14                       = 0x6B,
  kVK_F10                       = 0x6D,
  kVK_F12                       = 0x6F,
  kVK_F15                       = 0x71,
  kVK_Help                      = 0x72,
  kVK_Home                      = 0x73,
  kVK_PageUp                    = 0x74,
  kVK_ForwardDelete             = 0x75,
  kVK_F4                        = 0x76,
  kVK_End                       = 0x77,
  kVK_F2                        = 0x78,
  kVK_PageDown                  = 0x79,
  kVK_F1                        = 0x7A,
  kVK_LeftArrow                 = 0x7B,
  kVK_RightArrow                = 0x7C,
  kVK_DownArrow                 = 0x7D,
  kVK_UpArrow                   = 0x7E

It may be worth noting that the Eject Key which can be found on Apple's keyboard does not appear in this list, which is probably why KM cannot detect that key. (Although it might be an undocumented key and if Peter tried guessing a few unused values he might uncover it - I see only 5 possible values.) It's also worth noting that in this list F1 is x7A, which converts to 122, which is the number in ccstone's script above. Also note that the unusual key called Fn (sometimes Globe) is in this list, and note that KM can detect it.

There is one thing about this list that I cannot understand. That is, we can see entries for Mute, VolumeUp and VolumeDown, but not for the 7 other Shift+FunctionKey buttons. HOWEVER, I see an empty block of seven values from 41 to 47, and I'll bet that's where they fit. Regardless, I don't see any need for there to be two sets of scan codes for the function keys and the "media keys." I suppose Apple just conflated the idea of a "scan code" with a "key code".

I find it fascinating that when I flip this switch from blue to disabled (as shown below, it's disabled):...

...KM has the odd behaviour of recognizing only F5 and F6, but none of the others from F1 to F12. This is because Apple uses that switch to determine whether the row of function keys returns one set of Scan Codes or another. In either case Apple leaves the scan codes for F5 and F6 alone.

I think it pretty much all makes sense.

I'm well aware that Peter would never attempt to implement undocumented Apple functions like the scan code for the Eject button, but I have a hunch it would work if he tried it, at least until Apple changed the meaning of the undocumented scan codes.

Don't blame me! I specifically asked for "a convenient source". :wink:

Thanks for all the background and context.

That list also reminded me that most of those keys can be used as triggers. I've been too often limiting my macro triggers to Modifiers+Alphabet.

Thanks Chris! I tried it and it works very nicely.

I just pasted the above code, from set trigger... to end tell into an Execute AppleScript action in a new macro, called "TEST: Add a function to a macro".

When I ran that macro using the Run button, it added the trigger to itself because it was the selected macro.

When I set it to be triggered by "The status menu item is selected", then I could add that trigger to any macro that I selected before running the macro.

So now I need to figure out how to name a specific macro to KBM in AppleScript. I'm sure it's documented somewhere...

Got it!

I just changed the single line to:

	set theMacro to item 1 of (every macro whose name is  "Comment")

and it added that trigger to the macro that I had named "Comment". (Well, actually, I created a new macro and added a Comment action to it and KBM did the macro naming automatically from that.)

I also tested and this AppleScript line works in the script too, an equivalent to item 1:

	set theMacro to the first macro whose name is "Comment"

Saying "the macro ..." doesn't work, even if there is only one. I has to be "the first macro ... or "item 1 of (every macro ..."

I've compiled a list of the 16 Modifiers.

In Chris's script, above, he uses 2048 for a modifier of ⌥:

Replace that number with whatever Modifier combination you want from this list:

None			       0
Cmd					 256
Shift				 512
Shift+Cmd			 768
Opt					2048
Opt+Cmd				2304
Opt+Shift			2560
Opt+Shift+Cmd		2816
Ctl					4096
Ctl+Cmd				4352
Ctl+Shift			4608
Ctl+Shift+Cmd		4864
Ctl+Opt				6144
Ctl+Opt+Cmd			6400
Ctl+Opt+Shift		6656
Ctl+Opt+Shift+Cmd	6912

From this list, it seems to me that 1024 ought to also be a Modifier key, but I have not yet found what it might be.


The above page also includes useful notes on how to generate keystrokes with modifiers using AppleScript.

1024 is the alphalock, but it is not allowed in Hot Keys. This defines the bits, but only the four standard ones are allowed by the hot key API.

  btnStateBit                   = 7,    /* state of button?*/
  cmdKeyBit                     = 8,    /* command key down?*/
  shiftKeyBit                   = 9,    /* shift key down?*/
  alphaLockBit                  = 10,   /* alpha lock down?*/
  optionKeyBit                  = 11,   /* option key down?*/
  controlKeyBit                 = 12,   /* control key down?*/
  rightShiftKeyBit              = 13,   /* right shift key down? Not supported on Mac OS X.*/
  rightOptionKeyBit             = 14,   /* right Option key down? Not supported on Mac OS X.*/
  rightControlKeyBit            = 15    /* right Control key down? Not supported on Mac OS X.*/
1 Like