From da648b00e76ac514ddde237ac7bd052481b0a9e0 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Fri, 11 Jul 2025 15:03:01 -0400
Subject: [PATCH] cocoa: Don't minimize fullscreen windows for a modal file
dialog.
macOS sends a focus loss event when the dialog is created, which causes SDL
to try to minimize the window, which confuses the entire system. So in this
special case, don't do the minimization.
Fixes #13168.
(cherry picked from commit 9af93abd4f94ed52c6dd2859805aa832fafc4a3b)
---
src/dialog/cocoa/SDL_cocoadialog.m | 7 +++++++
src/video/SDL_video.c | 7 +++++--
src/video/cocoa/SDL_cocoawindow.h | 1 +
src/video/cocoa/SDL_cocoawindow.m | 12 ++++++++++++
4 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/src/dialog/cocoa/SDL_cocoadialog.m b/src/dialog/cocoa/SDL_cocoadialog.m
index 64b2fdf978fb5..bc806f52a8953 100644
--- a/src/dialog/cocoa/SDL_cocoadialog.m
+++ b/src/dialog/cocoa/SDL_cocoadialog.m
@@ -27,6 +27,8 @@
#import <Cocoa/Cocoa.h>
#import <UniformTypeIdentifiers/UTType.h>
+extern void Cocoa_SetWindowHasModalDialog(SDL_Window *window, bool has_modal);
+
static void AddFileExtensionType(NSMutableArray *types, const char *pattern_ptr)
{
if (!*pattern_ptr) {
@@ -163,6 +165,9 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
if (window) {
w = (__bridge NSWindow *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL);
+ if (w) {
+ Cocoa_SetWindowHasModalDialog(window, true);
+ }
}
if (w) {
@@ -186,6 +191,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
callback(userdata, files, -1);
}
+ Cocoa_SetWindowHasModalDialog(window, false);
ReactivateAfterDialog();
}];
} else {
@@ -206,6 +212,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
const char *files[1] = { NULL };
callback(userdata, files, -1);
}
+
ReactivateAfterDialog();
}
}
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 35c578ddfe802..fdfe239c8c0cb 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -171,9 +171,10 @@ static VideoBootStrap *bootstrap[] = {
}
#if defined(SDL_PLATFORM_MACOS) && defined(SDL_VIDEO_DRIVER_COCOA)
-// Support for macOS fullscreen spaces
+// Support for macOS fullscreen spaces, etc.
extern bool Cocoa_IsWindowInFullscreenSpace(SDL_Window *window);
extern bool Cocoa_SetWindowFullscreenSpace(SDL_Window *window, bool state, bool blocking);
+extern bool Cocoa_IsShowingModalDialog(SDL_Window *window);
#endif
#ifdef SDL_VIDEO_DRIVER_UIKIT
@@ -4171,7 +4172,9 @@ static bool SDL_ShouldMinimizeOnFocusLoss(SDL_Window *window)
#if defined(SDL_PLATFORM_MACOS) && defined(SDL_VIDEO_DRIVER_COCOA)
if (SDL_strcmp(_this->name, "cocoa") == 0) { // don't do this for X11, etc
- if (Cocoa_IsWindowInFullscreenSpace(window)) {
+ if (Cocoa_IsShowingModalDialog(window)) {
+ return false; // modal system dialogs can live over fullscreen windows, don't minimize.
+ } else if (Cocoa_IsWindowInFullscreenSpace(window)) {
return false;
}
}
diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h
index 67f1519eec49c..e4ab6efed4e19 100644
--- a/src/video/cocoa/SDL_cocoawindow.h
+++ b/src/video/cocoa/SDL_cocoawindow.h
@@ -152,6 +152,7 @@ typedef enum
@property(nonatomic) bool pending_size;
@property(nonatomic) bool pending_position;
@property(nonatomic) bool border_toggled;
+@property(nonatomic) bool has_modal_dialog;
#ifdef SDL_VIDEO_OPENGL_EGL
@property(nonatomic) EGLSurface egl_surface;
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index d9c70f2cfe52c..c34db72d71d3d 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -432,6 +432,18 @@ bool Cocoa_IsWindowZoomed(SDL_Window *window)
return zoomed;
}
+bool Cocoa_IsShowingModalDialog(SDL_Window *window)
+{
+ SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->internal;
+ return data.has_modal_dialog;
+}
+
+void Cocoa_SetWindowHasModalDialog(SDL_Window *window, bool has_modal)
+{
+ SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->internal;
+ data.has_modal_dialog = has_modal;
+}
+
typedef enum CocoaMenuVisibility
{
COCOA_MENU_VISIBILITY_AUTO = 0,