Do Something if No Keys are Pressed โ€“ Otherwise Cancel Macro

I try to do something that probably no one would understand. That's why I'm not even trying to explain it :smirk:

What I want to achieve is this:

I trigger a macro with a shortcut. KM should now wait 2 seconds. If no key is pressed in this time, then the macro should be executed.

But if any other key is pressed in these 2 seconds, the macro shall be aborted.

I have tried different things, but nothing works. Can anyone help? Thanks! :pray:

Use a "Pause Until" action set to "the pressed keys change" and set the action timeout to 2 seconds, abort and notify options both off.

Lateral thinking -- when no keys are pressed, any pressed key is a change :wink:

Be warned that the key pressed will be passed to the active window/field/dialog, so watch out for side effects.

2 Likes

That's exactly what I want. :smirk:

Thank you very much @Nige_S but I do not know how to do it. Would you be so kind to post me a template macro? You do it in 30 seconds, or in 25 :smirk:

It's just the one action that you drop into the appropriate place in your macro:

Pause Until Change.kmactions (467 Bytes)

...with the "Set Action Timeout..." option as:

1 Like

I am obviously doing something wrong. With this macro, "Done" should not be shown if I press a key after "f"", but it is shown. :man_shrugging:

1 Like

My bad -- I was concentrating on the pause action, assuming you had the branching already.

There's (at least!) two ways of doing this. The obvious way is to grab the millisecond time just before the pause action and just after -- if the difference is less than 2000 then a key was pressed, otherwise it was a timeout. But that could leave you at the mercy of timing issues around the 2 second mark.

IMO a better way (unless you need the time!) is to use the fact that a timeout can abort the macro. If you just want to cancel, leave "Timeout Aborts Macro" turned on and "Notification" off:

Pause Until Keypress or Abort.kmmacros (1.6 KB)

Image

If you want to continue rather than abort, perhaps to do some cleanup, and so need different branches depending on whether or not a key was pressed -- do the same but catch the error with a "Try/Catch" block. The logic would be that "no error means a key was pressed":

Pause Until Keypress and Branch.kmmacros (2.2 KB)

Image

1 Like

You've got to do something like this:

Cancel Macro if Keys Pressed Before Time Limit Example v1.00.kmmacros (9.2 KB)
Keyboard Maestro Export

The first pause gives you time to get your fingers off the macro trigger.

Remember the timeout in the pause-until action.

-Chris

3 Likes

For now, thank you @Nige_S @ccstone very warmly for your support. I need some time to try it all out. After that I will get back to you with the result ... and tell you what this is all about, if anyone is interested :rofl: :joy:

Another token I've yet to explore -- thanks for the nudge, @ccstone!

1 Like

It'd be the other around, wouldn't it - keystroke cancels macro, timeout leads to "do stuff"?

Unfortunately, none of the macros work. Whether I just press "f" or "f" and immediately afterwards another letter both lead to the same result. Does this mean that it might not be possible?

Ok, may I kindly ask you to take a look at the two macros below? They are to illustrate what I would like to do.

Macro 1: Just type "s", but at key DOWN not on release. This ensures normal writing, even when typing fast.

Macro 2: Starts Safari if I touch the trackpad within one second after typing "s".

This works perfectly. But I would like to have macro 2 like this:

  • If no other key is pressed for a second after "s" = launch Safari.
  • If another key is pressed after "s" (within one second), don't launch safari.

Does anyone know how to do this? Thanks a lot! :pray: :smiley:

Macro 1:

Macro 2:

Probably -- I'm confusing myself now! But the important bit is the ability to branch depending on keypress or timeout, and @Frankb can do it whichever way round is required.

@Nige_S Sorry, I'm not sure I understand you. Can you tell me how to solve this?

  • If no other key is pressed for a second after "s" = launch Safari.
  • If another key is pressed after "s" (within one second), don't launch safari.

I'm not sure understand me either! I'm very much learning as I go on this, so apologies if I'm sowing confusion...

There are reasons we're advised to use chords rather than unmodified keystrokes as hotkey triggers. And the workarounds to solve those problems will make the macro less reliable. the pressed keys change includes key release, so you need a pause between trigger and state check else releasing the trigger key will cancel the macro -- make that pause too short and you'll cancel the macro when you don't mean to, make it too long and it won't register the next keypress if you're a fast typist.

Also note that "ss" is quite a common combo to type -- and if "s" is your hotkey that will trigger the macro twice rather than trigger then cancel! So we need a semaphore lock with a very short timeout so any new instance aborts (rather than being added to the FIFO queue) if the macro is already running.

(I didn't know about that until trying this out, so I've certainly learn something today -- thanks!)

The following seems to do what you want, at least when used with "sharp and deliberate" keypresses -- you'll have to find out for yourself under real world conditions. I've kept the "Try/Catch" format because that makes the logic explicit and easier to follow.

Revised Pause Until Keypress and Branch.kmmacros (6.0 KB)

Image

1 Like

Good morning @Nige_S In any case, it's morning where I am. :smiley:

Thank you so much that you dedicate your time to me. You are my hero anyway. And I'm really sorry if I'm wasting your time on something that is not solvable, maybe. But your macro doesn't do what I want it to do.

A simple test:

  • just type "s". Safari will open. That is correct.

  • Type "s + space". Safari will also open. But it should not. because another character (space) comes after the โ€žsโ€œ. The pressed key change.

That's probably what you explained to me. This macro is only about time, not about key change.

When I write "simplicity" Safari is not opened. That is correct. But not because the first letter โ€žsโ€œ is followed by another 9 characters, but because too much time passes between the first letter โ€œsโ€œ and the last letter โ€žyโ€œ.

Is this correct?

Those both work as requested for me. But you have to be deliberate -- try "s"then wait a second then space. I think you're typing to quickly...

You must have a delay after the trigger and before the "Pause Until..." action so that the trigger's release is ignored. But any character typed during that delay will be ignored -- I think you are typing the space too soon. And when you type "simplicity" you might type fast enough to skip the first couple of characters, but at some stage you'll hit a key after the delay but before the timeout -- if you use my macro as provided you should get interrupted by the "Display Text" timeout message before you complete the word.

So the macro is about both keypress change and time.

IMO, the requirement to use an unmodified keystroke as a trigger is a fundamental flaw -- you might be able to get it to work some, even most, of the time by setting the timings to suit your typing speed but it will fail often. And as you're obviously a proficient typist I can't see why you'd find it more efficient to type an "s" and wait two seconds for Safari rather than type eg โŒƒS and have it appear instantly.

But that's probably me applying my own prejudices -- perhaps if you can explain why you need to trigger with an unmodified keystroke rather than the "recommended" method someone will be come up with a different approach.

@Nige_S Yes, it's all about writing fast, keeping your fingers on the keyboard and your eyes on the screen.

If all I have to do is type "s" and I can get two actions out ("s" and open Safari) then everything I described above is fulfilled.

But if I have to type โŒƒs, then it doesn't. I admit this is a luxury problem.

My original idea was to work around the usual short/long press macro. They don't work when you type fast because the letters are typed when released, not when pressed. This leads to the problem that not "simplicityโ€œis typed, but โ€žismplicityโ€œ. โ€žsโ€œ is typed on release, while "i" when pressed. With โ€žmy systemโ€œ, letters would be typed when pressed. This avoids glitches when typing fast.

But well, it doesn't work. I'll experiment some more with "the mouse moves". This is almost equivalent.

Thank you again for your help :+1:

Just coming at this from a different angle - it seems that you are trying to come up with a system where you can launch Safari during normal typing of text. And you type fast and accurately. You don't want to have to use a modifier key or touch the trackpad - you want to just type stuff and depending on your typing Safari launches or not?

Since you are inventing your own coded system anyway why not just use a Typed String Trigger to launch Safari?

If say you used "sqq" as the trigger that would allow you to choose to launch Safari at any time in your normal typing by just typing "q" twice after an "s" and the "sqq" would not appear in your typed text as Keyboard Maestro handles deleting the typed string.

The reason for the "qq" being that no words (as far as I know) have a double q in them. But there are other letters that could work too.

1 Like

That's a very good suggestion @Zabobon. At the moment, that's exactly how I do it. My "qq" is "space,space" being that no words have a double space in them or at the end. And because that is even faster.

Unfortunately KM does not measure the time for such triggers. If a word ends in "s + space", I think about something for a moment and then accidentally type space again, the macro "open Safari" is triggered (this is just a sample).

The macro should only trigger if "s+space+space" is typed within one second.

Again I admit, this is a luxury problem :slight_smile:

PS: But I still find it surprising that KM can not do something so simple: Do something when nothing happens, after typing a letter.