Fixed bug 1970 - Cocoa message boxes ignore parent window requests
authorSam Lantinga <slouken@libsdl.org>
Sun, 14 Jul 2013 11:58:57 -0700
changeset 7457 8e6dfbc8ac6b
parent 7456 193c9a1723ad
child 7458 648067e9073a
Fixed bug 1970 - Cocoa message boxes ignore parent window requests Ryan C. Gordon Cocoa_ShowMessageBox() ignores the "window" field of SDL_MessageBoxData, which means you can't assign a parent window to a message box. This is particularly egregious on Mac OS X, because it'll actually make the NSAlert visually part of the parent window instead of just concerning itself with window focus.
src/video/cocoa/SDL_cocoamessagebox.m
--- a/src/video/cocoa/SDL_cocoamessagebox.m	Sun Jul 14 11:57:45 2013 -0700
+++ b/src/video/cocoa/SDL_cocoamessagebox.m	Sun Jul 14 11:58:57 2013 -0700
@@ -29,21 +29,33 @@
 #undef pixel
 #endif
 
+#include "SDL_events.h"
+#include "SDL_timer.h"
 #include "SDL_messagebox.h"
 #include "SDL_cocoavideo.h"
 
 @interface SDLMessageBoxPresenter : NSObject {
 @public
     NSInteger clicked;
+    NSWindow *nswindow;
 }
+- (id) initWithParentWindow:(SDL_Window *)window;
+- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo;
 @end
 
 @implementation SDLMessageBoxPresenter
-- (id)init
+- (id) initWithParentWindow:(SDL_Window *)window
 {
     self = [super init];
     if (self) {
         clicked = -1;
+
+        /* Retain the NSWindow because we'll show the alert later on the main thread */
+        if (window) {
+            nswindow = [((SDL_WindowData *) window->driverdata)->nswindow retain];
+        } else {
+            nswindow = NULL;
+        }
     }
 
     return self;
@@ -51,8 +63,23 @@
 
 - (void)showAlert:(NSAlert*)alert
 {
-    clicked = [alert runModal];
+    if (nswindow) {
+        [alert beginSheetModalForWindow:nswindow modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil];
+        while (clicked < 0) {
+            SDL_PumpEvents();
+            SDL_Delay(100);
+        }
+        [nswindow release];
+    } else {
+        clicked = [alert runModal];
+    }
 }
+
+- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
+{
+    clicked = returnCode;
+}
+
 @end
 
 
@@ -90,7 +117,7 @@
         }
     }
 
-    SDLMessageBoxPresenter* presenter = [[[SDLMessageBoxPresenter alloc] init] autorelease];
+    SDLMessageBoxPresenter* presenter = [[[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window] autorelease];
 
     [presenter performSelectorOnMainThread:@selector(showAlert:)
                                 withObject:alert