As a start, here is the HTML Code that spawned this discussion (errrrr, rabbit hole) which was written by Claude Code.
To keep things unambiguous, I'll use these definitions:
-
The macro — the sequence of actions.
-
The prompt action — the Custom HTML Prompt action inside the macro.
-
The window — the Custom HTML Prompt window on screen.
-
KM Engine — the Keyboard Maestro engine working in the background.
-
You — the person picking an item from the prompt.
-
HTML Result Button — the global variable (it appears in my global variables list) that holds the button / list item picked. (I gather
%HTMLResult%is the modern replacement and is documented as scoped to the execution instance — see the last question.) -
JS Handler — the JavaScript in the prompt listening for key presses.
-
KM Handler — the KM Engine listening for Return and Esc, separate from the JS Handler.
The one distinction that matters: the prompt action "finishing" (the macro moves to the next action) is a separate event from the window "closing" (the window leaves the screen).
ITEM 1: Synchronous prompt (the prompt action finishes at Submit())
-
The macro reaches the prompt action.
-
The prompt action clears / deletes HTML Result Button.
-
The prompt action spawns the window and waits (the prompt action has not finished). The macro is parked, waiting for the prompt action to finish.
-
You pick a button / row. Your pick calls
Submit(choice). -
Submit(choice):
a. Tells the KM Engine you submitted the valuechoice.
b. The KM Engine finishes the prompt action, which copieschoiceinto HTML Result Button.
c. Closes the window. -
HTML Result Button holds
choice. -
The macro moves to the next action.
Question: Is the above correct and, if not, please correct it?
ITEM 2: Asynchronous prompt (the prompt action finishes at launch)
-
The macro reaches the prompt action.
-
The prompt action clears / deletes HTML Result Button.
-
The prompt action spawns the window but does not wait. The prompt action finishes immediately, because it has completed its only job — spawning the window.
-
There are now two independent streams:
a. The macro
i. At the finish of the prompt action, the KM Engine has no value for choice (you haven't chosen yet), so it copies nothing into HTML Result Button (the variable is never created — it doesn't appear in KM → Settings → Variables).
ii. The macro walks straight on to the next action, while the window sits open on its own.
b. The window
i. After the prompt action has finished, you pick a button / row, which calls Submit(choice)
ii. Submit(choice) closes the window.
iii. The prompt action has already finished, so there is no trigger to tell the KM Engine to copy choice into HTML Result Button.
iv. HTML Result Button is never created (doesn't appear in KM → Settings → Variables).
Question: Help me understand how / why the window is independent from the macro. How / why does the KM Engine treat it as a separate entity?
Question: Is the above correct and, if not, please correct it?
ITEM 3: Return vs double-click (how you select changes how many submitters act)
The above assumed one submitter. But how you pick a button / row changes how many submitters act on it.
ITEM 3A: Does selecting with Return create a race condition?
If you pick using Return, there could be two submitters acting on the same keystroke:
-
The JS Handler catches Return and calls
Submit(choice), wherechoiceis the row value. -
The KM Handler treats Return as "press the default button" — which for a window with buttons would be the default button's value, and for a buttonless list would be
OK. This callsSubmit(OK).
Question: Is the above correct and, if not, please correct it?
Question: Is there actually a race condition here — and does something prevent it, e.g. the
preventDefault()I have in my keydown handler? Put differently: doespreventDefault()on Return / Esc suppress the KM Handler? If there's no race, please explain why; if there is, please explain how it's resolved.
Question:What value will HTML Result Button hold (running synchronously), and why? Very confused about this one.
ITEM 3B: Selecting with a double-click does not create a race condition.
If you pick using a double-click, the KM Handler is not involved. The JS Handler is the only submitter, and the prompt action / window behave as described above.
Question:Is the above correct and, if not, please correct it?
Question: Is there no KM Handler equivalent that listens for mouse clicks? If not, why not? If there is, would there be a similar race — but with both submitters carrying the same
choicevalue?
One more, on scope:
Note: The wiki describes
%HTMLResult%as "the result of the last Custom HTML Prompt action in this execution instance" (instance-scoped), yet the olderHTML Result Buttonshows up in my global variables list. Are these two genuinely different scopes, and is that difference relevant to any of the above?
KM version: [11.0.4] · macOS: [26.5.2]