mirror of
https://github.com/Ryujinx/SDL.git
synced 2025-11-05 14:34:58 +00:00
Fix Cocoa_GetWindowDisplayIndex failing and causing a catastrophic crash
With the introduction of this function, it is possible that for certain
monitor and window configurations, creating an SDL window will cause a
native crash.
```
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000050
Exception Codes: 0x0000000000000001, 0x0000000000000050
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: Namespace SIGNAL, Code 11 Segmentation fault: 11
Terminating Process: exc handler [56627]
VM Region Info: 0x50 is not in any region. Bytes before following region: 140737486737328
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
UNUSED SPACE AT START
--->
VM_ALLOCATE 7fffffe75000-7fffffe76000 [ 4K] r-x/r-x SM=ALI
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libSDL2.dylib 0x10247f665 SDL_UpdateFullscreenMode + 357
1 libSDL2.dylib 0x10247ec70 SDL_CreateWindow_REAL + 1504
2 ??? 0x111262de8 ???
3 ??? 0x110c39fff ???
4 libcoreclr.dylib 0x101fdf2a9 CallDescrWorkerInternal + 124
```
Tracking thread from our end: https://github.com/ppy/osu-framework/issues/5190
Regressed with: https://github.com/libsdl-org/SDL/pull/5573
In testing, the window would not find a valid screen if created
"hanging" off a primary display with a secondary display below it. In
checking why this was the case, the `display_centre` was being
calculated with a negative y origin, causing a final negative value
falling outside all display bounds:
```
SDL error log [debug]: display_centre.y = -1296 + 1296 / 2
SDL error log [debug]: Display rect 0: 0 0 2560 1440
SDL error log [debug]: Display rect 1: 2560 -625 1080 2560
SDL error log [debug]: Display rect 2: 0 1440 1728 1296
```
The method that was being used to find the current window using the frame
origin/size seems unreliable, so I have opted to replace it with with a
tried method (https://stackoverflow.com/a/40891902).
Initial testing shows that this works with non-standard DPI screens, but
further testing would be appreciated (cc @sezero / @misl6 from the
original PR thread).
This commit is contained in:
parent
041666e6c3
commit
ce8aae1419
|
|
@ -2230,9 +2230,6 @@ int
|
||||||
Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window)
|
Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window)
|
||||||
{ @autoreleasepool
|
{ @autoreleasepool
|
||||||
{
|
{
|
||||||
NSRect displayframe;
|
|
||||||
SDL_Point display_center;
|
|
||||||
SDL_Rect sdl_display_rect;
|
|
||||||
SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
|
SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
|
||||||
|
|
||||||
/* Not recognized via CHECK_WINDOW_MAGIC */
|
/* Not recognized via CHECK_WINDOW_MAGIC */
|
||||||
|
|
@ -2240,23 +2237,17 @@ Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
NSArray *screens = [NSScreen screens];
|
||||||
Considering that we already have the display coordinates in which the window is placed (described via displayframe)
|
|
||||||
instead of checking in which display the window is placed, we should check which SDL display matches the display described
|
|
||||||
via displayframe.
|
|
||||||
*/
|
|
||||||
displayframe = data.nswindow.screen.frame;
|
|
||||||
|
|
||||||
display_center.x = displayframe.origin.x + displayframe.size.width / 2;
|
int index = 0;
|
||||||
display_center.y = displayframe.origin.y + displayframe.size.height / 2;
|
for (NSScreen *screen in screens) {
|
||||||
|
if (screen == data.nswindow.screen)
|
||||||
|
return index;
|
||||||
|
|
||||||
for (int i = 0; i < SDL_GetNumVideoDisplays(); i++){
|
index++;
|
||||||
SDL_GetDisplayBounds(i, &sdl_display_rect);
|
|
||||||
if (SDL_EnclosePoints(&display_center, 1, &sdl_display_rect, NULL)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SDL_SetError("Couldn't find the display where the window is attached to.");
|
|
||||||
|
SDL_SetError("Couldn't find the display where the window is attached.");
|
||||||
return -1;
|
return -1;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue