From fae02f2b4d8b477ed82b5bc337bcd5c2b68d737d Mon Sep 17 00:00:00 2001 From: Manolo Gouy Date: Tue, 17 Oct 2017 09:01:28 +0000 Subject: Mac OS: complete changes needed for 10.13 "High Sierra" regarding how FLTK applications start. With MacOS 10.13 "High Sierra", it was necessary to change what happens at application start time. The new procedure is: fl_open_display() calls [NSApp run], and during this call: the main event loop is started; the app delegate receives an openFile: message for each file dropped on the app icon. Each such filename is memorised in an NSMutableArray called dropped_files_list; the app delegate receives applicationDidFinishLaunching and stops the main event loop (this seems to occur unpredictably after the first openFile: message or after all of them). When the FLTK event loop begins, it checks whether dropped_files_list is empty. If it is not, the first element of this list is a filename which is opened and is removed from dropped_files_list. This new setup allows to turn resizable windows fullscreen and back as expected under MacOS, and to support launching apps while dropping file(s) on its icon. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12508 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl_cocoa.mm | 50 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index acb9dfc91..1d4f27136 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -114,6 +114,10 @@ static NSString *TIFF_pasteboard_type = (fl_mac_os_version >= 100600 ? NSPastebo static NSString *PDF_pasteboard_type = (fl_mac_os_version >= 100600 ? NSPasteboardTypePDF : NSPDFPboardType); static NSString *PICT_pasteboard_type = (fl_mac_os_version >= 100600 ? @"com.apple.pict" : NSPICTPboardType); static NSString *UTF8_pasteboard_type = (fl_mac_os_version >= 100600 ? NSPasteboardTypeString : NSStringPboardType); +static bool in_nsapp_run = false; // true during execution of [NSApp run] +static NSMutableArray *dropped_files_list = nil; // list of files dropped at app launch +typedef void (*open_cb_f_type)(const char *); +static open_cb_f_type get_open_cb(); #if CONSOLIDATE_MOTION static Fl_Window* send_motion; @@ -845,6 +849,18 @@ static int do_queued_events( double time = 0.0 ) double Fl_Cocoa_Screen_Driver::wait(double time_to_wait) { + if (dropped_files_list) { // when the list of dropped files is not empty, open one and remove it from list + open_cb_f_type open_cb = get_open_cb(); + NSString *s; + if ( (s = (NSString*)[dropped_files_list firstObject]) != nil) { + if (open_cb) open_cb([s UTF8String]); + [dropped_files_list removeObjectAtIndex:0]; + } + if ([dropped_files_list count] == 0) { + [dropped_files_list release]; + dropped_files_list = nil; + } + } Fl::run_checks(); static int in_idle = 0; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -1456,8 +1472,8 @@ static FLWindowDelegate *flwindowdelegate_instance = nil; #endif { - void (*open_cb)(const char*); @public + open_cb_f_type open_cb; TSMDocumentID currentDoc; } - (void)applicationDidFinishLaunching:(NSNotification *)notification; @@ -1469,7 +1485,6 @@ static FLWindowDelegate *flwindowdelegate_instance = nil; - (void)applicationWillHide:(NSNotification *)notify; - (void)applicationWillUnhide:(NSNotification *)notify; - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename; -- (void)open_cb:(void (*)(const char*))cb; @end @implementation FLAppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)notification @@ -1620,10 +1635,16 @@ static FLWindowDelegate *flwindowdelegate_instance = nil; } - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { + if (fl_mac_os_version < 101300) { // without the next two statements, the opening of the 1st window is delayed by several seconds - // under Mac OS ≥ 10.8 when a file is dragged on the application icon - Fl_Window *firstw = Fl::first_window(); - if (firstw) firstw->wait_for_expose(); + // under 10.8 ≤ Mac OS < 10.13 when a file is dragged on the application icon + Fl_Window *firstw = Fl::first_window(); + if (firstw) firstw->wait_for_expose(); + } else if (in_nsapp_run) { // memorize all dropped filenames + if (!dropped_files_list) dropped_files_list = [[NSMutableArray alloc] initWithCapacity:1]; + [dropped_files_list addObject:filename]; + return YES; + } if (open_cb) { fl_lock_function(); (*open_cb)([filename UTF8String]); @@ -1633,10 +1654,6 @@ static FLWindowDelegate *flwindowdelegate_instance = nil; } return NO; } -- (void)open_cb:(void (*)(const char*))cb -{ - open_cb = cb; -} @end @interface FLAppDelegateBefore10_5 : FLAppDelegate @@ -1659,12 +1676,16 @@ static FLWindowDelegate *flwindowdelegate_instance = nil; } @end +static open_cb_f_type get_open_cb() { + return ((FLAppDelegate*)[NSApp delegate])->open_cb; +} + /* * Install an open documents event handler... */ void Fl_Darwin_System_Driver::open_callback(void (*cb)(const char *)) { fl_open_display(); - [(FLAppDelegate*)[NSApp delegate] open_cb:cb]; + ((FLAppDelegate*)[NSApp delegate])->open_cb = cb; } @implementation FLApplication @@ -1721,7 +1742,14 @@ void Fl_Cocoa_Screen_Driver::open_display_platform() { localPool = [[NSAutoreleasePool alloc] init]; // never released FLAppDelegate *delegate = (fl_mac_os_version < 100500 ? [FLAppDelegateBefore10_5 alloc] : [FLAppDelegate alloc]); [(NSApplication*)NSApp setDelegate:[delegate init]]; - if (need_new_nsapp) (fl_mac_os_version >= 101300 ? [NSApp run] : [NSApp finishLaunching]); + if (need_new_nsapp) { + if (fl_mac_os_version >= 101300 ) { + in_nsapp_run = true; + [NSApp run]; + in_nsapp_run = false; + } + else [NSApp finishLaunching]; + } // empty the event queue but keep system events for drag&drop of files at launch NSEvent *ign_event; -- cgit v1.2.3