Canvas gets focus on mouse release

We realized that the gojs canvas will steal the focus on mouse release. So in the gif you see:

  1. I highlight the text and while still holding the mouse key I hover over gojs canvas and release the mouse. Notice the text loses the highlight and the active element becomes the canvas.

  2. I highlight the text and while still holding the mouse key I hover over a normal canvas and release the mouse. Notice the text highlight stays and active element won’t change.

Is there any way we can disable this behavior? Is this is bug?

canvas_focus_on_release

Here’s the full code on Stackblitz.

Have you tried it in Firefox? You’ll notice that the behavior is different from Chromium or Safari. You might get around that by implementing a “blur” listener on that “text to highlight” element. I don’t think we should do anything about the behavior of external elements.

  • Safari has the same issue
  • Firefox seems to be working fine

I have zero idea what you mean by " behavior of external elements". This behavior is specific to gojs canvas. I think my example was comprehensive enough to show that.

Implementing a “blur” listener on that “text to highlight” element.

To do what? Why would I need an blur handler here for?

I thought that the problem you are describing is one involving what happens when the user does a mouse down and drag in that element where the user is highlighting text. In some circumstances that element loses focus and in others it does not. You can affect that by implementing a “blur” listener to (conditionally?, after a timeout) call focus again on that element. Any other components on the page might want to gain focus when a mouse-up happens there, not just an interactive diagram.

The blur handler is not gonna work. I might have other focusable elements there that a user might Tab into or click on. I don’t want to return the focus to this particular input.

But let’s focus on the actual problem, shall we? The problem seems to be the mouseup handler on the canvas.

  • mouseup triggers doMouseUp handler on this.currentTool.doMouseUp
  • which then triggers doMouseUp on line 5255
  • which then calls the t.doFocus() on line 5268. t here is the Diagram

This has nothing to do with dragging anything. As long as a mouseup events is fired on the canvas, it will steal the focus regardless of where the mousedown has happened. So the question is, how can I disable this or overwrite this behavior.

gojs_mouse_up

You probably want to override ToolManager.doMouseUp, either by modifying the instance that is the Diagram.toolManager, or by subclassing ToolManager and installing an instance of it as the Diagram.defaultTool and Diagram.toolManager. Maybe something like:

new go.Diagram(. . ., {
  "toolManager.doMouseUp": function() {
    if (this.isActive) go.ToolManager.prototype.doMouseUp.call(this);
  },
  . . .
})

But I don’t know if that might break some other cross-component interactions that your app might do. I think it’s safe enough for most cases.

Why would you need to get focus on mouseup? Wouldn’t that make sense to happen on mousedown? That seems to be the case natively with input on browsers. The document.activeElement changes when you do mousedown on an input.

Yes, by default a GoJS Diagram will request focus both on mouse-down and on mouse-up events. I think the idea is that if a diagram is receiving mouse events (or pointer/touch/stylus events) it probably wants to get keyboard focus too.

Does it work for your case?

That doesn’t make sense to me. If I haven’t touched/clicked/pointed on the canvas, I don’t want the keyboard focus either.

My interaction has started elsewhere and I just release on the canvas. I fail to see any use case where only releasing on any element requires focus change. As an inspiration you can look at how Figma canvas works. Or basically any other native elements on a webpage. Elements only get focus when they are clicked/touched on.

Yes, by default a GoJS Diagram will request focus both on mouse-down and on mouse-up events. I think the idea is that if a diagram is receiving mouse events (or pointer/touch/stylus events) it probably wants to get keyboard focus too.

I know this already. My question was why?

Does it work for your case?

It seems to be working so far. I’ll be doing more tests.

Think of most situations where the user does a drag-and-drop from a palette-like component to a diagram. There’s no mouse-down on the target diagram, but there is a mouse-up.

In fact, way back in v1 (I don’t remember the exact versions, maybe 8-10 years ago) a mouse-up event did not cause the diagram to get focus. We got complaints about that behavior, and we also encountered some unusual situations where it really was wise for the diagram to get focus. So we changed to the current focus policy. I can’t remember any focus complaints, except for the aforementioned difference in behaviors between Firefox and Chrome, since then.

That slightly makes sense but the users could have just called diagram.focus() after they drop something on the canvas. So it would be a user-space thing.

Anyway, thanks for the help.