Left click after right click make context menu not working gojs

This is a part of my node

 new Node("Table", {
    contextMenu: getContextMenuTemplate(navigate),
    locationObjectName: 'BODY',
    locationSpot: Spot.TopLeft,
    isShadowed: false,
    minSize: new Size(60, 40),
    resizable: true,
    selectionAdorned: false,
    selectionObjectName: 'BODY',
    shadowColor: 'black',
    shadowOffset: new Point(10, 10),
    click: (_, node) => {
      ...
    },
    doubleClick: (_, node) => {
      ...
    }
  })
...

When I left click to select it, resize elements shows up, right after I left click on it the context menu show up but the functions are never executed

Is your context menu implemented as a GoJS Adornment, or is it implemented as HTML?

I don’t understand the exact sequence of actions I need to take in order to reproduce the problem. Do you see the behavior if you run Basic | GoJS or Context Menu | GoJS ?

I use a gojs Adornment for the contextMenu

After more investigation I have two issues in fact

The first one, if we left click and right after we right click, the context menu is not showing up before a certain delay (need to click again) and in local, it show up but the button is not working (but if I reopen it after a certain delay, it works)

Is the problem that you describe reproducible in Basic | GoJS ?

If so, please detail the exact steps I must make to reproduce it.

If not, could you please provide a stand-alone sample and detailed instructions for reproducing the problem?

I did not mentionned it after I rework my message but I can reproduce the issue in Basic | GoJS

As mentionned in the message, if you left click and right after you left click, I you do it fast enought, the context menu is not showing up

I also see that I did not explain more about the second issue

The second one is, if you wait (approx 1s) you don’t have the first issue (the dropdown menu is showing up) but the data is null

Two left clicks close together in time results in a double-click event.

But unless you handle click or doubleClick events to cause a context menu to appear, I don’t see how two (left) clicks would cause a context menu to show.

Note that a “click” requires a mouse or finger down event soon followed by an up event without moving too far away. How “soon” a second click results in a double-click is determined by the system. The distance between the clicks is controlled by ToolManager | GoJS API.

not two left click, one left and one right click

I assumed by “right after” you actually meant to say “soon after” or “immediately after”, not after a right-click.

OK, so if you meant to describe a left-click followed as soon as you could by a right-click at the same point, I can try to duplicate that to see if there are any surprises that cause a contextClick not to occur.

For the other issue, what data is null?

yes

This is the button that I use

$("ContextMenuButton",
        $(Panel, "Horizontal",
            $(Shape,
                { margin: 3, strokeWidth: 0, geometry: svgToGeo(icon), visible: icon !== undefined }),
            $(TextBlock, text, {
                margin: 5, font: '15pt sans-serif', width: 150
            }),
            { click: action},
        ), visiblePredicate ? new Binding("visible", "", (o, e) => o.diagram ? visiblePredicate(o, e) : false).ofObject() : {});

the “data” that is null is, from both visiblePredicate and action the GraphObject.part.data that they give retrieve a null

How is that defined? Why is a predicate a click event handler? The function signatures are quite different, and predicates do not have side-effects.

const generateButtonParameters = (name: string, _: (to: To, options?: NavigateOptions | undefined) => void): [(e: any, obj: any) => void, (o: any, e: any) => boolean] => {
    return [
        (_, thisObj: GraphObject) => { // action
            const nodedata = thisObj?.part?.data as ObjectData;
            const redirectUrl = nodedata.hyperlinksArray.find((hl: NodeHyperlink) => hl.name === name).url as string;

            //TODO: replace window.location.href by navigate(`../..${redirectUrl}`); where navigate is currently _ https://forum.nwoods.com/t/mergenodedataarray-with-group-node-causes-exception/14798/9
            redirectUrl.startsWith('http') || redirectUrl.startsWith(' http') ?
                window.open(redirectUrl, "_blank") :
                window.location.href = `../..${redirectUrl}`;
        },
        (o, _) => { // visiblePredicate
            const nodedata = o.part.data as ObjectData;
            return (nodedata.hyperlinksArray?.find((hl: NodeHyperlink) => hl.name === name)?.url ?? "") !== "";
        }
    ]
}

OK, so I hope you can see how that visiblePredicate does not make sense as a click event handler.

there is a typo in the code that I sended, I fixed it, visiblePredicate is not a click event handler, action is

When the user first does a left click, InputEvent.clickCount is 1. If the user then quickly does another left click, InputEvent.clickCount is 2, and the second click is considered a double-click.

If the user first does a left click and then quickly does a right click, that second click also has InputEvent.clickCount == 2. By convention a right click cannot be a context-click if clickCount > 1 – i.e. when it’s a double-click or a triple-click. This is normally desired to avoid extra context click events if the user accidentally does two or more right clicks quickly.

In your situation there is a left click and then a quick right click. I can see why you would want to treat that right-double-click as wanting to invoke a context menu. But I hope you can see why the rule had always been that right-double-clicks never invoke a context menu. I don’t know that we want to change this behavior.

But you can change the implementation of the ContextMenuTool by overriding the ContextMenuTool.canStart method:

  new go.Diagram("myDiagramDiv",
    {
      "contextMenuTool.canStart": function() {
        if (!this.isEnabled) return false;
        const diagram = this.diagram;
        if (this.isBeyondDragSize()) return false;
        if (!diagram.lastInput.right) return false;
        //if (diagram.lastInput.clickCount > 1) return false;
        if ((diagram.lastInput.isTouchEvent && this.defaultTouchContextMenu !== null) ||
          this.findObjectWithContextMenu() !== null) return true;
        return false;
      },
    . . .

That is the definition of ContextMenuTool.canStart with the check for InputEvent.clickCount commented out.

Note that overriding a method on ContextMenuTool has no effect on the raising of any “…ContextClicked” DiagramEvent or on calling of any contextClick property.

I think that there is a misunderstand here, may I explain myself badly, and sorry for that

the steps are :

  • left click (select the node)
  • right click (do nothing if done too fast after the left click)

There is no double or triple click