From 685b8b7a00ad171f76aba6a93ffaff890aa0caa1 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sat, 6 Dec 2014 12:48:18 +0100 Subject: cocoa: use --idle when running inside bundle Previously when using the bundle we used a custom bizarro thing to wait for events. Just use `--idle` and greatly simplify the code. --- osdep/macosx_application.h | 11 --- osdep/macosx_application.m | 185 +++++++++++----------------------------- osdep/macosx_application_objc.h | 2 - osdep/macosx_events.m | 10 +-- 4 files changed, 56 insertions(+), 152 deletions(-) (limited to 'osdep') diff --git a/osdep/macosx_application.h b/osdep/macosx_application.h index 23c5838a3b..d6a9425f29 100644 --- a/osdep/macosx_application.h +++ b/osdep/macosx_application.h @@ -32,18 +32,7 @@ typedef enum { // multithreaded wrapper for mpv_main int cocoa_main(mpv_main_fn mpv_main, int argc, char *argv[]); - void cocoa_register_menu_item_action(MPMenuKey key, void* action); - -// initializes Cocoa application -void init_cocoa_application(void); void terminate_cocoa_application(void); -// Runs the Cocoa Main Event Loop -void cocoa_run_runloop(void); -void cocoa_stop_runloop(void); -void cocoa_post_fake_event(void); - -void macosx_finder_args_preinit(int *argc, char ***argv); - #endif /* MPV_MACOSX_APPLICATION */ diff --git a/osdep/macosx_application.m b/osdep/macosx_application.m index 9efeeb274d..98d00244fb 100644 --- a/osdep/macosx_application.m +++ b/osdep/macosx_application.m @@ -48,7 +48,6 @@ static pthread_t playback_thread_id; - (NSMenu *)appleMenuWithMainMenu:(NSMenu *)mainMenu; - (NSMenu *)movieMenu; - (NSMenu *)windowMenu; -- (void)handleFiles; @end @interface NSApplication (NiblessAdditions) @@ -61,10 +60,6 @@ Application *mpv_shared_app(void) } @implementation Application -@synthesize files = _files; -@synthesize argumentsList = _arguments_list; -@synthesize willStopOnOpenEvent = _will_stop_on_open_event; - @synthesize menuItems = _menu_items; - (void)sendEvent:(NSEvent *)event @@ -79,10 +74,7 @@ Application *mpv_shared_app(void) { if (self = [super init]) { self.menuItems = [[[NSMutableDictionary alloc] init] autorelease]; - self.files = nil; - self.argumentsList = [[[NSMutableArray alloc] init] autorelease]; _eventsResponder = [EventsResponder sharedInstance]; - self.willStopOnOpenEvent = NO; NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager]; [em setEventHandler:self @@ -234,47 +226,14 @@ Application *mpv_shared_app(void) range:NSMakeRange(0, [MPV_PROTOCOL length])]; url = [url stringByRemovingPercentEncoding]; - - self.files = @[url]; - - if (self.willStopOnOpenEvent) { - self.willStopOnOpenEvent = NO; - cocoa_stop_runloop(); - } else { - [self handleFiles]; - } + [_eventsResponder handleFilesArray:@[url]]; } - (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames { - Application *app = mpv_shared_app(); - NSMutableArray *filesToOpen = [[[NSMutableArray alloc] init] autorelease]; - - [filenames enumerateObjectsUsingBlock:^(id obj, NSUInteger i, BOOL *_) { - NSInteger place = [app.argumentsList indexOfObject:obj]; - if (place == NSNotFound) { - // Proper new event ^_^ - [filesToOpen addObject:obj]; - } else { - // This file was already opened from the CLI. Cocoa is trying to - // open it again using events. Ignore it! - [app.argumentsList removeObjectAtIndex:place]; - } - }]; - SEL cmpsel = @selector(localizedStandardCompare:); - self.files = [filesToOpen sortedArrayUsingSelector:cmpsel]; - if (self.willStopOnOpenEvent) { - self.willStopOnOpenEvent = NO; - cocoa_stop_runloop(); - } else { - [self handleFiles]; - } -} - -- (void)handleFiles -{ - [_eventsResponder handleFilesArray:self.files]; + NSArray *files = [filenames sortedArrayUsingSelector:cmpsel]; + [_eventsResponder handleFilesArray:files]; } @end @@ -284,6 +243,26 @@ struct playback_thread_ctx { char ***argv; }; +void terminate_cocoa_application(void) +{ + [NSApp hide:NSApp]; + [NSApp terminate:NSApp]; +} + +static void cocoa_run_runloop(void) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [NSApp run]; + [pool drain]; +} + +static void cocoa_stop_runloop(void) +{ + [NSApp performSelectorOnMainThread:@selector(stop:) + withObject:nil + waitUntilDone:true]; +} + static void *playback_thread(void *ctx_obj) { mpthread_set_name("playback core (OSX)"); @@ -295,38 +274,12 @@ static void *playback_thread(void *ctx_obj) } } -int cocoa_main(mpv_main_fn mpv_main, int argc, char *argv[]) -{ - @autoreleasepool { - struct playback_thread_ctx ctx = {0}; - ctx.mpv_main = mpv_main; - ctx.argc = &argc; - ctx.argv = &argv; - - init_cocoa_application(); - macosx_finder_args_preinit(&argc, &argv); - pthread_create(&playback_thread_id, NULL, playback_thread, &ctx); - - [[EventsResponder sharedInstance] waitForInputContext]; - - cocoa_run_runloop(); - - // This should never be reached: cocoa_run_runloop blocks until the - // process is quit - fprintf(stderr, "There was either a problem " - "initializing Cocoa or the Runloop was stopped unexpectedly. " - "Please report this issues to a developer.\n"); - pthread_join(playback_thread_id, NULL); - return 1; - } -} - void cocoa_register_menu_item_action(MPMenuKey key, void* action) { [NSApp registerSelector:(SEL)action forKey:key]; } -void init_cocoa_application(void) +static void init_cocoa_application(bool regular) { NSApp = mpv_shared_app(); [NSApp setDelegate:NSApp]; @@ -334,7 +287,9 @@ void init_cocoa_application(void) // Will be set to Regular from cocoa_common during UI creation so that we // don't create an icon when playing audio only files. - [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory]; + [NSApp setActivationPolicy: regular ? + NSApplicationActivationPolicyRegular : + NSApplicationActivationPolicyAccessory]; atexit_b(^{ // Because activation policy has just been set to behave like a real @@ -344,47 +299,6 @@ void init_cocoa_application(void) }); } -void terminate_cocoa_application(void) -{ - [NSApp hide:NSApp]; - [NSApp terminate:NSApp]; -} - -void cocoa_run_runloop() -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [NSApp run]; - [pool drain]; -} - -void cocoa_stop_runloop(void) -{ - [NSApp performSelectorOnMainThread:@selector(stop:) - withObject:nil - waitUntilDone:true]; - cocoa_post_fake_event(); -} - -void cocoa_post_fake_event(void) -{ - NSEvent* event = [NSEvent otherEventWithType:NSApplicationDefined - location:NSMakePoint(0,0) - modifierFlags:0 - timestamp:0.0 - windowNumber:0 - context:nil - subtype:0 - data1:0 - data2:0]; - [NSApp postEvent:event atStart:NO]; -} - -static void macosx_wait_fileopen_events() -{ - mpv_shared_app().willStopOnOpenEvent = YES; - cocoa_run_runloop(); // block until done -} - static void macosx_redirect_output_to_logfile(const char *filename) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -444,30 +358,33 @@ static bool bundle_started_from_finder(int argc, char **argv) } } -void macosx_finder_args_preinit(int *argc, char ***argv) +int cocoa_main(mpv_main_fn mpv_main, int argc, char *argv[]) { - Application *app = mpv_shared_app(); - - if (bundle_started_from_finder(*argc, *argv)) { - macosx_redirect_output_to_logfile("mpv"); - macosx_wait_fileopen_events(); - - char **cocoa_argv = talloc_zero_array(NULL, char*, [app.files count] + 2); - cocoa_argv[0] = "mpv"; - cocoa_argv[1] = "--quiet"; - int cocoa_argc = 2; + @autoreleasepool { + struct playback_thread_ctx ctx = {0}; + ctx.mpv_main = mpv_main; + ctx.argc = &argc; + ctx.argv = &argv; - for (NSString *filename in app.files) { - cocoa_argv[cocoa_argc] = (char*)[filename UTF8String]; - cocoa_argc++; + if (bundle_started_from_finder(argc, argv)) { + argc = 1; // clears out -psn argument is present + macosx_redirect_output_to_logfile("mpv"); + init_cocoa_application(true); + } else { + init_cocoa_application(false); } - *argc = cocoa_argc; - *argv = cocoa_argv; - } else { - for (int i = 0; i < *argc; i++ ) { - NSString *arg = [NSString stringWithUTF8String:(*argv)[i]]; - [app.argumentsList addObject:arg]; - } + pthread_create(&playback_thread_id, NULL, playback_thread, &ctx); + [[EventsResponder sharedInstance] waitForInputContext]; + cocoa_run_runloop(); + + // This should never be reached: cocoa_run_runloop blocks until the + // process is quit + fprintf(stderr, "There was either a problem " + "initializing Cocoa or the Runloop was stopped unexpectedly. " + "Please report this issues to a developer.\n"); + pthread_join(playback_thread_id, NULL); + return 1; } } + diff --git a/osdep/macosx_application_objc.h b/osdep/macosx_application_objc.h index bc2ff8eee7..2383ba810c 100644 --- a/osdep/macosx_application_objc.h +++ b/osdep/macosx_application_objc.h @@ -26,8 +26,6 @@ @property(nonatomic, retain) NSMutableDictionary *menuItems; @property(nonatomic, retain) NSArray *files; -@property(nonatomic, retain) NSMutableArray *argumentsList; -@property(nonatomic, assign) BOOL willStopOnOpenEvent; @end Application *mpv_shared_app(void); diff --git a/osdep/macosx_events.m b/osdep/macosx_events.m index fcbfd46042..026f3777d1 100644 --- a/osdep/macosx_events.m +++ b/osdep/macosx_events.m @@ -439,11 +439,11 @@ void cocoa_set_input_context(struct input_ctx *input_context) { size_t num_files = [files count]; char **files_utf8 = talloc_array(NULL, char*, num_files); - [files enumerateObjectsUsingBlock:^(id obj, NSUInteger i, BOOL *_){ - NSURL *url = [NSURL URLWithString:obj]; - NSString *path = [url path]; - char *filename = (char *)[path UTF8String]; - size_t bytes = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + [files enumerateObjectsUsingBlock:^(NSString *p, NSUInteger i, BOOL *_){ + if ([p hasPrefix:@"file:///.file/id="]) + p = [[NSURL URLWithString:p] path]; + char *filename = (char *)[p UTF8String]; + size_t bytes = [p lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; files_utf8[i] = talloc_memdup(files_utf8, filename, bytes + 1); }]; mp_event_drop_files(_inputContext, num_files, files_utf8); -- cgit v1.2.3