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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 1e520b2..144326f 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -1071,11 +1071,20 @@ SDL_GetDisplay(int displayIndex)
int
SDL_GetWindowDisplayIndex(SDL_Window * window)
{
+ int displayIndex = -1;
+
CHECK_WINDOW_MAGIC(window, -1);
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 {
- int displayIndex;
int i, dist;
int closest = -1;
int closest_dist = 0x7FFFFFFF;
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index 3f5c046..157353c 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -2230,25 +2230,37 @@ int
Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window)
{ @autoreleasepool
{
+ NSScreen *screen;
SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
/* Not recognized via CHECK_WINDOW_MAGIC */
- if (data == NULL){
+ if (data == nil) {
return 0;
}
- NSArray *screens = [NSScreen screens];
+ /* NSWindow.screen may be nil when the window is off-screen. */
+ screen = data.nswindow.screen;
+
+ if (screen != nil) {
+ CGDirectDisplayID displayid;
+ int i;
- int index = 0;
- for (NSScreen *screen in screens) {
- if (screen == data.nswindow.screen)
- return index;
+ /* https://developer.apple.com/documentation/appkit/nsscreen/1388360-devicedescription?language=objc */
+ displayid = [[screen.deviceDescription objectForKey:@"NSScreenNumber"] unsignedIntValue];
- index++;
+ 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.");
- return -1;
+ /* Other code may expect SDL_GetWindowDisplayIndex to always return a valid
+ * 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