Fixed bug 3015 - grab mouse inconsistent state
authorSam Lantinga <slouken@libsdl.org>
Mon, 15 Jun 2015 23:44:08 -0700
changeset 9745 885b6b5c8426
parent 9744 59a012991992
child 9746 b39bdcf9cdc0
Fixed bug 3015 - grab mouse inconsistent state Martin Gerhardy Not sure - but I think there might be a logic flaw in SDL_SetWindowGrab. The problem here is that this modifies the window flags and e.g. sets SDL_WINDOW_INPUT_GRABBED - but the _this->grabbed_window pointer is not yet set. Then in SDL_UpdateWindowGrab the _this->grabbed_window pointer is only set if the function pointer _this->SetWindowGrab is not NULL. But if this is NULL, the _this->grabbed_window pointer is never set, but every future call to any of the grab functions include an assert for: SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags & SDL_WINDOW_INPUT_GRABBED) != 0)); That means the first call works, the second always fails and triggers the assert.
src/video/SDL_video.c
--- a/src/video/SDL_video.c	Mon Jun 15 20:24:51 2015 -0700
+++ b/src/video/SDL_video.c	Mon Jun 15 23:44:08 2015 -0700
@@ -2122,28 +2122,30 @@
 void
 SDL_UpdateWindowGrab(SDL_Window * window)
 {
-    if (_this->SetWindowGrab) {
-        SDL_Window *grabbed_window;
-        SDL_bool grabbed;
-        if ((SDL_GetMouse()->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) &&
-             (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
-            grabbed = SDL_TRUE;
-        } else {
-            grabbed = SDL_FALSE;
-        }
-
-        grabbed_window = _this->grabbed_window;
-        if (grabbed) {
-            if (grabbed_window && (grabbed_window != window)) {
-                /* stealing a grab from another window! */
-                grabbed_window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
+    SDL_Window *grabbed_window;
+    SDL_bool grabbed;
+    if ((SDL_GetMouse()->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) &&
+         (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
+        grabbed = SDL_TRUE;
+    } else {
+        grabbed = SDL_FALSE;
+    }
+
+    grabbed_window = _this->grabbed_window;
+    if (grabbed) {
+        if (grabbed_window && (grabbed_window != window)) {
+            /* stealing a grab from another window! */
+            grabbed_window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
+            if (_this->SetWindowGrab) {
                 _this->SetWindowGrab(_this, grabbed_window, SDL_FALSE);
             }
-            _this->grabbed_window = window;
-        } else if (grabbed_window == window) {
-            _this->grabbed_window = NULL;  /* ungrabbing. */
         }
-
+        _this->grabbed_window = window;
+    } else if (grabbed_window == window) {
+        _this->grabbed_window = NULL;  /* ungrabbing. */
+    }
+
+    if (_this->SetWindowGrab) {
         _this->SetWindowGrab(_this, window, grabbed);
     }
 }