GNOME Bugzilla – Bug 142529
Focus tracking mode = Centred makes Launch-menu navigation jumpy in gnopernicus magnifier
Last modified: 2005-03-22 09:23:25 UTC
Using Gnome built with gnopernicus-0.9.1 and gnome-mag 0.11.1 on 3rd of May 2004. - Launch gnopernicus (and enable magnifier) - Select Preferences->Magnifier - Select 'Add/Modify' - Select focus tracking mode as 'Centered' - Click on the 'Launch Button' - Move the mouse slowly up and down the Launch menu. Note that the menu navigation is very unstable in the magnifier window.
Gnome mag changed about 1 hour ago, on HEAD. Please try the new gnome-mag and see if the problems are still there.
I can say with nearly total confidence that this is 100% unrelated to the gnome-mag changes.
I agree
Yes you are right Bill this is not a gnome-mag problem. I also do not think this is a bug. When you open the launcher menu and you move the mouse up and down in that menu, when the mouse is over an item of that menu, gnopernicus recives a focus event and, the tracking mode automaticly switches to "focus tracking". Also with the slightest movement of the mouse gnopernicus will switch back on to "mouse tracking". The ROI for focus "tracking" can be different from the ROI for "mouse tracking" and this is causing the unstability. So gnopernicus is responding OK. I can't see a fix for this .
This seems to be another illustration of Gnopernicus really needing to know when focus is generated by the user from a keystroke, and when it isn't. How can Gnopernicus do the right thing (not react to focus driven by the mouse) if it isn't listening to all keystrokes that can generate focus (tab, arrows) and matching them to the corresponding focus events?
I disagree with Peter about the keystrokes here; I don't think listening for keystrokes is the only, or even the best, way of doing this. But while I agree with Dragan's observations mostly, I think the observed end-user behavior is not desirable. Perhaps a better solution would be to avoid "focus:"-driven ROI changes while the mouse is active: for instance: on_focus: if ((time-since-last-mouse-move < timer) && (focus-roi-is-inside-target)) { deferred_roi = roi; roi_timeout = g_timeout_add (defer_focus_roi, timeout); /* put this on a timer, which resets on each */ } Then either remove the timeout or reset its timer to zero each time the mouse moves. This means that if the mouse stops moving, the focussed object will be centered after the timeout period. Also, if a focus event which is outside the mouse-based ROI occurs, gnopernicus will follow it successfully. In this last, rather unusual case, perhaps the mouse tracking should be temporarily suspended so that the user can see where the focus has gone.
Apologies for spam-- ensuring Sun a11y team are cc'ed on all current a11y bugs. Filter on "SUN A11Y SPAM" to ignore.
at higher mag factors this bug can really impact usability of magnifier.
The real issue here is that when the user is driving the desktop with mouse movement, Gnopernicus should be a bit smarter and ignore "mouse-driven" focus events. This, again, may be an XEvIE-requiring situation. Gnopernicus needs to know that mouse activity is happening and act smarter.
xevie won't help here, I do not believe this is a reasonable solution. The solution in comment #6 makes more sense to me, and does not require any new notifications or API.
to be more clear - in general we do NOT want to thread mouse motion events through multiple processes, and at-spi already gives mouse motion notifications. So only the xevie key notifications are of potential use - but they, too, fail, since focus changes can occur in response to things other than user key input, and we only want to reject focus events which occur _while the mouse is moving_.
Created attachment 37492 [details] [review] proposed patch
not sure how the patch above is intended to solve the problem. It seems to me that it would interlace focus tracking events whenever the process idled, which could happen while the mouse is still moving...
Could we use a g_timeouts here instead? I suggest that we use a g_timeout to un-set static gboolean mouse_is_moving, and set this gboolean and a static last_mouse_time when mouse motion occurs. We could then discard focus tracking events while mouse_is_moving. mouse_is_moving would only get set to FALSE after the timeout expires, and the mainloop is idle - and then, only if a suitable length of time has elapsed since last_mouse_time.
What is a suitable timeout? [Duh answer: longer then it would take on most people's hardware to receive a focus event from a mouse-over; shorter than is likely for a user to move their hand from the mouse to the up/down arrow key]. 1/10th of a second? Half a second? Longer?
the intersection between 'longer than it takes to receive a mouseover focus' and 'shorter than the user's mouse-to-keyboard time' is the issue. AFAIK the mouseover-focus time is usually short, but if it could be configured to a longer value (say > 200 ms) then we could have a problem. The gnome systems I have tried seem to have very fast mouseover-focus response, so I suggest we try 100 ms.
The idea is to present only the last event to magnifier. The patch does not only delay the event, it skips from presentation all events except last. So, Bill, your idea in comment #14 is implemented, but in other way. My first try was with g_timeout. But the results are better with g_idle. The impresion whit g_timeout is that magnifier doesn't fallow the mouse in case of fast (fast = not very slow) movements.
That's not quite what I was suggesting in comment #14. Using g_idle is not correct IMO. I don't think the last focus event should be acted on either, if the mouse has been moving so recently. The patch will still result in jerky motion in some cases.
Created attachment 37883 [details] [review] a new proposed patch
Hi Remus: That's the basic idea I had in mind. However, the latest patch adds a timeout on *every* mouse motion. That's a lot of overhead, and I think we can/should avoid it. I also think the increment/decrement of src_mouse_moved is an invitation for problems, if the increment/decrement counts are wrong... we should use a boolean here instead. I am attaching a patch which does the following: * when the mouse moves, attach a g_idle_source if one it not already waiting (this means all we need to do is check for (mouse_is_moving_idle_handler == 0) on each mouse motion event, for efficiency); * the mouse_is_moving_idle_handler re-sets a g_timeout (mouse_stopped_moving_timeout) each time gnopernicus becomes idle after a series of mouse motion events; * mouse_stopped_moving_timeout re-sets 'src_mouse_is_moving' to FALSE after an idle period of SRC_MOUSE_MOVED_TIMEOUT milliseconds.
Created attachment 37894 [details] [review] revised patch which uses less CPU, uses boolean for is_moving, etc.
also, I found that on my system a slightly longer timeout period (300 ms) seems to give better results. With 200 ms I still saw quite a bit of jerkiness - this may also have to do with the fact that at-spi's mouse motion events don't get sent as often as 'X' mouse events, i.e. they are less frequent, so delays of 200ms or less will be impacted by the at-spi mouse-motion latency and the granularity of mouse-moved events (currently 100 ms if the mouse has recently been 'idle', 20ms while the mouse is continuously moving).
Patch looks ok for me.
yesterday was code freeze :-/
Comment on attachment 37894 [details] [review] revised patch which uses less CPU, uses boolean for is_moving, etc. Patch committed to cvs head.