From 6e7a7c9350b6ada2b65d4f20740cb651eed882ab Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 17 Feb 2026 11:46:20 +0100 Subject: [PATCH] Fix `Screen.CursorLock` in Editor to skip when viewport is unfocused --- Source/Editor/Windows/GameWindow.cs | 2 +- Source/Engine/Engine/Screen.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Windows/GameWindow.cs b/Source/Editor/Windows/GameWindow.cs index 5f9ad71fd..e95fb61b2 100644 --- a/Source/Editor/Windows/GameWindow.cs +++ b/Source/Editor/Windows/GameWindow.cs @@ -874,7 +874,7 @@ namespace FlaxEditor.Windows _cursorVisible = Screen.CursorVisible; _cursorLockMode = Screen.CursorLock; Screen.CursorVisible = true; - if (Screen.CursorLock == CursorLockMode.Clipped || Screen.CursorLock == CursorLockMode.Locked) + if (_cursorLockMode != CursorLockMode.None) Screen.CursorLock = CursorLockMode.None; // Defocus diff --git a/Source/Engine/Engine/Screen.cpp b/Source/Engine/Engine/Screen.cpp index d2fb7db3d..39c6dc865 100644 --- a/Source/Engine/Engine/Screen.cpp +++ b/Source/Engine/Engine/Screen.cpp @@ -21,6 +21,9 @@ namespace Nullable Size; bool CursorVisible = true; CursorLockMode CursorLock = CursorLockMode::None; +#if USE_EDITOR + CursorLockMode PendingCursorLock = CursorLockMode::None; +#endif bool LastGameViewportFocus = false; } @@ -124,7 +127,17 @@ void Screen::SetCursorLock(CursorLockMode mode) const auto win = Editor::Managed->GetGameWindow(true); Rectangle bounds(Editor::Managed->GameViewportToScreen(Float2::Zero), Editor::Managed->GetGameWindowSize()); if (win) + { bounds = Rectangle(win->ScreenToClient(bounds.GetTopLeft()), bounds.Size); + + // Don't change lock mode in play mode when viewport doesn't have focus + if (mode != CursorLockMode::None && Editor::IsPlayMode && !Engine::HasGameViewportFocus()) + { + PendingCursorLock = mode; + return; + } + PendingCursorLock = CursorLockMode::None; + } #else const auto win = Engine::MainWindow; Rectangle bounds = win != nullptr ? win->GetClientBounds() : Rectangle(); @@ -211,6 +224,10 @@ void ScreenService::Update() if (gameViewportFocus != LastGameViewportFocus) Screen::SetCursorVisible(CursorVisible); LastGameViewportFocus = gameViewportFocus; + + // Sync pending cursor lock mode in Editor (eg. when viewport focus can change) + if (PendingCursorLock != CursorLockMode::None && Engine::HasGameViewportFocus()) + Screen::SetCursorLock(PendingCursorLock); #endif }