Under Review

Action Menu does not work with touch/mouse in the simulator - app crash

If you use an action menu using the device buttons everything seems to work fine. But if you use touch, i.e. click on the menu itself in the simulator with the mouse, the delegate is called, but the action menu is not popped and stays displayed.

This ultimately results in an app crash when you do use the buttons in an attempt to get off the menu:

selected 1

Error: Unexpected Type Error
Stack: 

Encountered app crash.

Thankfully, it all seems to work correctly on a real device, but means it cannot be tested at all on a touch device like the venu 2 or vivoactive 6.

This is broken in SDK 7.1.0 through to 8.4.0. It last worked in 6.2.4

  • Now I have got up and had time to look at your code, I can get the same behaviour as you if I move my action menu to be pushed from onShow().

    If an action menu is pushed from onShow(), it does not get popped automatically irrespective of using touch or buttons, and crashes if the back or enter button is pressed after an initial selection which I can see does call the delegate.

    If an action menu is pushed from an input or behaviour delegate, it appears to work fine if you just use buttons, but if you attempt selection using touch, it does not get popped automatically, and crashes if the back or enter button is subsequently pressed

    Clearly there is a bug, and the exact symptoms seen vary slightly dependent on how it is invoked.

  • That is why I said in my followup, WatchUi.ActionMenu

    Action menu was added as a simple discreet menu to match some new on device behaviour. Unlike Menu2 it pops itself. 

    Why is it better to use Menu2? I want a simple menu with a confirm/cancel option to confirm an action. ActionMenu is perfect for that and exists on all devices I'm developing for right now. On most watches it slides in from the side and only partially covers the screen. It is perfect for that whereas Menu2 is heavyweight. Previously in older apps, I use "has" to pick ActionMenu when it's available, and menu2 when it's not.

    I don't need a workaround, it's a sim only bug which I don't experience when I use the buttons, not touch. Although it appears this is different to FlowState. There are no issues on real devices I've found and have used ActionMenu for years without any reported problems. 

    I guess I'm not experienced enough having been here only a decade. 

  • I completely agree with you. Even if you use something in an unusual way, or even incorrectly, it should not crash.

    I was simply trying to suggest why the behaviour you see differs slightly.

    It's clear, action menu is very broken in the sim. Thankfully, I'm not seeing any problems on real devices. 

  • OK, now I know what's happening in my case.

     yes I tried on venux1, vivoactive6 in the sim, with mouse only. The reason experienced forum users post code (even without others asking them) is because it helps others to reproduce it or to spot the problem and help. Not in this case BUT....

    After I saw flowstate's code I realized, that although contrary to him I do use the 

    setActionMenuIndicator({:enabled => true});
    it turns out, that I am not using ActionMenu. Instead:
    // vivoactive6 has onActionMenu instead of onMenu
    (:action_menu)
    function onActionMenu() {
      return onMenu();
    }
    and there I use Menu or Menu2.
    So this explains why I don't see the crash. On the other hand it might also give you a workaround until it's fixed by Garmin: replace ActionMenu with Menu or Menu2.
    And to follow up on this: what is the reason one would use ActionMenu? Looking at the functionality, it's better to use Menu2: Menu2 is since CIQ 3.0.0 while ActionMenu only since 3.4.0. Menu2 has all the functionalities that ActionMenu has, and some more. There might be slight differences in how it behaves in terms of closing itself automatically, but that is probably not the reason they introduced a new set of classes. So what am I missing here?
  • Just to make everyone here happy, I added a custom delegate to my recreation code, and I get exactly the same result.

    No matter how I attempt to select an item or exit the menu, I see the same thing:

    - the action menu does not close itself (as the documentation claims it should)

    - the next BACK or ENTER keypress crashes the app. (Pressing UP or DOWN doesn't do anything).

    It doesn't matter whether I use the mouse to simulate a tap, use the mouse to click on a device button, or use the keyboard to simulate the first button press / action.

    However, to trigger the crash, the 2nd action has to be a button press (either via the mouse or keyboard) - simply clicking on the menu item (to simulate a tap) does not cause the crash for me.

    So it does seem that:

    - after the first BACK or ENTER the action menu is in some kind of broken state where it's still on the screen but it's not supposed to be. Again, the docs say: 

    "An action menu will dismiss it self on either user selecting a menu item or pressing back button."

    This isn't happening.

    - the second BACK or ENTER causes the action menu to try to select the item or close itself, but it can't do that because of the previous point

    TL;DR to cause the crash, do the following action twice: press BACK or ENTER.

    class VeryUsefulDelegate extends WatchUi.ActionMenuDelegate {
        function initialize() {
            ActionMenuDelegate.initialize();
        }
    
        function onBack() as Void {
            // this is displayed as expected after the first action, if the first action is BACK
            System.println("onBack"); 
        }
    
        function onSelect(item as WatchUi.ActionMenuItem) as Void {
            // this is displayed as expected after the first action, if the first action is ENTER (or a tap on the menu item)
            System.println("onSelect: " + item); 
        }
    }
    
    class TestView extends WatchUi.View {
    //...
        function onShow() as Void {
            var menu = new ActionMenu(null);
            menu.addItem(new ActionMenuItem({:label => "foo"}, null));
            WatchUi.showActionMenu(menu, new VeryUsefulDelegate());
        }
    //...
    }

    Sample output:

    onBack
    
    Error: Null Reference Error
    Details: Failed invoking <symbol>
    Stack: 
    
    Encountered app crash.

    Again, even if there's something wrong with my code, I don't think the sim should be crashing in this case.

    Environment: fr955, SDK 8.4.0, Windows