Pause until / exectue

I am currently using the following sequencing

  • { Pause until } [ button A ] appears
  • { Press button } [ button A ]
  • { Pause until } [ button B ] appears
  • { Press button } [ button B ]
    and so on

I have duplicated entries for every actionable button to press.

Appreciate guidance to simplify
Thank you

Yeah that's what I do. Don't know of a simpler way I'm afraid. Would be nice if the Press Button action had an optional check-box like this:

@peternlewis, what do you think?

2 Likes

Actually it is not only Press Button, Wait for Menu, Wait for Pictures, and more

Maybe the [ Pause Until Conditions are Met ] can add a condition to be executed as soon as condition is met

It wouldn't make sense to add optional actions to the Pause Until, as there are too many permutations. Rather, for actions that interact with something in one way only (like buttons), I can imagine a conditional pause might be quite easy to implement.

Not exactly simplifying, but a way to make it more concise within your macro would be to make a Collection of your button titles and then use a "For Each" over that collection.

Completely untested mock-up:

1 Like

That's great for when they're presented one after another, but most often there will be other actions in-between button presses. I like your thinking though!

Obviously, if there's more variation in each "loop" than in OP's example then it probably wouldn't be appropriate. More importantly, IMO, is that it isn't as readable as multiple pause-then-do statements.

And while I like the thought of special-casing button press actions to include pause-until, I have the same readability concerns -- especially if you then wrap that action in another "Pause Until" because you have multiple wait conditions...

I'm starting to think that verbosity is actually a benefit in KM macros!

Yeah I hear that. I'd still love the option though.

As a general rule I prefer to keep seperate actions seperate. That way you can combine them whatever way you want.

If you commonly use the sequence

Pause Until Button XXX is Enabled
Press Button XXX

Then I suggest the solution is to create a Subroutine macro that does exactly that, and then create an Execute Subroutine macro pre-configured to execute the Press Button When Enabled subroutine and add that as a Favorite action.

Or you could just add the pair of actions as a favorite action, but then you do have the two buttons referenced and have to ensure you set both names the same.

Fully understood and agree of keeping actions separate.

Though in my use case the buttons never come immediately available. For every single button I have to Pause and Press.

One of the script goes as follows:

  • Open file
  • Wait until Menu 'Refresh' becomes available (Wait until file opened)
  • Select Menu 'Refresh'
  • Wait for button 'Refresh'
  • Press button 'Refresh'
  • Wait for button 'Close'
  • Press button 'Close'
  • Menu 'Publish'
  • Wait for button 'Publish'
  • Press button 'Publish'

Elder's improvement guidance appreciated.

I can't think of any scenario where I'd want to attempt to press a button before it exists. Therefore, according to @peternlewis's advice, I'll be using this submacro whenever I want to press a button:

Once that's set up in your Global macro group, all you need to do is call it with the button name as a parameter:

3 Likes

@noisneil appreciate your hands-on guidance on this.

That works well, and reduces number of steps.

1 Like

Once the Execute a Macro action above is saved as a Favourite, you might like to fool around with this. I'm trying to figure out how to access the Parameter field without using found images, as it's prone to failure when the action is near the bottom of the Editor window. If I can, this might be quite tidy.

Demo Video

CleanShot 2022-06-15 at 16.36.53

New Button Press.kmmacros (36 KB)

Macro screenshot

Even better would be to create the action with a script, as I've seen @Zabobon do elsewhere. Perhaps he might be able to point me in the right direction...?

Ok this works without using found images! :blush:

New Button Press.kmmacros (35 KB)

Macro screenshot

It sounds like you have your solution anyway. But in case it helps, I worked out how to make a Macro where a User Prompt asks you for the Parameter and then creates a new Action set up like that and called the same as the Parameter. But in order to make it work for your Custom Action I need a copy of your Custom Action to adapt. If you upload it I could have a go. But no worries if you are happy with your solution.

And to be honest, one problem with having a Macro that creates a Custom Action using AppleScript and XML is that it is almost too bespoke and a bit fiddly to adapt to other uses. If you have managed to use native Keyboard Maestro actions to achieve what you want I think that is a better/simpler solution. After all, that is the whole strength of Keyboard Maestro's modular Actions system.

1 Like

Thanks @Zabobon! Here's the action if you fancy a tinker:

Press Button.kmactions (621 Bytes)

Peter says the next update will automatically place the text cursor in the parameter field, but I'm still curious to know how you'd auto-create an action with variables to set values.

OK, in an effort to disprove this, I decided to look at my own macros. And it turns out in every single case I do a Pause Until immediately before the Press Button.

As such, I will look at adding an option to the Press Button to handle this.

Thanks for the feedback.

8 Likes

EDIT - after replying with an Example of how to do this with AppleScript and how to adapt that AppleScript to other situations I suddenly realised a much simpler solution. So, I am editing my original post with this non-AppleScript version:

Since it is the case that pasting the XML code of an Action recreates that Action in Keyboard Maestro we don't need AppleScript at all to create a single Action...

It can be done by just using Keyboard Maestro native Actions and replacing the parts of the XML code that we want with Keyboard Maestro Variables!

So, first create a Custom Action (with Placeholder text for the bits you want to Prompt the User for).

Select just this one Action in Keyboard Maestro and choose Edit>Copy As>Copy as XML

Paste this into a Text Editor (I just use Apple Notes). Edit this XML text to replace the Placeholder text with Keyboard Maestro Variables (shown in bold just to make it clearer)

So this:

is edited to become this:

To build the Macro to make use of this:
Put that edited XML code in a Set Variable Action.
Filter that Variable to process the Variables.
Then paste that Variable's XML text by using an Insert Text by Pasting Action.

Running the resultant Macro will create a new Customised Action just below whatever current Action is selected in the Macro you are editing.

Here is an Example Macro using the Action that @noisneil uploaded for me.

EXAMPLE Create Single Action with original XML.kmmacros (5.1 KB)

And here is that Example Macro in use:

EXAMPLE Create Single Action with AppleScript and User Input

As this particular custom Action references a Macro to Execute that is not on my computer it shows "none". But as the reference for the Macro it is looking for is in the XML code it should work fine on @noisneil's Mac. And of course even that could be changed to a Variable.

This approach should work with any Keyboard Maestro Action (not just the Execute Macro Action).

EDIT - I've just realised you can be even cheekier if instead of using Placeholder text you just enter the Variable names you want to use in you initial Custom Action, quoted like this:

When this Action is copied as XML those Variables will be quoted correctly in the XML. No need to edit them in the XML.

One last thing to bear in mind is that when you are building your Macro, if you try and paste this XML text into a Set Variable Action it won't paste in. It will create a new Action. So you do have to temporarily add something to the XML text to "break" it so that it will just paste in as text. A simple way is to first paste it into a Text Editor, add a random letter at the front of the code, copy and paste this edited version into the Set Variable Action and then remove that random letter.

5 Likes

That is so freakin' cool!!!!

:trophy::trophy::trophy::trophy::trophy::trophy:

2 Likes

Thank you @peternlewis, I learnt a ton of this thread to improve my macros. Appreciate yours and @noisneil guidance.

I have now done an inventory of my own macros, where I am Pausing [ any hint on how to simplify is appreciated ]

8 times for menu item to become available

  • wait for application to have fully started
  • refresh of external data source is completed

4 times until picture becomes available

  • Actually these are webforms inside an application [ Sign In and Password ]

2 times for python scripts to be completed

  • "Pause for 8 minutes"