DisplayableManager ::OnInteractorStyleEvent for ThreeD keypress

We have a DisplayableManager that implements ::OnInteractorStyleEvent to respond to key-presses while the mouse is in the ThreeD render frame. In order to actually receive a callback for these events, it seems that I need to click in the ThreeD render frame first, before pressing a key.

Is there some state I can change in order to receive these events after simply mouse-enter, rather than requiring a click first?

(from what I can tell, the vtkInteractorStyle only raises a callback if it sees an observer for a given event… I tried setting a breakpoint in vtkMRMLAbstractDisplayableManager::vtkInternal::UpdateInteractorStyle, but that bp is not hit when I click in the render window, so I’m not sure where the observer might be added/removed…)

This is a longstanding issue - in the past we changed to focus on mouse enter, but on some platforms that caused the window to raise to the front when you move the mouse over it.

The best solution IMO is to use Qt key bindings to get the events and then sort out which window they belong to.

1 Like

I think the main issue is that we don’t show which view is “active”. We could change viewer window border or header to indicate that the view is in focus.

This would be a hint for the user and it could be also used for forwarding unprocessed Qt keypress events to viewers. It could be also useful for specifying view-specific actions (such as “Show in active view”).

There is already an Active attribute for view nodes, I guess that was ported over from Slicer 2 or 3.

1 Like

Ah, ok, it is driven by the Qt widget keyboard focus. Thanks. (This did feel kind of familiar). For my purposes I think I can just set that manually to the ThreeD view when the user enables this short-term interaction mode, at least to reduce the surprise/confusion.

I wonder if this has been fixed in more recent Qt versions, because at least according to the docs, setFocus is only supposed to apply when the window is active. Or maybe we were accidentally calling raise() somewhere too.

It was actually in the pre-Qt days (Tk) and it would happen on linux as I recall and was probably a window manager “feature” that setting the focus on a vtkRenderWindow resulted in raising the parent toplevel window. This wouldn’t be a problem if the user is already interacting with the app, but if you try dynamically track mouse enter / and leave events so that the correct VTK window gets the focus then it’s a problem because those events happen even if the window isn’t in front. That’s why I’m suggesting (and Andras too I believe) are suggesting that we could track the mouse to know the active window, but use Qt to get the events globally and pass them to the correct viewer.

I agree with Steve. We should not change the focus just because the mouse hovers over some window. This would be a huge deviation from how widgets are supposed to be used and it would probably cause many problems.

Definitely not advocating that globally. (I’ve used default Motif enough to strongly dislike that interaction style :slight_smile:)

Setting focus myself on a one-off basis after the users clicks the mode checkbox should be sufficient. Thanks.