Skip to content
This repository
Browse code

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...
commit e2404d2cfc3ceb1444d07a9929a42552df418e01 1 parent 24aa789
authored November 22, 2013
31  Source/OpenTK/Platform/Windows/WinGLNative.cs
@@ -73,6 +73,7 @@ internal sealed class WinGLNative : INativeWindow, IInputDriver
73 73
         bool mouse_outside_window = true;
74 74
         bool invisible_since_creation; // Set by WindowsMessage.CREATE and consumed by Visible = true (calls BringWindowToFront).
75 75
         int suppress_resize; // Used in WindowBorder and WindowState in order to avoid rapid, consecutive resize events.
  76
+        bool is_in_modal_loop; // set to true whenever we enter the modal resize/move event loop 
76 77
 
77 78
         Rectangle
78 79
             bounds = new Rectangle(),
@@ -262,14 +263,23 @@ IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntP
262 263
                     // Entering the modal size/move loop: we don't want rendering to
263 264
                     // stop during this time, so we register a timer callback to continue
264 265
                     // processing from time to time.
  266
+                    is_in_modal_loop = true;
265 267
                     StartTimer(handle);
  268
+
  269
+                    if (!CursorVisible)
  270
+                        UngrabCursor();
266 271
                     break;
267 272
 
268 273
                 case WindowMessage.EXITMENULOOP:
269 274
                 case WindowMessage.EXITSIZEMOVE:
270  
-                    // ExitingmModal size/move loop: the timer callback is no longer
  275
+                    // Exiting from Modal size/move loop: the timer callback is no longer
271 276
                     // necessary.
  277
+                    is_in_modal_loop = false;
272 278
                     StopTimer(handle);
  279
+
  280
+                    // Ensure cursor remains grabbed
  281
+                    if (!CursorVisible)
  282
+                        GrabCursor();
273 283
                     break;
274 284
 
275 285
                 case WindowMessage.ERASEBKGND:
@@ -306,9 +316,14 @@ IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntP
306 316
                                     Resize(this, EventArgs.Empty);
307 317
                             }
308 318
 
309  
-                            // Ensure cursor remains grabbed
310  
-                            if (!CursorVisible)
311  
-                                GrabCursor();
  319
+                            if (!is_in_modal_loop)
  320
+                            {
  321
+                                // If we are in a modal resize/move loop, cursor grabbing is
  322
+                                // handled inside [ENTER|EXIT]SIZEMOVE case above.
  323
+                                // If not, then we have to handle cursor grabbing here.
  324
+                                if (!CursorVisible)
  325
+                                    GrabCursor();
  326
+                            }
312 327
                         }
313 328
                     }
314 329
                     break;
@@ -351,11 +366,11 @@ IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntP
351 366
                     {
352 367
                         windowState = new_state;
353 368
                         WindowStateChanged(this, EventArgs.Empty);
354  
-                    }
355 369
 
356  
-                    // Ensure cursor remains grabbed
357  
-                    if (!CursorVisible)
358  
-                        GrabCursor();
  370
+                        // Ensure cursor remains grabbed
  371
+                        if (!CursorVisible)
  372
+                            GrabCursor();
  373
+                    }
359 374
 
360 375
                     break;
361 376
 

0 notes on commit e2404d2

Please sign in to comment.
Something went wrong with that request. Please try again.