Further adjust implementation of Cocoa_GetWindowDisplayIndex

As discussed in PR review, there may be an off-chance that the index
returned doesn't match up with SDL's display indexing.

This change ensures that the indices match and adds a safety check for
off-screen windows.
This commit is contained in:
Dean Herbert 2022-07-24 20:19:16 +09:00 committed by Sam Lantinga
parent ce8aae1419
commit 6bcde52d88
2 changed files with 32 additions and 11 deletions

View file

@ -1071,11 +1071,20 @@ SDL_GetDisplay(int displayIndex)
int int
SDL_GetWindowDisplayIndex(SDL_Window * window) SDL_GetWindowDisplayIndex(SDL_Window * window)
{ {
int displayIndex = -1;
CHECK_WINDOW_MAGIC(window, -1); CHECK_WINDOW_MAGIC(window, -1);
if (_this->GetWindowDisplayIndex) { if (_this->GetWindowDisplayIndex) {
return _this->GetWindowDisplayIndex(_this, window); displayIndex = _this->GetWindowDisplayIndex(_this, window);
}
/* A backend implementation may fail to get a display index for the window
* (for example if the window is off-screen), but other code may expect it
* to succeed in that situation, so we fall back to a generic position-
* based implementation in that case. */
if (displayIndex >= 0) {
return displayIndex;
} else { } else {
int displayIndex;
int i, dist; int i, dist;
int closest = -1; int closest = -1;
int closest_dist = 0x7FFFFFFF; int closest_dist = 0x7FFFFFFF;

View file

@ -2230,25 +2230,37 @@ int
Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window) Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window)
{ @autoreleasepool { @autoreleasepool
{ {
NSScreen *screen;
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 */
if (data == NULL){ if (data == nil) {
return 0; return 0;
} }
NSArray *screens = [NSScreen screens]; /* NSWindow.screen may be nil when the window is off-screen. */
screen = data.nswindow.screen;
int index = 0; if (screen != nil) {
for (NSScreen *screen in screens) { CGDirectDisplayID displayid;
if (screen == data.nswindow.screen) int i;
return index;
index++; /* https://developer.apple.com/documentation/appkit/nsscreen/1388360-devicedescription?language=objc */
displayid = [[screen.deviceDescription objectForKey:@"NSScreenNumber"] unsignedIntValue];
for (i = 0; i < _this->num_displays; i++) {
SDL_DisplayData *displaydata = (SDL_DisplayData *)_this->displays[i].driverdata;
if (displaydata != NULL && displaydata->display == displayid) {
return i;
}
}
} }
SDL_SetError("Couldn't find the display where the window is attached."); /* Other code may expect SDL_GetWindowDisplayIndex to always return a valid
return -1; * index for a window. The higher level GetWindowDisplayIndex code will fall
* back to a generic position-based query if the backend implementation
* fails. */
return SDL_SetError("Couldn't find the display where the window is located.");
}} }}
int int