Fix crash on leftover window handle inside an input device events queue

This commit is contained in:
2026-04-08 17:13:34 +02:00
parent 96301f20c6
commit 9e48cc4156
3 changed files with 12 additions and 23 deletions
+11 -12
View File
@@ -89,17 +89,6 @@ Delegate<StringView> Input::AxisValueChanged;
Array<ActionConfig> Input::ActionMappings; Array<ActionConfig> Input::ActionMappings;
Array<AxisConfig> Input::AxisMappings; Array<AxisConfig> Input::AxisMappings;
void ClearWindowInputs(Window* window)
{
WindowsManager::WindowsLocker.Lock();
for (int32 i = InputEvents.Count() - 1; i >= 0; i--)
{
if (InputEvents[i].Target == window)
InputEvents.RemoveAtKeepOrder(i);
}
WindowsManager::WindowsLocker.Unlock();
}
void InputSettings::Apply() void InputSettings::Apply()
{ {
PROFILE_MEM(Input); PROFILE_MEM(Input);
@@ -934,9 +923,10 @@ void InputService::Update()
Input::GamepadsChanged(); Input::GamepadsChanged();
} }
WindowsManager::WindowsLocker.Lock();
// Pick the first focused window for input events // Pick the first focused window for input events
Window* defaultWindow = nullptr; Window* defaultWindow = nullptr;
WindowsManager::WindowsLocker.Lock();
for (auto window : WindowsManager::Windows) for (auto window : WindowsManager::Windows)
{ {
if (window->IsFocused() && window->GetSettings().AllowInput) if (window->IsFocused() && window->GetSettings().AllowInput)
@@ -945,6 +935,15 @@ void InputService::Update()
break; break;
} }
} }
// Remove events from destroyed windows
for (int32 i = InputEvents.Count() - 1; i >= 0; i--)
{
const auto& e = InputEvents[i];
if (e.Target && !WindowsManager::Windows.Contains(e.Target))
InputEvents.RemoveAtKeepOrder(i);
}
WindowsManager::WindowsLocker.Unlock(); WindowsManager::WindowsLocker.Unlock();
// Send input events for the focused window // Send input events for the focused window
@@ -17,8 +17,6 @@
#include "Engine/Scripting/ManagedCLR/MMethod.h" #include "Engine/Scripting/ManagedCLR/MMethod.h"
#include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MClass.h"
extern void ClearWindowInputs(Window* window);
#if USE_CSHARP #if USE_CSHARP
// Helper macros for calling C# events // Helper macros for calling C# events
#define BEGIN_INVOKE_EVENT(name, paramsCount) \ #define BEGIN_INVOKE_EVENT(name, paramsCount) \
@@ -124,7 +122,6 @@ WindowBase::WindowBase(const CreateWindowSettings& settings)
WindowBase::~WindowBase() WindowBase::~WindowBase()
{ {
ClearWindowInputs((Window*)this);
ASSERT(!RenderTask); ASSERT(!RenderTask);
ASSERT(!_swapChain); ASSERT(!_swapChain);
WindowsManager::Unregister((Window*)this); WindowsManager::Unregister((Window*)this);
@@ -186,7 +183,6 @@ String WindowBase::ToString() const
void WindowBase::OnDeleteObject() void WindowBase::OnDeleteObject()
{ {
// Dereference window // Dereference window
ClearWindowInputs((Window*)this);
#if !USE_EDITOR #if !USE_EDITOR
if (RenderTask && RenderTask == MainRenderTask::Instance) if (RenderTask && RenderTask == MainRenderTask::Instance)
{ {
@@ -181,13 +181,7 @@ WindowsWindow::~WindowsWindow()
{ {
if (HasHWND()) if (HasHWND())
{ {
// Destroy window DestroyWindow(_handle);
if (DestroyWindow(_handle) == 0)
{
LOG(Warning, "DestroyWindow failed! Error: {0:#x}", GetLastError());
}
// Clear
_handle = nullptr; _handle = nullptr;
_visible = false; _visible = false;
} }