Fix lockup when a scroll event is received outside the drawing area
commit6bf756c665c73f2ad222ed7b1d99987f8d9ec04d
authorPeter Clifton <peter@clifton-electronics.co.uk>
Sun, 27 Oct 2013 16:53:40 +0000 (27 16:53 +0000)
committerPeter Clifton <peter@clifton-electronics.co.uk>
Sun, 27 Oct 2013 16:53:46 +0000 (27 16:53 +0000)
treee8b608cd1e09f6844690256baa65df119466a64c
parent72238c0a0fe177ac9493c4c08876f7c151c87aad
Fix lockup when a scroll event is received outside the drawing area

This can occur if the user is dragging a component in the drawing area (hence
a pointer grab is in operation), and during this drag, the user moves the mouse
outside the drawing area and touches the scroll wheel.

We then hit the scroll event handler, mouse action handler, action dispatcher
etc.. and find we do not have a current location known. (The cursor is outside
the drawing area).  We then prompt for a location, and using a recursive main-
loop, wait for some kind (e.g. a mouse click) which gives one.

The problem appears to be caused by the fact it is likely we get a second
scroll event with the first, and that we process this from within the recursive
main-loop. We are still outside the drawing area, so prompt the user for a
location, and enter another level of recursion. (In my tests, I was able to hit
6 or 7 levels deep of main-loop recursion).

Our code fails to exit its recursive main-loop if it rucurses, and in any case,
we would not want to prompt the user "n" times in a row. The failure to exit
from recursion is probably due to the event handlers attached by the first
recursive main-loop being called prior to those attached later. (We attempt to
quit the first recursive main-loop, but cannot, as there are others now running).

As a quick work-around to the immediate problem, prevent scroll events being
received from within the recursive main-loop. This prevents the lockup, but
ideally we should re-think how we handle these events to avoid requiring the
user to click on a coordinate.

I have also added a GDK_THREADS_{LEAVE,ENTER} pair around running the main-loop,
as this is what GTK's code does for gtk_dialog_run().
src/hid/gtk/gui-misc.c
src/hid/gtk/gui-top-window.c