[vtk-developers] interaction focus problems

Chris Kruszynski Chris.Kruszynski at cwi.nl
Thu Aug 7 12:08:03 EDT 2008


Hello,

I can't help but notice that the focus mechanism in handling events is 
kind of overshooting its purpose. The way I see it, it's only there so 
various observers (widgets and interactor styles) listening for 
keyboard/mouse events can prevent others from receiving/blocking those 
keyboard/mouse events if the observer is in some self-defined 'active' 
state. The only way to get hold of events if someone else has focus is 
to declare the vtkCommand subclass as PassiveObserver, as these are 
handled before focus holders.

Focus is granted for all events to which the vtkCommand has subscribed, 
not just the mouse/keyboard events. This includes events that are 
totally or at least partially unrelated to mouse/keyboard events, and 
which perhaps should not have been blocked but passed on to other 
interested observers.

While the widgets which grab the focus only subscribe to keyboard and 
mouse events, vtkInteractorStyle uses the same vtkCallbackCommand for a 
whole range of events which are not necessarily related to input events. 
The result is that during interaction none of these events are passed to 
interested parties, even if they perhaps should be.

Most notably, vtkInteractorStyle also subscribes to DeleteEvent. This 
means that if the interactor is deleted while a mouse button was still 
pressed and focus was held by vtkInteractorStyle, no other interested 
parties will receive this event. If, say, there was a vtkWeakPointer 
pointing to the interactor, it would suddenly stop working as 
advertised. I know the only place where vtkWeakPointer is used it is not 
pointing to an interactor, but this second example might be more 
relevant: vtkInteractorObserver listens for the DeleteEvent on 
vtkRenderWindowInteractor to set it's Interactor ivar to NULL if the 
interactor is deleted. vtkInteractorStyle duplicates this behavior using 
the same vtkCallbackCommand used to listen for keyboard/mouse events. 
The effect is that if an instance of a subclass of vtkInteractorStyle 
has focus, only that instance will receive the DeleteEvent. Widgets also 
inherit this behavior from vtkInteractorObserver, thus if the interactor 
is deleted while vtkInteractorStyle had focus (say, the mouse button was 
still pressed) all widgets using that interactor will no longer have a 
valid pointer to the interactor, which might lead to obscure crashes.

Also, vtkInteractorStyle blocks TimerEvent if it has focus, irrespective 
of whether it actually uses a timer or whether the TimerEvent is even 
from it's own timer or somebody else's. Thus if something is doing a 
timer-based animation, this suddenly stops if the mouse is pressed, and 
continues when it is released.

Finally there is a small issue with how the interactor styles use 
GrabFocus: when the mouse wheel is turned, the styles grab and release 
the focus, even if they already had the focus because a button was 
pressed. The effect is that after turning the mouse wheel during other 
interaction focus is lost.

I would like to propose the following changes:
- vtkInteractorStyle should have a separate vtkCommand for 
non-mouse/keyboard related events, so it doesn't block these events 
unintentionally.
- vtkInteractorStyle should not listen to DeleteEvent at all, since it's 
superclass is already doing the same, and handles it in the same way.
- Either check for previous focus when handling mouse wheel events, or 
don't touch the focus at all for those events, as I am not sure why 
focus is grabbed there in the first place.

I can apply these changes and create a patch, but I would like to hear 
other people's opinion before I even start.


kind regards,

Chris Kruszynski




More information about the vtk-developers mailing list