Is there a way to run an action only if the macro to which it belongs is not called as a subroutine in another macro?
Say I have macro B with action x. Macro B is called as a subroutine in macro A. If macro A is run, I don't want the action x to execute. But if Macro B is run by itself, I want x to execute.
Is that possible? In Python, there is the if name == "main": construction that accomplishes this.
There are some %Executing%
tokens that would probably be usable, but if it's a subroutine, you could also do it by passing a flag as a parameter.
MacroA: Call sub with parameter "MacroA", set to local_flagValue or whatever in MacroB.
MacroB: Case local_flagValue ≠ MacroA then run action.
-rob.
I think I understand. So, the action x is put inside an if-statement: if local_flag = empty, execute x. Then every time I put the macro inside another macro, I set the local_flag to 1 (or any other value) in the macro call parameters. I'm hoping this construction works if macro C is inside B and B is inside A.
That's clever and very helpful. Thank you.
By "inside" I assume you mean "called by?" If they're subroutines, you can pass any parameters you want, so you could build whatever system you needed to make sure that whatever actions run only when you want them to run.
Even if they're macros not subroutines, you can use the "with parameter" option to pass in a value that will show up in the %TriggerValue%
token (I think that's where it shows up; that's from memory).
So just have Macro C pass something to B, and have B pass two things to A, etc.
-rob.
As @griffman stated, yes!
Try out the following macro: one target (Run Me
) and two callers...
Test Submacro & Subroutine Macros.kmmacros (6.1 KB)
The target will produce one of three dialogs:
2025-01-02 1304 UPDATE: The above has a bug. I'll leave it for illustration only. Using @Nige_S's suggestion, I've shared an updated version below.
Hey, @R_B_Jawad, I just discovered an issue; so I need to add a disclaimer.
If the Execute a Macro is used and Asynchronously is selected, then the method I used in my example macros will not work!
( expand / collapse )
If Asynchronously is selected:
%ExecutingMacro% == %ExecutingThisMacro%
@peternlewis is that intentional? If so, is there some other method that can be used by a target macro to determine if it was triggered directly (vs triggered via Execute a Macro or Execute a Subroutine)?
For async macros, I think you'd need to set a global variable in the calling macro, then check that global in the called async macro.
-rob.
Then "Run Me"s %Trigger%
will be "Execute Macro" rather than the calling macro's trigger. That, combined with your other test, may be enough to differentiate.
Ah, thanks @Nige_S. That (or %TriggerBase%) can be use to address the @R_B_Jawad's original question. I'll update the test macros below.
With async, short of @griffman's suggestion, do you know if there is any method that the target can use to determine which macro called it?
Using @Nige_S's insight, I've updated the set of test macros. As a bonus I added a macro that use the AppleScript to trigger the target.
Test Submacro & Subroutine Macros,v2.0.kmmacros (13.0 KB)
Here's the updated logic...
( expand / collapse )
I'd probably pass the caller's instance UUID as (part of) the parameter -- assuming you are using the "Execute a Macro" action. If it's via "Trigger Macro by Hot Key" then I think that @griffman's global is the only way to go.
Yes - an asynchronously executed macro is its own new instance.
Check the TriggerBase token or Trigger token?
Generally I would say if you need to do this you are doing things wrong. If it is a subroutine/sub-macro and it needs to know how it was triggered, then pass in that information. If a macro is triggered by normal triggers and by executing as a subroutine, break it in to an additional macro as the subroutine, and call that from the triggered macro, passing in additional information about the desired behaviour if necessary.