[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