Question about TriggerValue's meaning

If I'm wrong, I will apologize profusely. But I've tested this. I will even accept a punishment if I'm wrong (typos excluded).

I always assumed that the %TriggerValue% (and %TriggerBase%) returned the values for the currently running macro. But I just did some testing and that's not entirely accurate. And that results in a problem. Let me start with an example.

Let's say you have two macros called Macro1 and Macro2, and Macro1 is triggered by the hotkey CMD-A and simply calls Macro2. I.e.,

Both macros will see the following values from these tokens if you trigger Macro1 with CMD-A:
%TriggerBase% = Hot Key Trigger
%TriggerValue% = CMD-A

But if you change the calling macro to pass a parameter like this:

image

Then Macro2 will see the following values:
%TriggerBase% = Hot Key Trigger
%TriggerValue% = zzz

...and these are now different values from what Macro1 sees.

In other words, TriggerValue can be modified so that it's different in each child macro, but the TriggerBase is always the same. Is that the most desirable behaviour? But wait, that's not all.

Until today I thought that TriggerBase would change when you called a macro. I was wrong. I had expected that calling a macro via the Execute Macro action would change both tokens: TriggerBase (probably to "Execute Macro") and TriggerValue (probably to the parameter or an empty string, but definitely not the value from one of its parent macros and yet it inherits the TriggerValue parameter from its parent.)

Think about that. If Macro2 above called a new macro, Macro3, and Macro3 displayed the contents of %TriggerValue%, it would see the parameters that Macro1 passed to Macro2. It would have no way of knowing that it didn't receive any parameters itself from Macro2! It would inherit the parameters passed from Macro1 to Macro2 unless Macro2 passed different parameters to Macro3.

I can't imagine any scenario in which I would want a macro to be unaware that the %TriggerValue% token it is examining was NOT being passed by its parent but rather some inherited value from a macro three level up. Why would anyone want a macro to be unable to determine if the contents of %TriggerValue% was meant for it or for some parent macro higher up in the chain?

A simple solution might be to empty TriggerValue of its contents when executing the Execute Macro action (and no parameters is being passed). But I'm still not satisfied by the fact that TriggerValue and TriggerBase still wouldn't be matching up with each other. I think the best solution would also be to create a new TriggerBase called "Execute Macro" and also set its value appropriately whenever Execute Macro is called. Then everything would be consistent.

Hi Sleepy. Thanks for spending some time on this and explainig things so clearly. I'd not even been aware of %TriggerBase%, so thanks for that too.

I come at this from a slightly different perspective. As long as the behavior is well-defined and consistent, I can work with it. I'm pleased that you shared "%TriggerValue% can be propogated through a macro chain—I assumed (ahem) that it was undefined unless set with something. Thanks for that as well.

But in a lot of cases, I think it is tricky to assert that something "should" work one way or the other. None of us can know how the majority of KBM users actually use the tool. And those of us who use it extensively may not be using it in the same way as the majority of more casual users.

Everything you say is true. And thanks for the compliments. I'm really putting my neck out on a limb here and I was expecting to be eviscerated. Since you aren't eviscerating me, that makes me feel a lot better. For now.

I'm not a language expert, but I'll bet KM's mechanism of passing parameters to subroutines when no other parameters are passed down is a unique implementation. And regardless of whether it's unique or not, wouldn't you agree that it should be explicitly documented? Where is this documented? Something highly unusual is undocumented? (I couldn't see any documentation about this behaviour, can you?)

So at a minimum I would infer you agree that it should be documented. And you don't seem opposed to the idea of considering what the desired behaviour should be.

I don't want to break people's KM macros by making willy-nilly changes to the language. Sometimes if a design decision is not optimal you just have to live with it. I agree. But I also agree that users have the right to dig into the guts of a language and debate things like this, even if my suggestions are not adopted.

I don't know if this helps or not, because I honestly didn't read everything. :roll_eyes:But a while back I ran into some issues with %TriggerValue%, and since then, I always use the "with parameter" option of the Execute Macro action, even if I have nothing to pass. Leaving it empty solved whatever problem I was having.

It's part of my KMFAM set of actions, and I don't even think about it anymore.

1 Like

I never thought of that. It does prevent the "undocumented passing of parent parameters to child process" problem. So that's a good idea. Although it doesn't address the problem of the mismatched Value vs Base issue.

I'm not sure what you think about how KM should work, but I'm going to infer that you would agree that this odd behaviour should at least be documented.

Yes, in my opinion it should be documented. But I'll let you talk with JMichaelTX or peternlewis about it. Feel free to add their names with "@" in front, to get their attention.

Ok thanks. @peternlewis

Have you read:
TriggerValue token

Different ways of triggering the macro will set this field differently.

  • You can pass an explicit value in using the “with parameter” option when executing a script from AppleScript.
  • You can pass an explicit value in when using the Execute a Macro action.
  • You can pass an explicit value in when executing the macro via the web server.
  • You can pass an explicit value in when executing the macro via the kmtrigger URL.

and:
TriggerBase token

My post made it very clear how to change the TriggerValue token by passing a parameter. (If you didn't notice it, please refer to the part of my post where I pass "zzz" to Macro2 and how that affects TriggerValue.) So I'm unsure as to whether or not you understand the subsequent points I made after I explained that. My concerns were much deeper than how a user can set TriggerValue.

The Trigger tokens are based on the parent macro, which is the macro that starts a new Instance.

While this is a complex subject, it is well defined. Execute Macro will only start a new instance if you execute the macro asynchronously. Otherwise, you stay within the same macro instance, with the same Trigger tokens.

However, the TriggerValue is also used to pass parameters, and so if you use the Execute Macro action with a parameter, that will overwrite the trigger value for the sub-macros.

There are a thousand other ways this could be implemented, but this is the way it is implemented.

3 Likes

Well, maybe 999 other ways. :wink: (just kidding)

Makes perfect sense to me. I like the way it works, and have been using it for several years without issue.

Well, you're the Architect. Your word is final. I still love you.

I don't object to most of how it works. What I'm mostly objecting to is the inability of a sub macro to figure out if the TriggerValue token was a parameter meant for it or if the value was meant for a parent macro.

I also thought this part of the mechanism should be documented, and I even got Dan to agree with that idea. The wiki for TriggerValue doesn't explain this unusual behaviour at all. In fact the first line of the wiki says TriggerValue contains "the value associated with how the macro was triggered" but in fact it contains a value from some macro between it and the first macro in the instance chain, and there's no way to determine how high up that chain it came from.

Could you please suggest some new text for the wiki that would be clearer? Thx

Dan did agree that the issue should be documented, and I believe he has the permissions to edit the wiki, so I'll leave it to him to consider doing that. I'm recommending Dan because, as my first sentence is the first post indicated, I'm worried about looking critical of KM. When in fact I'm absolutely in love with KM.

As long as this thread isn't deleted the explanation can always be found in my initial post above. I think I saw wiki pages linking to forum pages, so Dan could consider that option here.

I'll leave the Wiki editing in @JMichaelTX's (and Peter's) very capable hands.

Jim, if it's documented in the Wiki, then just give a link. If not, I think Peter's explanation (above) is a great one. Personally, I always use "with parameter" when I use "Execute Macro", even if the parameter is blank, unless I have a reason not to. Feel free to recommend that, or not, in the Wiki.

Whatever you decide, I'll support it. You (and Peter) continue to do an awesome job with the Wiki, and although it's usually a thankless job, thank you. :smile:

Peter - I have an idea. I don't know if it's a good one or not. But it's "only" a change to the UI. No change to to "the back-end".

What if, instead of a checkbox for "With Parameter", you had a drop-down with two options:

  • With Parameter
  • Inherit Parameter (or Inherit TriggerValue)

It's still just a boolean value, but represented as a drop-down instead of a checkbox. And it would still function just like it does now. For example, when "With Parameter" is selected, there's a box for the parameter, and when "Inherit Parameter" is selected, there's no parameter box. Obvious the Gear menu would change slightly to match this.

The best part is you leave everything the same in the back-end. It's still a boolean value. The "only" thing that changes is the UI.

I'm not downplaying what it takes to change the UI. All I'm saying is it wouldn't change anything functionally, and it wouldn't break existing code (and wouldn't change Plist/XML values, for those of us who might or might not care).

Just a thought.

1 Like

A drop-down in a drop-down?

No, like this:

You click on the little up-down arrow, and you can select "With Parameter" or "Inherit Parameter". Since there's only two options, it's the same as a checkbox, with better documentation. :smile:

I hadn't really considered putting a solution, so much as it is one, into the Editor. Good idea. But of course I'll settle for a documentation update. Actually, even if nothing changes, I kinda feel proud since I made a good point and got a couple of people on my side.

1 Like

OK, I have updated the token:TriggerValue [Keyboard Maestro Wiki] to provide this additional explanation:

Comments?