From 7e59c3b9a7f7d43e6b5d5357fc55ac0093f1e843 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Mon, 31 Mar 2025 23:25:38 +0300 Subject: [PATCH] Fix restoring locked cursor state when window gains focus again --- Source/Editor/Windows/GameWindow.cs | 3 ++- Source/Engine/Input/Mouse.h | 3 ++- Source/Engine/Platform/Base/WindowBase.h | 1 + Source/Engine/Platform/SDL/SDLInput.cpp | 7 +++++++ Source/Engine/Platform/SDL/SDLWindow.cpp | 10 ++++++++++ 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Windows/GameWindow.cs b/Source/Editor/Windows/GameWindow.cs index 7a85486d6..935ca9686 100644 --- a/Source/Editor/Windows/GameWindow.cs +++ b/Source/Editor/Windows/GameWindow.cs @@ -1179,9 +1179,10 @@ namespace FlaxEditor.Windows _cursorVisible = Screen.CursorVisible; _cursorLockMode = Screen.CursorLock; - // Restore cursor visibility (could be hidden by the game) + // Restore cursor state, could be hidden or locked by the game if (!_cursorVisible) Screen.CursorVisible = true; + Screen.CursorLock = CursorLockMode.None; } } diff --git a/Source/Engine/Input/Mouse.h b/Source/Engine/Input/Mouse.h index bb10cb873..aecccd965 100644 --- a/Source/Engine/Input/Mouse.h +++ b/Source/Engine/Input/Mouse.h @@ -119,7 +119,8 @@ public: /// /// Gets the current state of mouse relative mode. /// - API_FUNCTION() FORCE_INLINE bool IsRelative() const + /// The window to check against, or null to check for any window. + virtual API_FUNCTION() bool IsRelative(Window* window = nullptr) const { return _relativeMode; } diff --git a/Source/Engine/Platform/Base/WindowBase.h b/Source/Engine/Platform/Base/WindowBase.h index c271754f4..d53292ef4 100644 --- a/Source/Engine/Platform/Base/WindowBase.h +++ b/Source/Engine/Platform/Base/WindowBase.h @@ -45,6 +45,7 @@ protected: bool _isHorizontalFlippingMouse = false; bool _isVerticalFlippingMouse = false; bool _isClippingCursor = false; + bool _restoreRelativeMode = false; explicit WindowBase(const CreateWindowSettings& settings); virtual ~WindowBase(); diff --git a/Source/Engine/Platform/SDL/SDLInput.cpp b/Source/Engine/Platform/SDL/SDLInput.cpp index ff3f362a1..40c3e3b9d 100644 --- a/Source/Engine/Platform/SDL/SDLInput.cpp +++ b/Source/Engine/Platform/SDL/SDLInput.cpp @@ -432,6 +432,13 @@ public: if (!SDL_SetWindowRelativeMouseMode(windowHandle, relativeMode)) LOG(Error, "Failed to set mouse relative mode: {0}", String(SDL_GetError())); } + + bool IsRelative(Window* window) const override + { + if (window == nullptr) + return _relativeMode; + return _relativeModeWindow == window && _relativeMode; + } }; /// diff --git a/Source/Engine/Platform/SDL/SDLWindow.cpp b/Source/Engine/Platform/SDL/SDLWindow.cpp index 8624e69ca..8c1fb8a3f 100644 --- a/Source/Engine/Platform/SDL/SDLWindow.cpp +++ b/Source/Engine/Platform/SDL/SDLWindow.cpp @@ -440,6 +440,9 @@ void SDLWindow::HandleEvent(SDL_Event& event) if (inRelativeMode) Input::Mouse->SetRelativeMode(true, this); } + else if (_restoreRelativeMode) + Input::Mouse->SetRelativeMode(true, this); + _restoreRelativeMode = false; return; } case SDL_EVENT_WINDOW_FOCUS_LOST: @@ -448,6 +451,13 @@ void SDLWindow::HandleEvent(SDL_Event& event) SDL_StopTextInput(_window); if (_isClippingCursor) SDL_SetWindowMouseRect(_window, nullptr); + + if (Input::Mouse->IsRelative(this)) + { + Input::Mouse->SetRelativeMode(false, this); + _restoreRelativeMode = true; + } + OnLostFocus(); return; }