Problems Dealing with Dynamically Changing Menus on macOS

I built a macro containing four nested If/Then actions. It all works fine, until it doesn't. When it stops working correctly, I quit and reboot both KM editor and engine. Then everything's fine until it fails again.

Specifically, the if statements are looking at menu status to figure out the content of the selection. When it fails, it doesn't evaluate the if statements correctly.

Is this just a chronic problem that I need to get used to, or are there best practices to keep KM from losing the plot?

Thanks.

depending on why you're using the nested IF statements, a SWITCH statement might work better for you.

Thanks for the thought. I looked at the SWITCH statement in the wiki, but I didn't think it was the right solution. Each if statement is evaluating two or more menu conditions.

I'd love to learn a better way to do this, but it seemed like the wrong tool for the task.

Could you post your macro so we can look for other ways to improve it?

I have no reports of anything similar, so it's hard to know what you are experiencing or why.

Menu actions require a lot of accessibility inter-process communication, so it is possible there is something interfering with that.

1 Like

Hey @anamorph,

You've told us virtually nothing we can use to help you.

  • What version of macOS?
  • What version of Keyboard Maestro?
  • What application are you working in?

@vincent_ardern is right – we need to see your macro.

If we're not testing we're guessing, and guessing often wastes everyone's time.

-Chris

Thanks, Peter, just wanted to check. I'm continuing to troubleshoot to see if I can isolate what's going on.

Always appreciate you help, Chris. Yeah, I know the drill. I just wanted to know if this was a known problem or not. Since it isn't, it means I haven't gotten to the bottom of it yet.

Okay, did some more testing, and have an evolving hypothesis.

@peternlewis, is it possible that KM can't see a change in an app's menu state until the menu has been pulled down?

In simplified form, my macro is evaluating the state of a menu item. Depending on what kind of item is selected in the app, the menu item changes. My macro triggers various actions depending on the type of object selected.

It appears that the macro can only read the current state of the menu item after the menu has been pulled down. If the menu changes state without being displayed, KM will not recognize the new state.

I don't understand what's going on under the hood between KM and the OS. Is this menu refresh issue possible, and is there a better workaround than just having KM pull down the menu to refresh it?

If you'd prefer to see all the details, let me know and I'll post the macro and a more complete explanation.

Thanks for your help.

Dynamically changing menus on macOS can be quite problematic, and this has been the subject of much cursing amongst automators for decades...

The problem is NOT with Keyboard Maestro it's with macOS.

The only way to deal with it that I know of for certain is to open the menu and cause the macOS to update itself.

This is clunky, but it works.

It might be possible to query a menu object with System Events and get it to update, but I'd have to know the app and experiment to find out.

-Chris

1 Like

I agree. I've now done quite a lot of testing, and it's definitely the source of the problem.

I appreciate the effort. The App is Scrivener 3, and the menus I'm evaluating are:

  • Documents>Merge

  • Edit>Select>Select with Subdocuments
    and

  • Edit>Select>Select Current Text

(These are the dynamically changing menu items. If you select documents in the Binder, Select Current Text will exist but be disabled. If you select folders, Select with Subdocuments will exist and be enabled.)

I'd appreciate the help to try to update the menus with System Events.

Otherwise, I'll go the clunky route.

Thanks.

Definitely if the app is poorly behaved.

A standard Cocoa app will properly handle this, but cross platform apps particularly often don't necessarily update their menus for accessibility purposes until you force them to.

When asked for the menus via the accessibility subsystem, the menus are either not there, or not currently correctly built for the context (eg, menus may be disabled or invisible when they should not be).

Options to force the application into updating its menus include:

  • Switch out and back to the application, and then use the Select Menu Item action.
  • Use the Show Menu variant (leave the item field blank) of the Select Menu Item action to show the menu item first, and then the Select Menu Item.
  • Simulate a click in the menu bar, and then use the Select Menu Item action.
  • Desperate measures, simulate a click in the menu bar, and then use arrows and typeahead (Insert Text by Typing) to select the menu item.

Is it possible to list the menu items in eg AppleScript - and wait until the right one shows up? (Probably looping - with a "bail out" capability.)

This did it. I used the Show menu with item field blank followed by a keystroke action Escape key. The menu flashes on screen for a nanosecond at the start of the macro, and then everything works.

Thanks!

2 Likes

Hey @anamorph,

I took a look, and it's NOT possible to cause the dynamic menu to update without actually opening the menu (with AppleScript UI-Scripting).

So there's NO advantage to using AppleScript over Keyboard Maestro in this case.

-Chris

Thanks very much for looking into it.

1 Like