Keypress dependant loop takes on a life of it's own

Hello,

I tried in vain to create a keypress dependant macro to read through my apple mail emails quickly.

The apple mail part is simple and irrelevant to my question which is why I created a macro with a simple display "hello world", because it's the keypress dependant loop can't does not work.

With the macro below, my objective was to display a new hello world notification each time I press the escape key and exit the macro if I press the § key.

What I get instead are keyboard maestro notifications displayed in batches of 200 to 300.

thanks very much for your help

I wrote the macro below

Loop press key.kmmacros (3.9 KB)

Your test macro works as advertised for me (KM 10.1.1, macOS 10.13) -- one esc keypress, one alert. How are you triggering it? Are you, perhaps, spawning multiple instances, each responding to the keypress?

In case this is an OS-specific problem, say what you're running and I'm sure someone will have the same to test under.

1 Like

OK I will review it again. thanks very much

Like Nice mentioned, one long 1.5s Esc keypress = one notification.

What is your setting for the keyboard's keystroke repetition setting in System Preferences>Keyboard?

What happens if you go to a text field, then
do a long keypress of the a key? let's say, for 2 seconds
Is the result a popup menu?

In addition to my questions, a comment:

There's a "wait for a long keypress, and only then execute an action" macro somewhere in the forums. I can't find the original source but I have a copy of it that I use very frequently, can share it if you like.

2 Likes

Hi @hello !! nice to hear from you ! hello @Nige_S

Instead of focusing on the solution. I would like to describe the problem. I think that my post creates more confusion than anything else.

Basically, I have a little series of actions to quickly read emails in apple mail:

Series of actions (1-5 are a loop)

1- open email
2- mouse left click anywhere in the email to make scrolling active
3- when I press escape →
4- delete that email
5- go to next email
6- resume the loop ie step 1

  • if during the process I press the q key, exit loop ie cancel macro.

All very simple, except for the loop part which is driving me bananas. I can't figure out why I can't do something as simple.

When I asked my question in this forum I did not want to burden/distract everyone with the simple email actions, so I replaced the sequence of email actions with hello world, but the problem is basically the loop. I put a 1.5 second pause as a last resort in the macro because nothing was working. In practice, I do not want to have to press a key for 1.5 seconds. It would defeat the purpose of quickly reading emails. Many will be deleted within a fraction of a second.

I would like to understand how to create the loop and eventually add it in my KBM as a favorite action. Once again, after all these years of using KBM, I don't understand why I am unable to do it on my own.

Unfortunately, I have never had covid, so I can't blame it on a neurological complication of long covid.

thank you both very much. Sorry for the delay in responding. I was trying in vain to progress on my own.

1 Like

Hey @Ronald , same, good to see you!

This one seems to do half of what you need:


When you open an email
If you press the Left arrow key it will delete the email
Other than that, there's nothing more to it
You can see other emails in your inbox using the Up and Down arrow keys, and again, anytime you press Left, it will delete the currently select email.

It doesn't do the scroll, if you can share your macro we can help add that part.

Also: Just learned Cmd-Z can undo the action and recovers the last deleted email


Edit: Forget the macro I just posted, pressing Delete does the same, no KM needed.
Can you share your macro.

Thank you for your post and taking the time to write a macro.

There is a misunderstanding. I can easily delete emails in apple mail with a Better Touch Tool gesture (left 3 finger sweep)

Your macro does not allow you to read the email in large format and does not give you access to the email scrollbar.

I am not looking for a delete action.

I am looking for a series of actions as described above

assume that the Mail app is open.

1- open email "large format"(⌘O)
2- mouse left click anywhere in the email to make scrolling active (see image) so you can scroll down the email, otherwise the scroll bar in the email is not active
3- if I press escape →
3a- delete that email
3b- go to next email ie select next email in list
3c loop back to step 1
4- if I press q cancel the macro

thanks again

Do you actually need a macro for this? Return key opens an email, Delete key deletes it, next email is automatically selected ready for you to hit the Return key again. It seems you are introducing a lot of overhead to save pressing one key per email!

Also, I don't understand your second action. Scrolling is always available, even when the scroll bar isn't visible. And simply clicking in the email body doesn't make a hidden scroll bar appear.

Sidenote: Universally hiding the scroll bar by default was, IMO, one of the silliest decisions Apple ever made. I can understand it on a phone, where screen estate is at a premium, but all it does on a Mac is remove useful information -- how far down a document you are and the proportion of the whole document you are currently viewing.

3 Likes

Thanks for the clarification, understood what you are trying to achieve.

Important:
Seems like the Esc key is incompatible with Mail.
When I try to use it, the computer makes a beep.
Tried using it as a trigger and as part of a macro to break the loop, but same result, the trigger does not trigger it, and when used as part of a macro, it does not break the loop.

Seems like you need at least two macros:

Macro A

One macro that:

  • Starts loop
  • Opens selected mail in Large Format, and
  • Makes this email the active window (your Click at 521, 407 action)

Macro B

Do nothing
In case you do not want to delete the currently active email. For this you need a macro that

  • Closes the Large Format window, and
  • Selects a different email.
    Example of a pseudo-macro:
    Step 1 (Trigger): Press Up key
    Step 2: Close Large Format window
    Step 3: Select next email

Break loop

The action to end all this

  • Press a key,
  • Break whole loop

Made a quick macro, but want to do some further testing

1 Like

You have a good point, but on closer look: if you press return, the email is scrollable with the spacebar but not with 2 fingers sliding down on the trackpad.
When you are reading a large number of emails you really want to keep the keystrokes to a minimum.
Also intellectually, I would like to know how to craete a loop including a command to exit the loop
thanks very much for your reply . Concerning apple and the scroll bar you are 100% right.

I am working on it.
Seems rather incredible to me that creating a loop is not straightforward in KBM
thanks again

If you want to have a series of Actions keep repeating in a loop until a certain Key is pressed, you can select those Actions and Engroup them in an Enclosing Action "Until"

And set the condition to end the loop to be the key you want to press. I wouldn't recommend using "Q" as the key to end the loop as you might type "Q" as part of other typing. The obvious key to use is "Esc".

Also, endless loops can create havoc if they run away with themselves. So, good idea to have a Macro to Cancel All Macros set up with a hotkey you can easily remember!

2 Likes

Fantastic. I will try it now. thanks very muc !

1 Like

Ah, so what you need is to move the pointer over the active email window -- not clicking will reduce the chance of accidentally doing something unintended.

Personally, I'd keep the mouse/trackpad actions to a minimum. I quickly triage the morning mail with Return, Delete and Page Up/Page Down keys, leaving my left hand free to hold the coffee :slight_smile: That does require an extended keyboard, of course... So I've settled for moving the pointer to just inside the bottom-left corner of the frontmost window, where it's least likely to be in the way but still activates scrolling within the email.

So here's a couple of options. The first is loop-less -- simply open your first email, then press esc to delete that and open the next. There's a check to make sure your Inbox isn't the frontmost Mail window to stop you deleting mails before they've been read -- I've assumed Inbox triage, but you could change/add to/remove to suit what you are doing.

Mail Delete and Open Next.kmmacros (4.9 KB)

Summary

And here's a simple "loop" version. Trigger the macro by hotkey and it'll run forever -- because the calculation 1 will always evaluate to "true" -- or until you press the Q key. I've put in "Pause until key up"s matching the keydowns so longer keypresses are treated as a single event rather than multiple (don't actually know if that's necessary! Anyone?). Again, it will delete, open next, move pointer on every press of esc until you end the macro.

Mail Delete and Open Next Loop.kmmacros (8.9 KB)

Summary

I was pleasantly surprised -- having the macro running an endless loop only used ~10% of one core on my laptop. I'd love to hear how it performs on your machine.

As @Zabobon says -- be ready with a manual "Cancel", just in case! It was problem on my machine, but you never know...

2 Likes

This is my favorite and runs very fast on a 2018 Mini
2 minor issues

  • as mentioned by @hello, the Esc keep beep is a bit irritating as one sifts through a series of emails. I tried replacing with other keys like §, but the beep persists.
  • I was reading my email with your macro and realize that from time to time I need to keep my email
    Ideally there should be 3 options Esc (delete), k (keep ie do not delete email and go to next), and q (cancel macro). I tried to figure it out, but I think it's too complex, ie a loop within a loop.

THANKS VERY VERY MUCH !

1 Like

Mute your speakers at the start of the macro, then unmute as part of the Q-key processing?

That's the easiest way, but perhaps you like to listen to music while triaging your email...

As I understand it (and I'd love to be told different!), when an app's window is frontmost KM only "swallows" hotkey triggers -- everything else is passed on to the application, even if (as here) a KM macro is "using" it first. So the System beep is Mail.app informing you that the esc key is not a valid keystroke in the current situation.

The only way I know round that would be to have it be a hotkey trigger, so KM swallowed it whole. That could be done, but introduces more complexity (that's the problem with single-key hotkeys) -- you'd need another Macro Group for "temporary" Mail macros which contained a macro that handles your "key interrupts", one hotkey trigger per action you want to take. Your "main" macro would then simply enable the "temporary" Macro Group, your q action would disable it.

It also reduces complexity -- there's no need for a loop if everything's based on hotkeys! But I'm going to use one anyway, to flash a notification that the processing macro is enabled.

This is just another level in the "If/Else" construct:

if the key is ESC then
    delete the email
    open the next
else 
    if the key is k then
        keep the email
        open the next
    else
        end the macros
   end if
end if

You could probably also do this with a "Switch/Case" action based on the Trigger Clipboard value, and that would be clearer if you started adding more key, but I've stuck with the "If Then Else" actions so you can see the evolution of the macro.

There's also the problem of "next email". By default, where the message list is sorted with newest at the top, "next" is the "next one down" -- so that's the way I've set this up.

Mail Processing Controller.kmmacros (3.1 KB)

Summary

Mail Processor.kmmacros (14.9 KB)

Summary

I'm sure this could be done better, but hopefully it'll give you something to start from.

2 Likes

To swallow the key, use a second macro with a hot key that simply sets a variable. This is generally a better way to detect keys anyway, since it will detect the keystroke (event), rather than the key being down (state). Detecting the key being down means a) you could miss the detection if you tap the key quickly enough, and b) you could detect it twice in successive loops if you held it down long enough.

So create a second macro:

Name: Detect and Swallow Escape
Trigger: Hot Key Pressed Escape
Action: Set variable "Escape Pressed" to 1

Disable this macro.

Before the loop, add the actions:

Set variable "Escape Pressed" to 0
Enable Macro "Detect and Swallow Escape"

In the loop, use the Variable condition to detect if the variable "Escape Pressed" is 1. If so, handle the Escape press and set the variable value back to 0.

Add more macros for more keystroke conditions.

3 Likes

WOW !! Spectacular. Amazing ! I am zooming through my emails. Fantastic ! thanks very much for the macro and your explanations !!

1 Like

Thanks very much Peter. I have to sit down and decrypt your methodology

2 Likes

Ronald's current mailbox:

2 Likes