]> git.sesse.net Git - vlc/blobdiff - modules/gui/macosx/intf.m
macosx: lock access to addon_entry_t
[vlc] / modules / gui / macosx / intf.m
index 174af9c1ca86f324ce7799fe1ef5ebf2ebaf930f..199ddc1962d9931f15250c4289aae83eacceaa7d 100644 (file)
@@ -135,8 +135,6 @@ int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
         return VLC_EGENERIC;
     }
 
-    [[VLCMain sharedInstance] setActiveVideoPlayback: YES];
-
     SEL sel = @selector(setupVoutForWindow:withProposedVideoViewPosition:);
     NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[o_vout_controller methodSignatureForSelector:sel]];
     [inv setTarget:o_vout_controller];
@@ -275,7 +273,6 @@ static void QuitVLC( void *obj )
  * Run: main loop
  *****************************************************************************/
 static NSLock * o_appLock = nil;    // controls access to f_appExit
-static NSLock * o_plItemChangedLock = nil;
 
 static void Run(intf_thread_t *p_intf)
 {
@@ -283,7 +280,6 @@ static void Run(intf_thread_t *p_intf)
     [VLCApplication sharedApplication];
 
     o_appLock = [[NSLock alloc] init];
-    o_plItemChangedLock = [[NSLock alloc] init];
     o_vout_provider_lock = [[NSLock alloc] init];
 
     libvlc_SetExitHandler(p_intf->p_libvlc, QuitVLC, p_intf);
@@ -294,7 +290,6 @@ static void Run(intf_thread_t *p_intf)
 
     [NSApp run];
     [[VLCMain sharedInstance] applicationWillTerminate:nil];
-    [o_plItemChangedLock release];
     [o_appLock release];
     [o_vout_provider_lock release];
     o_vout_provider_lock = nil;
@@ -390,13 +385,7 @@ static int PLItemChanged(vlc_object_t *p_this, const char *psz_var,
 {
     NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
 
-    /* Due to constraints within NSAttributedString's main loop runtime handling
-     * and other issues, we need to wait for -PlaylistItemChanged to finish and
-     * then -informInputChanged on this non-main thread. */
-    [o_plItemChangedLock lock];
-    [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(PlaylistItemChanged) withObject:nil waitUntilDone:YES]; // MUST BE ON MAIN THREAD
-    [[VLCMain sharedInstance] informInputChanged]; // DO NOT MOVE TO MAIN THREAD
-    [o_plItemChangedLock unlock];
+    [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(PlaylistItemChanged) withObject:nil waitUntilDone:NO];
 
     [o_pool release];
     return VLC_SUCCESS;
@@ -463,14 +452,15 @@ static int ShowController(vlc_object_t *p_this, const char *psz_variable,
                      vlc_value_t old_val, vlc_value_t new_val, void *param)
 {
     intf_thread_t * p_intf = VLCIntf;
-    if (p_intf && p_intf->p_sys) {
+    if (p_intf) {
         playlist_t * p_playlist = pl_Get(p_intf);
         BOOL b_fullscreen = var_GetBool(p_playlist, "fullscreen");
-        if (strcmp(psz_variable, "intf-toggle-fscontrol") || b_fullscreen)
+        if (b_fullscreen)
             [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(showFullscreenController) withObject:nil waitUntilDone:NO];
-        else
+        else if (!strcmp(psz_variable, "intf-show"))
             [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(showMainWindow) withObject:nil waitUntilDone:NO];
     }
+
     return VLC_SUCCESS;
 }
 
@@ -493,7 +483,7 @@ static int DialogCallback(vlc_object_t *p_this, const char *type, vlc_value_t pr
     }
 
     NSValue *o_value = [NSValue valueWithPointer:value.p_address];
-    [[VLCCoreDialogProvider sharedInstance] performEventWithObject: o_value ofType: type];
+    [[[VLCMain sharedInstance] coreDialogProvider] performEventWithObject: o_value ofType: type];
 
     [o_pool release];
     return VLC_SUCCESS;
@@ -616,7 +606,7 @@ static VLCMain *_o_sharedMainInstance = nil;
         _o_sharedMainInstance = [super init];
 
     p_intf = NULL;
-    p_current_input = p_input_changed = NULL;
+    p_current_input = NULL;
 
     o_open = [[VLCOpen alloc] init];
     o_coredialogs = [[VLCCoreDialogProvider alloc] init];
@@ -637,6 +627,8 @@ static VLCMain *_o_sharedMainInstance = nil;
 
     o_vout_controller = [[VLCVoutWindowController alloc] init];
 
+    informInputChangedQueue = dispatch_queue_create("org.videolan.vlc.inputChangedQueue", DISPATCH_QUEUE_SERIAL);
+
     return _o_sharedMainInstance;
 }
 
@@ -682,8 +674,7 @@ static VLCMain *_o_sharedMainInstance = nil;
             var_SetBool(p_playlist, "fullscreen", YES);
     }
 
-    /* load our Core and Shared Dialogs nibs */
-    nib_coredialogs_loaded = [NSBundle loadNibNamed:@"CoreDialogs" owner: NSApp];
+    /* load our Shared Dialogs nib */
     [NSBundle loadNibNamed:@"SharedDialogs" owner: NSApp];
 
     /* subscribe to various interactive dialogues */
@@ -777,9 +768,6 @@ static VLCMain *_o_sharedMainInstance = nil;
     [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(computerWillSleep:)
            name:NSWorkspaceWillSleepNotification object:nil];
 
-    /* we will need this, so let's load it here so the interface appears to be more responsive */
-    nib_open_loaded = [NSBundle loadNibNamed:@"Open" owner: NSApp];
-
     /* update the main window */
     [o_mainwindow updateWindow];
     [o_mainwindow updateTimeSlider];
@@ -851,6 +839,9 @@ static VLCMain *_o_sharedMainInstance = nil;
     var_DelCallback(p_intf->p_libvlc, "intf-boss", BossCallback, self);
 
     if (p_current_input) {
+        /* continue playback where you left off */
+        [[self playlist] storePlaybackPositionForItem:p_current_input];
+
         var_DelCallback(p_current_input, "intf-event", InputEvent, [VLCMain sharedInstance]);
         vlc_object_release(p_current_input);
         p_current_input = NULL;
@@ -1271,9 +1262,11 @@ static VLCMain *_o_sharedMainInstance = nil;
 // This must be called on main thread
 - (void)PlaylistItemChanged
 {
+    input_thread_t *p_input_changed = NULL;
+
     if (p_current_input && (p_current_input->b_dead || !vlc_object_alive(p_current_input))) {
         var_DelCallback(p_current_input, "intf-event", InputEvent, [VLCMain sharedInstance]);
-        p_input_changed = p_current_input;
+        vlc_object_release(p_current_input);
         p_current_input = NULL;
 
         [o_mainmenu setRateControlsEnabled: NO];
@@ -1291,6 +1284,8 @@ static VLCMain *_o_sharedMainInstance = nil;
             }
 
             p_input_changed = vlc_object_hold(p_current_input);
+
+            [[self playlist] continuePlaybackWhereYouLeftOff:p_current_input];
         }
     }
 
@@ -1298,15 +1293,17 @@ static VLCMain *_o_sharedMainInstance = nil;
     [o_mainwindow updateWindow];
     [self updateDelays];
     [self updateMainMenu];
-}
 
-- (void)informInputChanged
-{
-    if (p_input_changed) {
+    /*
+     * Due to constraints within NSAttributedString's main loop runtime handling
+     * and other issues, we need to inform the extension manager on a separate thread.
+     * The serial queue ensures that changed inputs are propagated in the same order as they arrive.
+     */
+    dispatch_async(informInputChangedQueue, ^{
         [[ExtensionsManager getInstance:p_intf] inputChanged:p_input_changed];
-        vlc_object_release(p_input_changed);
-        p_input_changed = NULL;
-    }
+        if (p_input_changed)
+            vlc_object_release(p_input_changed);
+    });
 }
 
 - (void)updateMainMenu
@@ -1504,6 +1501,10 @@ static VLCMain *_o_sharedMainInstance = nil;
         }
 
         if (state == END_S || state == -1) {
+            /* continue playback where you left off */
+            if (p_current_input)
+                [[self playlist] storePlaybackPositionForItem:p_current_input];
+
             if (i_control_itunes > 0) {
                 if (o_itunes_play_timer) {
                     [o_itunes_play_timer invalidate];
@@ -1579,10 +1580,7 @@ static VLCMain *_o_sharedMainInstance = nil;
 
 - (id)controls
 {
-    if (o_controls)
-        return o_controls;
-
-    return nil;
+    return o_controls;
 }
 
 - (id)bookmarks
@@ -1598,9 +1596,6 @@ static VLCMain *_o_sharedMainInstance = nil;
 
 - (id)open
 {
-    if (!o_open)
-        return nil;
-
     if (!nib_open_loaded)
         nib_open_loaded = [NSBundle loadNibNamed:@"Open" owner: NSApp];
 
@@ -1631,10 +1626,7 @@ static VLCMain *_o_sharedMainInstance = nil;
 
 - (id)playlist
 {
-    if (o_playlist)
-        return o_playlist;
-
-    return nil;
+    return o_playlist;
 }
 
 - (id)info
@@ -1642,10 +1634,7 @@ static VLCMain *_o_sharedMainInstance = nil;
     if (! nib_info_loaded)
         nib_info_loaded = [NSBundle loadNibNamed:@"MediaInfo" owner: NSApp];
 
-    if (o_info)
-        return o_info;
-
-    return nil;
+    return o_info;
 }
 
 - (id)wizard
@@ -1657,23 +1646,22 @@ static VLCMain *_o_sharedMainInstance = nil;
         nib_wizard_loaded = [NSBundle loadNibNamed:@"Wizard" owner: NSApp];
         [o_wizard initStrings];
     }
+
     return o_wizard;
 }
 
 - (id)coreDialogProvider
 {
-    if (o_coredialogs)
-        return o_coredialogs;
+    if (!nib_coredialogs_loaded) {
+        nib_coredialogs_loaded = [NSBundle loadNibNamed:@"CoreDialogs" owner: NSApp];
+    }
 
-    return nil;
+    return o_coredialogs;
 }
 
 - (id)eyeTVController
 {
-    if (o_eyetv)
-        return o_eyetv;
-
-    return nil;
+    return o_eyetv;
 }
 
 - (id)appleRemoteController