Permalink
Browse files

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.
  • Loading branch information...
1 parent 24aa789 commit e2404d2cfc3ceb1444d07a9929a42552df418e01 @thefiddler thefiddler committed Nov 22, 2013
Showing with 23 additions and 8 deletions.
  1. +23 −8 Source/OpenTK/Platform/Windows/WinGLNative.cs
@@ -73,6 +73,7 @@ internal sealed class WinGLNative : INativeWindow, IInputDriver
bool mouse_outside_window = true;
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.
+ bool is_in_modal_loop; // set to true whenever we enter the modal resize/move event loop
Rectangle
bounds = new Rectangle(),
@@ -262,14 +263,23 @@ IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntP
// Entering the modal size/move loop: we don't want rendering to
// stop during this time, so we register a timer callback to continue
// processing from time to time.
+ is_in_modal_loop = true;
StartTimer(handle);
+
+ if (!CursorVisible)
+ UngrabCursor();
break;
case WindowMessage.EXITMENULOOP:
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.
+ is_in_modal_loop = false;
StopTimer(handle);
+
+ // Ensure cursor remains grabbed
+ if (!CursorVisible)
+ GrabCursor();
break;
case WindowMessage.ERASEBKGND:
@@ -306,9 +316,14 @@ IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntP
Resize(this, EventArgs.Empty);
}
- // Ensure cursor remains grabbed
- if (!CursorVisible)
- GrabCursor();
+ 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)
+ GrabCursor();
+ }
}
}
break;
@@ -351,11 +366,11 @@ IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntP
{
windowState = new_state;
WindowStateChanged(this, EventArgs.Empty);
- }
- // Ensure cursor remains grabbed
- if (!CursorVisible)
- GrabCursor();
+ // Ensure cursor remains grabbed
+ if (!CursorVisible)
+ GrabCursor();
+ }
break;

0 comments on commit e2404d2

Please sign in to comment.