From 76afb8583b39305cf73191664c0015a8ee2400d4 Mon Sep 17 00:00:00 2001 From: Mirko Galimberti Date: Mon, 25 Apr 2022 10:35:56 +0200 Subject: [PATCH] Introduces Cocoa_GetWindowDisplayIndex. This enable a proper management for dpi when switching between retina and non-retina displays. --- src/video/SDL_sysvideo.h | 1 + src/video/SDL_video.c | 99 ++++++++++++++++--------------- src/video/cocoa/SDL_cocoavideo.m | 1 + src/video/cocoa/SDL_cocoawindow.h | 1 + src/video/cocoa/SDL_cocoawindow.m | 30 ++++++++++ 5 files changed, 84 insertions(+), 48 deletions(-) diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 2384a64ac..b68b92c37 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -237,6 +237,7 @@ struct SDL_VideoDevice int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp); int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp); void* (*GetWindowICCProfile) (_THIS, SDL_Window * window, size_t* size); + int (*GetWindowDisplayIndex)(_THIS, SDL_Window * window); void (*SetWindowMouseRect)(_THIS, SDL_Window * window); void (*SetWindowMouseGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); void (*SetWindowKeyboardGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 93c803e70..2b896c44b 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1060,61 +1060,64 @@ SDL_GetDisplay(int displayIndex) int SDL_GetWindowDisplayIndex(SDL_Window * window) { - int displayIndex; - int i, dist; - int closest = -1; - int closest_dist = 0x7FFFFFFF; - SDL_Point center; - SDL_Point delta; - SDL_Rect rect; - CHECK_WINDOW_MAGIC(window, -1); + if (_this->GetWindowDisplayIndex) { + return _this->GetWindowDisplayIndex(_this, window); + } else { + int displayIndex; + int i, dist; + int closest = -1; + int closest_dist = 0x7FFFFFFF; + SDL_Point center; + SDL_Point delta; + SDL_Rect rect; - if (SDL_WINDOWPOS_ISUNDEFINED(window->x) || - SDL_WINDOWPOS_ISCENTERED(window->x)) { - displayIndex = (window->x & 0xFFFF); - if (displayIndex >= _this->num_displays) { - displayIndex = 0; + if (SDL_WINDOWPOS_ISUNDEFINED(window->x) || + SDL_WINDOWPOS_ISCENTERED(window->x)) { + displayIndex = (window->x & 0xFFFF); + if (displayIndex >= _this->num_displays) { + displayIndex = 0; + } + return displayIndex; } - return displayIndex; - } - if (SDL_WINDOWPOS_ISUNDEFINED(window->y) || - SDL_WINDOWPOS_ISCENTERED(window->y)) { - displayIndex = (window->y & 0xFFFF); - if (displayIndex >= _this->num_displays) { - displayIndex = 0; - } - return displayIndex; - } - - /* Find the display containing the window */ - for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *display = &_this->displays[i]; - - if (display->fullscreen_window == window) { - return i; - } - } - center.x = window->x + window->w / 2; - center.y = window->y + window->h / 2; - for (i = 0; i < _this->num_displays; ++i) { - SDL_GetDisplayBounds(i, &rect); - if (SDL_EnclosePoints(¢er, 1, &rect, NULL)) { - return i; + if (SDL_WINDOWPOS_ISUNDEFINED(window->y) || + SDL_WINDOWPOS_ISCENTERED(window->y)) { + displayIndex = (window->y & 0xFFFF); + if (displayIndex >= _this->num_displays) { + displayIndex = 0; + } + return displayIndex; } - delta.x = center.x - (rect.x + rect.w / 2); - delta.y = center.y - (rect.y + rect.h / 2); - dist = (delta.x*delta.x + delta.y*delta.y); - if (dist < closest_dist) { - closest = i; - closest_dist = dist; + /* Find the display containing the window */ + for (i = 0; i < _this->num_displays; ++i) { + SDL_VideoDisplay *display = &_this->displays[i]; + + if (display->fullscreen_window == window) { + return i; + } } + center.x = window->x + window->w / 2; + center.y = window->y + window->h / 2; + for (i = 0; i < _this->num_displays; ++i) { + SDL_GetDisplayBounds(i, &rect); + if (SDL_EnclosePoints(¢er, 1, &rect, NULL)) { + return i; + } + + delta.x = center.x - (rect.x + rect.w / 2); + delta.y = center.y - (rect.y + rect.h / 2); + dist = (delta.x*delta.x + delta.y*delta.y); + if (dist < closest_dist) { + closest = i; + closest_dist = dist; + } + } + if (closest < 0) { + SDL_SetError("Couldn't find any displays"); + } + return closest; } - if (closest < 0) { - SDL_SetError("Couldn't find any displays"); - } - return closest; } SDL_VideoDisplay * diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index 231b2de5c..74d853829 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -103,6 +103,7 @@ Cocoa_CreateDevice(int devindex) device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp; device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp; device->GetWindowICCProfile = Cocoa_GetWindowICCProfile; + device->GetWindowDisplayIndex = Cocoa_GetWindowDisplayIndex; device->SetWindowMouseRect = Cocoa_SetWindowMouseRect; device->SetWindowMouseGrab = Cocoa_SetWindowMouseGrab; device->SetWindowKeyboardGrab = Cocoa_SetWindowKeyboardGrab; diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h index a42d9c87b..f8363f327 100644 --- a/src/video/cocoa/SDL_cocoawindow.h +++ b/src/video/cocoa/SDL_cocoawindow.h @@ -153,6 +153,7 @@ extern void Cocoa_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_t extern void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern void* Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size); +extern int Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window); extern int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); extern void Cocoa_SetWindowMouseRect(_THIS, SDL_Window * window); extern void Cocoa_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index bca8eb4dd..ea520e4b8 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -2197,6 +2197,36 @@ Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size) return retIccProfileData; } +int Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window){ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + + /* Not recognized via CHECK_WINDOW_MAGIC */ + if (data == NULL){ + return 0; + } + + /* + 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. + */ + CGRect displayframe = data->nswindow.screen.frame; + SDL_Point display_center; + SDL_Rect sdl_display_rect; + + display_center.x = displayframe.origin.x + displayframe.size.width / 2; + display_center.y = displayframe.origin.y + displayframe.size.height / 2; + + for (int i = 0; i < SDL_GetNumVideoDisplays(); i++){ + 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."); + return -1; +} + int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) {