SDL: Allow Cocoa_VideoInit to succeed when current display mode has invalid flags

From d9c44b65374d0bca490337f315765c57bb5e517d Mon Sep 17 00:00:00 2001
From: James Howard <[EMAIL REDACTED]>
Date: Tue, 19 Oct 2021 10:49:17 -0700
Subject: [PATCH] Allow Cocoa_VideoInit to succeed when current display mode
 has invalid flags

This fixes a specific issue seen on macOS 10.14.6 where a DELL E248WFP
Display connected to a 2014 Mac Mini with a scaled 1920x1080 resolution
selected and SDL_Init(SDL_INIT_VIDEO) failed with the error: "The video
driver did not add any displays".

The underlying cause was that the current 1080p display mode did not
have the flag kDisplayModeSafeFlag, the check for which was added in
a963e36, with the idea that certain display modes should not be
candidates for switching to in fullscreen exclusive mode. That may well
be the right thing to do for filtering down a list of candidate modes,
but it doesn't pay to be so picky about the current mode. After all,
this current mode was set by System Preferences, the picture does appear
correctly on screen, and other non-SDL based applications launch and run
correctly in this mode.

Therefore the fix is to have GetDisplayMode only filter out a mode based
on flags if it's part of a candidate list, but if it's the current mode
and it can possibly be converted to an SDL_DisplayMode, do so.
---
 src/video/cocoa/SDL_cocoamodes.m | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/video/cocoa/SDL_cocoamodes.m b/src/video/cocoa/SDL_cocoamodes.m
index e1fd4081c7..dce71690c7 100644
--- a/src/video/cocoa/SDL_cocoamodes.m
+++ b/src/video/cocoa/SDL_cocoamodes.m
@@ -162,7 +162,7 @@
 }
 
 static SDL_bool
-GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CFArrayRef modelist, CVDisplayLinkRef link, SDL_DisplayMode *mode)
+GetDisplayMode(_THIS, CGDisplayModeRef vidmode, SDL_bool vidmodeCurrent, CFArrayRef modelist, CVDisplayLinkRef link, SDL_DisplayMode *mode)
 {
     SDL_DisplayModeData *data;
     bool usableForGUI = CGDisplayModeIsUsableForDesktopGUI(vidmode);
@@ -178,7 +178,9 @@
         return SDL_FALSE;
     }
 
-    if (!HasValidDisplayModeFlags(vidmode)) {
+    /* Don't fail the current mode based on flags because this could prevent Cocoa_InitModes from
+     * succeeding if the current mode lacks certain flags (esp kDisplayModeSafeFlag). */
+    if (!vidmodeCurrent && !HasValidDisplayModeFlags(vidmode)) {
         return SDL_FALSE;
     }
 
@@ -375,7 +377,7 @@
             SDL_zero(display);
             /* this returns a stddup'ed string */
             display.name = (char *)Cocoa_GetDisplayName(displays[i]);
-            if (!GetDisplayMode(_this, moderef, NULL, link, &mode)) {
+            if (!GetDisplayMode(_this, moderef, SDL_TRUE, NULL, link, &mode)) {
                 CVDisplayLinkRelease(link);
                 CGDisplayModeRelease(moderef);
                 SDL_free(display.name);
@@ -499,7 +501,7 @@
      * sure there are no duplicates so it's safe to always add the desktop mode
      * even in cases where it is in the CopyAllDisplayModes list.
      */
-    if (desktopmoderef && GetDisplayMode(_this, desktopmoderef, NULL, link, &desktopmode)) {
+    if (desktopmoderef && GetDisplayMode(_this, desktopmoderef, SDL_TRUE, NULL, link, &desktopmode)) {
         if (!SDL_AddDisplayMode(display, &desktopmode)) {
             CFRelease(((SDL_DisplayModeData*)desktopmode.driverdata)->modes);
             SDL_free(desktopmode.driverdata);
@@ -546,7 +548,7 @@
             CGDisplayModeRef moderef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
             SDL_DisplayMode mode;
 
-            if (GetDisplayMode(_this, moderef, modes, link, &mode)) {
+            if (GetDisplayMode(_this, moderef, SDL_FALSE, modes, link, &mode)) {
                 if (!SDL_AddDisplayMode(display, &mode)) {
                     CFRelease(((SDL_DisplayModeData*)mode.driverdata)->modes);
                     SDL_free(mode.driverdata);