| 397 | } |
| 398 | |
| 399 | void SetRelativeMode(bool relativeMode, Window* window) final override |
| 400 | { |
| 401 | ASSERT(window != nullptr); |
| 402 | if (relativeMode == _relativeMode) |
| 403 | return; |
| 404 | |
| 405 | auto windowHandle = static_cast<SDLWindow*>(window)->_window; |
| 406 | if (relativeMode) |
| 407 | { |
| 408 | _relativeModeWindow = window; |
| 409 | SDL_GetMouseState(&_oldPosition.X, &_oldPosition.Y); |
| 410 | #if !PLATFORM_MAC |
| 411 | if (!SDL_CursorVisible()) |
| 412 | { |
| 413 | // Trap the cursor in current location to prevent accidental interactions with other UI elements or applications |
| 414 | SDL_Rect clipRect = { (int)_oldPosition.X, (int)_oldPosition.Y, 1, 1 }; |
| 415 | SDL_SetWindowMouseRect(windowHandle, &clipRect); |
| 416 | } |
| 417 | #endif |
| 418 | } |
| 419 | else |
| 420 | { |
| 421 | if (_relativeModeWindow != window) |
| 422 | { |
| 423 | // FIXME: When floating game window is focused and editor viewport activated, the relative mode gets stuck |
| 424 | return; |
| 425 | } |
| 426 | #if !PLATFORM_MAC |
| 427 | SDL_SetWindowMouseRect(windowHandle, nullptr); |
| 428 | #endif |
| 429 | SDL_WarpMouseInWindow(windowHandle, _oldPosition.X, _oldPosition.Y); |
| 430 | _relativeModeWindow = nullptr; |
| 431 | } |
| 432 | |
| 433 | Mouse::SetRelativeMode(relativeMode, window); |
| 434 | if (!SDL_SetWindowRelativeMouseMode(windowHandle, relativeMode)) |
| 435 | LOG(Error, "Failed to set mouse relative mode: {0}", String(SDL_GetError())); |
| 436 | |
| 437 | #if false && PLATFORM_MAC |
| 438 | // Warping right before entering relative mode seems to generate motion event during relative mode |
| 439 | SDL_PumpEvents(); |
| 440 | SDL_FlushEvent(SDL_EVENT_MOUSE_MOTION); |
| 441 | #endif |
| 442 | } |
| 443 | |
| 444 | bool IsRelative(Window* window) const override |
| 445 | { |
no test coverage detected