Fix "CursorVisible bugs"

When we enter the modal resize loop on Windows with ClipCursor set, we
cause a feedback loop where every resize causes the cursor to move and
every move causes a new resize. To fix this, we need to ungrab the
cursor when we are enter the modal loop.
This commit is contained in:
Stefanos A. 2013-11-22 14:10:21 +01:00
parent 24aa7893b8
commit e2404d2cfc

View file

@ -73,6 +73,7 @@ namespace OpenTK.Platform.Windows
bool mouse_outside_window = true; bool mouse_outside_window = true;
bool invisible_since_creation; // Set by WindowsMessage.CREATE and consumed by Visible = true (calls BringWindowToFront). bool invisible_since_creation; // Set by WindowsMessage.CREATE and consumed by Visible = true (calls BringWindowToFront).
int suppress_resize; // Used in WindowBorder and WindowState in order to avoid rapid, consecutive resize events. int suppress_resize; // Used in WindowBorder and WindowState in order to avoid rapid, consecutive resize events.
bool is_in_modal_loop; // set to true whenever we enter the modal resize/move event loop
Rectangle Rectangle
bounds = new Rectangle(), bounds = new Rectangle(),
@ -262,14 +263,23 @@ namespace OpenTK.Platform.Windows
// Entering the modal size/move loop: we don't want rendering to // Entering the modal size/move loop: we don't want rendering to
// stop during this time, so we register a timer callback to continue // stop during this time, so we register a timer callback to continue
// processing from time to time. // processing from time to time.
is_in_modal_loop = true;
StartTimer(handle); StartTimer(handle);
if (!CursorVisible)
UngrabCursor();
break; break;
case WindowMessage.EXITMENULOOP: case WindowMessage.EXITMENULOOP:
case WindowMessage.EXITSIZEMOVE: case WindowMessage.EXITSIZEMOVE:
// ExitingmModal size/move loop: the timer callback is no longer // Exiting from Modal size/move loop: the timer callback is no longer
// necessary. // necessary.
is_in_modal_loop = false;
StopTimer(handle); StopTimer(handle);
// Ensure cursor remains grabbed
if (!CursorVisible)
GrabCursor();
break; break;
case WindowMessage.ERASEBKGND: case WindowMessage.ERASEBKGND:
@ -306,11 +316,16 @@ namespace OpenTK.Platform.Windows
Resize(this, EventArgs.Empty); Resize(this, EventArgs.Empty);
} }
// Ensure cursor remains grabbed if (!is_in_modal_loop)
{
// If we are in a modal resize/move loop, cursor grabbing is
// handled inside [ENTER|EXIT]SIZEMOVE case above.
// If not, then we have to handle cursor grabbing here.
if (!CursorVisible) if (!CursorVisible)
GrabCursor(); GrabCursor();
} }
} }
}
break; break;
case WindowMessage.STYLECHANGED: case WindowMessage.STYLECHANGED:
@ -351,11 +366,11 @@ namespace OpenTK.Platform.Windows
{ {
windowState = new_state; windowState = new_state;
WindowStateChanged(this, EventArgs.Empty); WindowStateChanged(this, EventArgs.Empty);
}
// Ensure cursor remains grabbed // Ensure cursor remains grabbed
if (!CursorVisible) if (!CursorVisible)
GrabCursor(); GrabCursor();
}
break; break;