From 59d34bc35dbe9d23e78f137c08e47fecddcc93a4 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 15 Jun 2015 23:44:08 -0700 Subject: [PATCH] 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 | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 2e168ded5de77..22e08cc93c84a 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -2122,28 +2122,30 @@ SDL_GetWindowGammaRamp(SDL_Window * window, Uint16 * red, 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; - } + 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; + 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); } }