Fix potential crashes on macOS due to missing window inside view event

This commit is contained in:
Wojtek Figat
2023-10-21 13:04:33 +02:00
parent ba39938ed5
commit 08a6a2b6dc

View File

@@ -4,6 +4,7 @@
#include "../Window.h" #include "../Window.h"
#include "Engine/Platform/Apple/AppleUtils.h" #include "Engine/Platform/Apple/AppleUtils.h"
#include "Engine/Platform/WindowsManager.h"
#include "Engine/Platform/IGuiData.h" #include "Engine/Platform/IGuiData.h"
#include "Engine/Core/Log.h" #include "Engine/Core/Log.h"
#include "Engine/Input/Input.h" #include "Engine/Input/Input.h"
@@ -14,6 +15,14 @@
#include <AppKit/AppKit.h> #include <AppKit/AppKit.h>
#include <QuartzCore/CAMetalLayer.h> #include <QuartzCore/CAMetalLayer.h>
inline bool IsWindowInvalid(Window* win)
{
WindowsManager::WindowsLocker.Lock();
const bool hasWindow = WindowsManager::Windows.Contains(win);
WindowsManager::WindowsLocker.Unlock();
return !hasWindow || !win;
}
KeyboardKeys GetKey(NSEvent* event) KeyboardKeys GetKey(NSEvent* event)
{ {
switch ([event keyCode]) switch ([event keyCode])
@@ -268,17 +277,20 @@ NSDragOperation GetDragDropOperation(DragDropEffect dragDropEffect)
// Handle resizing to be sure that content has valid size when window was resized // Handle resizing to be sure that content has valid size when window was resized
[self windowDidResize:notification]; [self windowDidResize:notification];
if (IsWindowInvalid(Window)) return;
Window->OnGotFocus(); Window->OnGotFocus();
} }
- (void)windowDidResignKey:(NSNotification*)notification - (void)windowDidResignKey:(NSNotification*)notification
{ {
if (IsWindowInvalid(Window)) return;
Window->OnLostFocus(); Window->OnLostFocus();
} }
- (void)windowWillClose:(NSNotification*)notification - (void)windowWillClose:(NSNotification*)notification
{ {
[self setDelegate: nil]; [self setDelegate: nil];
if (IsWindowInvalid(Window)) return;
Window->Close(ClosingReason::User); Window->Close(ClosingReason::User);
} }
@@ -375,6 +387,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (void)keyDown:(NSEvent*)event - (void)keyDown:(NSEvent*)event
{ {
if (IsWindowInvalid(Window)) return;
KeyboardKeys key = GetKey(event); KeyboardKeys key = GetKey(event);
if (key != KeyboardKeys::None) if (key != KeyboardKeys::None)
Input::Keyboard->OnKeyDown(key, Window); Input::Keyboard->OnKeyDown(key, Window);
@@ -405,6 +418,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (void)keyUp:(NSEvent*)event - (void)keyUp:(NSEvent*)event
{ {
if (IsWindowInvalid(Window)) return;
KeyboardKeys key = GetKey(event); KeyboardKeys key = GetKey(event);
if (key != KeyboardKeys::None) if (key != KeyboardKeys::None)
Input::Keyboard->OnKeyUp(key, Window); Input::Keyboard->OnKeyUp(key, Window);
@@ -412,6 +426,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (void)flagsChanged:(NSEvent*)event - (void)flagsChanged:(NSEvent*)event
{ {
if (IsWindowInvalid(Window)) return;
int32 modMask; int32 modMask;
int32 keyCode = [event keyCode]; int32 keyCode = [event keyCode];
if (keyCode == 0x36 || keyCode == 0x37) if (keyCode == 0x36 || keyCode == 0x37)
@@ -437,6 +452,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (void)scrollWheel:(NSEvent*)event - (void)scrollWheel:(NSEvent*)event
{ {
if (IsWindowInvalid(Window)) return;
Float2 mousePos = GetMousePosition(Window, event); Float2 mousePos = GetMousePosition(Window, event);
double deltaX = [event scrollingDeltaX]; double deltaX = [event scrollingDeltaX];
double deltaY = [event scrollingDeltaY]; double deltaY = [event scrollingDeltaY];
@@ -451,6 +467,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (void)mouseMoved:(NSEvent*)event - (void)mouseMoved:(NSEvent*)event
{ {
if (IsWindowInvalid(Window)) return;
Float2 mousePos = GetMousePosition(Window, event); Float2 mousePos = GetMousePosition(Window, event);
if (!Window->IsMouseTracking() && !IsMouseOver) if (!Window->IsMouseTracking() && !IsMouseOver)
return; return;
@@ -459,18 +476,21 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (void)mouseEntered:(NSEvent*)event - (void)mouseEntered:(NSEvent*)event
{ {
if (IsWindowInvalid(Window)) return;
IsMouseOver = true; IsMouseOver = true;
Window->SetIsMouseOver(true); Window->SetIsMouseOver(true);
} }
- (void)mouseExited:(NSEvent*)event - (void)mouseExited:(NSEvent*)event
{ {
if (IsWindowInvalid(Window)) return;
IsMouseOver = false; IsMouseOver = false;
Window->SetIsMouseOver(false); Window->SetIsMouseOver(false);
} }
- (void)mouseDown:(NSEvent*)event - (void)mouseDown:(NSEvent*)event
{ {
if (IsWindowInvalid(Window)) return;
Float2 mousePos = GetMousePosition(Window, event); Float2 mousePos = GetMousePosition(Window, event);
MouseButton mouseButton = MouseButton::Left; MouseButton mouseButton = MouseButton::Left;
if ([event clickCount] == 2) if ([event clickCount] == 2)
@@ -486,6 +506,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (void)mouseUp:(NSEvent*)event - (void)mouseUp:(NSEvent*)event
{ {
if (IsWindowInvalid(Window)) return;
Float2 mousePos = GetMousePosition(Window, event); Float2 mousePos = GetMousePosition(Window, event);
MouseButton mouseButton = MouseButton::Left; MouseButton mouseButton = MouseButton::Left;
Input::Mouse->OnMouseUp(Window->ClientToScreen(mousePos), mouseButton, Window); Input::Mouse->OnMouseUp(Window->ClientToScreen(mousePos), mouseButton, Window);
@@ -493,6 +514,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (void)rightMouseDown:(NSEvent*)event - (void)rightMouseDown:(NSEvent*)event
{ {
if (IsWindowInvalid(Window)) return;
Float2 mousePos = GetMousePosition(Window, event); Float2 mousePos = GetMousePosition(Window, event);
MouseButton mouseButton = MouseButton::Right; MouseButton mouseButton = MouseButton::Right;
if ([event clickCount] == 2) if ([event clickCount] == 2)
@@ -508,6 +530,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (void)rightMouseUp:(NSEvent*)event - (void)rightMouseUp:(NSEvent*)event
{ {
if (IsWindowInvalid(Window)) return;
Float2 mousePos = GetMousePosition(Window, event); Float2 mousePos = GetMousePosition(Window, event);
MouseButton mouseButton = MouseButton::Right; MouseButton mouseButton = MouseButton::Right;
Input::Mouse->OnMouseUp(Window->ClientToScreen(mousePos), mouseButton, Window); Input::Mouse->OnMouseUp(Window->ClientToScreen(mousePos), mouseButton, Window);
@@ -515,6 +538,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (void)otherMouseDown:(NSEvent*)event - (void)otherMouseDown:(NSEvent*)event
{ {
if (IsWindowInvalid(Window)) return;
Float2 mousePos = GetMousePosition(Window, event); Float2 mousePos = GetMousePosition(Window, event);
MouseButton mouseButton; MouseButton mouseButton;
switch ([event buttonNumber]) switch ([event buttonNumber])
@@ -544,6 +568,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (void)otherMouseUp:(NSEvent*)event - (void)otherMouseUp:(NSEvent*)event
{ {
if (IsWindowInvalid(Window)) return;
Float2 mousePos = GetMousePosition(Window, event); Float2 mousePos = GetMousePosition(Window, event);
MouseButton mouseButton; MouseButton mouseButton;
switch ([event buttonNumber]) switch ([event buttonNumber])
@@ -565,6 +590,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
{ {
if (IsWindowInvalid(Window)) return NSDragOperationNone;
Float2 mousePos; Float2 mousePos;
MacDropData dropData; MacDropData dropData;
GetDragDropData(Window, sender, mousePos, dropData); GetDragDropData(Window, sender, mousePos, dropData);
@@ -580,6 +606,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
{ {
if (IsWindowInvalid(Window)) return NSDragOperationNone;
Float2 mousePos; Float2 mousePos;
MacDropData dropData; MacDropData dropData;
GetDragDropData(Window, sender, mousePos, dropData); GetDragDropData(Window, sender, mousePos, dropData);
@@ -590,6 +617,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender - (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
{ {
if (IsWindowInvalid(Window)) return NO;
Float2 mousePos; Float2 mousePos;
MacDropData dropData; MacDropData dropData;
GetDragDropData(Window, sender, mousePos, dropData); GetDragDropData(Window, sender, mousePos, dropData);
@@ -600,6 +628,7 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
- (void)draggingExited:(id<NSDraggingInfo>)sender - (void)draggingExited:(id<NSDraggingInfo>)sender
{ {
if (IsWindowInvalid(Window)) return;
Window->OnDragLeave(); Window->OnDragLeave();
} }