[vlc-commits] notify: update macOS plugin to use the new playlist

Felix Paul Kühne git at videolan.org
Sat Apr 13 18:25:20 CEST 2019


vlc | branch: master | Felix Paul Kühne <felix at feepk.net> | Sat Apr 13 18:20:41 2019 +0200| [98f8356b8922930d35d098d0105e749a0fc78dc7] | committer: Felix Paul Kühne

notify: update macOS plugin to use the new playlist

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=98f8356b8922930d35d098d0105e749a0fc78dc7
---

 modules/notify/osx_notifications.m | 191 +++++++++++++++++--------------------
 1 file changed, 87 insertions(+), 104 deletions(-)

diff --git a/modules/notify/osx_notifications.m b/modules/notify/osx_notifications.m
index 96fde610de..d61131a77c 100644
--- a/modules/notify/osx_notifications.m
+++ b/modules/notify/osx_notifications.m
@@ -4,11 +4,11 @@
  * This plugin provides support for macOS notifications on current playlist
  * item changes.
  *****************************************************************************
- * Copyright © 2008, 2011, 2012, 2015, 2018 the VideoLAN team
+ * Copyright © 2008, 2011, 2012, 2015, 2018, 2019 the VideoLAN team
  *
- * Authors: Rafaël Carré <funman at videolanorg>
- *          Felix Paul Kühne <fkuehne at videolan.org
- *          Marvin Scholz <epirat07 at gmail.com>
+ * Authors: Marvin Scholz <epirat07 at gmail.com>
+ *          Felix Paul Kühne <fkuehne # videolan.org>
+ *          Rafaël Carré <funman at videolanorg>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,14 +31,12 @@
 # include "config.h"
 #endif
 
-#import <Foundation/Foundation.h>
 #import <Cocoa/Cocoa.h>
 
 #include <vlc_common.h>
 #include <vlc_plugin.h>
-#include <vlc_playlist_legacy.h>
-#include <vlc_input.h>
-#include <vlc_meta.h>
+#include <vlc_playlist.h>
+#include <vlc_player.h>
 #include <vlc_interface.h>
 #include <vlc_url.h>
 
@@ -46,14 +44,14 @@
 #pragma mark Class interfaces
 @interface VLCNotificationDelegate : NSObject <NSUserNotificationCenterDelegate>
 {
-    /** Interface thread, required for skipping to the next item */
-    intf_thread_t * _Nonnull interfaceThread;
-    
     /** Holds the last notification so it can be cleared when the next one is delivered */
-    NSUserNotification * _Nullable lastNotification;
-    
-    /** Indicates if VLC is in foreground */
-    BOOL isInForeground;
+    NSUserNotification * _Nullable _lastNotification;
+
+    /* the playlist reference */
+    vlc_playlist_t *_p_playlist;
+
+    /* the listener ID for playlist notifications */
+    vlc_playlist_listener_id *_playlistListenerID;
 }
 
 /**
@@ -62,23 +60,43 @@
 - (instancetype)initWithInterfaceThread:(intf_thread_t * _Nonnull)intf_thread;
 
 /**
- * Delegate method called when the current input changed
+ * Delegate method called when the current playlist item changed
  */
-- (void)currentInputDidChanged:(input_thread_t * _Nonnull)input;
+- (void)currentPlaylistItemChanged:(size_t)index;
 
 @end
 
-
-#pragma mark -
-#pragma mark Local prototypes
 struct intf_sys_t
 {
     void *vlcNotificationDelegate;
 };
 
-static int InputCurrent(vlc_object_t *, const char *,
-                        vlc_value_t, vlc_value_t, void *);
+#pragma mark -
+#pragma mark callback
 
+static void
+cb_playlist_current_item_changed(vlc_playlist_t *playlist,
+                                 ssize_t index,
+                                 void *p_data)
+{
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCNotificationDelegate *notificationDelegate = (__bridge VLCNotificationDelegate *)p_data;
+        [notificationDelegate currentPlaylistItemChanged:index];
+    });
+}
+
+static const struct vlc_playlist_callbacks playlist_callbacks = {
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    cb_playlist_current_item_changed,
+    NULL,
+    NULL,
+};
 
 #pragma mark -
 #pragma mark C module functions
@@ -88,7 +106,6 @@ static int InputCurrent(vlc_object_t *, const char *,
 static int Open(vlc_object_t *p_this)
 {
     intf_thread_t *p_intf = (intf_thread_t *)p_this;
-    playlist_t *p_playlist = pl_Get(p_intf);
     intf_sys_t *p_sys = p_intf->p_sys = calloc(1, sizeof(intf_sys_t));
 
     if (!p_sys)
@@ -106,8 +123,6 @@ static int Open(vlc_object_t *p_this)
         p_sys->vlcNotificationDelegate = (__bridge_retained void*)notificationDelegate;
     }
 
-    var_AddCallback(p_playlist, "input-current", InputCurrent, p_intf);
-
     return VLC_SUCCESS;
 }
 
@@ -117,12 +132,7 @@ static int Open(vlc_object_t *p_this)
 static void Close(vlc_object_t *p_this)
 {
     intf_thread_t *p_intf = (intf_thread_t *)p_this;
-    playlist_t *p_playlist = pl_Get(p_intf);
     intf_sys_t *p_sys = p_intf->p_sys;
-    
-    // Remove the callback, this must be done here, before deallocating the
-    // notification delegate object
-    var_DelCallback(p_playlist, "input-current", InputCurrent, p_intf);
 
     @autoreleasepool {
         // Transfer ownership of notification delegate object back to ARC
@@ -136,27 +146,6 @@ static void Close(vlc_object_t *p_this)
     free(p_sys);
 }
 
-/*
- * Callback invoked on playlist item change
- */
-static int InputCurrent(vlc_object_t *p_this, const char *psz_var,
-                        vlc_value_t oldval, vlc_value_t newval, void *param)
-{
-    intf_thread_t *p_intf = (intf_thread_t *)param;
-    intf_sys_t *p_sys = p_intf->p_sys;
-    input_thread_t *p_input = newval.p_address;
-    VLC_UNUSED(oldval);
-
-    @autoreleasepool {
-        VLCNotificationDelegate *notificationDelegate =
-            (__bridge VLCNotificationDelegate*)p_sys->vlcNotificationDelegate;
-        
-        [notificationDelegate currentInputDidChanged:(input_thread_t *)p_input];
-    }
-
-    return VLC_SUCCESS;
-}
-
 /**
   * Transfers a null-terminated UTF-8 C "string" to a NSString
   * in a way that the NSString takes ownership of it.
@@ -192,18 +181,13 @@ static inline NSString* CharsToNSString(char * _Nullable cStr)
     self = [super init];
     
     if (self) {
-        interfaceThread = intf_thread;
-        
-        // Subscribe to notifications to determine if VLC is in foreground or not
-        [[NSNotificationCenter defaultCenter] addObserver:self
-                                                 selector:@selector(applicationActiveChange:)
-                                                     name:NSApplicationDidBecomeActiveNotification
-                                                   object:nil];
-
-        [[NSNotificationCenter defaultCenter] addObserver:self
-                                                 selector:@selector(applicationActiveChange:)
-                                                     name:NSApplicationDidResignActiveNotification
-                                                   object:nil];
+        _p_playlist = vlc_intf_GetMainPlaylist(intf_thread);
+        vlc_playlist_Lock(_p_playlist);
+        _playlistListenerID = vlc_playlist_AddListener(_p_playlist,
+                                                       &playlist_callbacks,
+                                                       (__bridge void *)self,
+                                                       YES);
+        vlc_playlist_Unlock(_p_playlist);
 
         [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
     }
@@ -211,36 +195,58 @@ static inline NSString* CharsToNSString(char * _Nullable cStr)
     return self;
 }
 
-- (void)currentInputDidChanged:(input_thread_t *)input
+- (void)dealloc
 {
-    if (!input)
-        return;
-    
-    input_item_t *item = input_GetItem(input);
-    if (!item)
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+    // Clear a remaining lastNotification in Notification Center, if any
+    if (_lastNotification) {
+        [[NSUserNotificationCenter defaultUserNotificationCenter]
+         removeDeliveredNotification:_lastNotification];
+        _lastNotification = nil;
+    }
+
+    if (_p_playlist) {
+        if (_playlistListenerID) {
+            vlc_playlist_Lock(_p_playlist);
+            vlc_playlist_RemoveListener(_p_playlist, _playlistListenerID);
+            vlc_playlist_Unlock(_p_playlist);
+        }
+    }
+}
+
+- (void)currentPlaylistItemChanged:(size_t)index
+{
+    vlc_player_t *player = vlc_playlist_GetPlayer(_p_playlist);
+    vlc_player_Lock(player);
+    input_item_t *inputItem = vlc_player_HoldCurrentMedia(player);
+    vlc_player_Unlock(player);
+    if (inputItem == NULL) {
         return;
+    }
     
     // Get title, first try now playing
-    NSString *title = CharsToNSString(input_item_GetNowPlayingFb(item));
+    NSString *title = CharsToNSString(input_item_GetNowPlayingFb(inputItem));
 
     // Fallback to item title or name
     if ([title length] == 0)
-        title = CharsToNSString(input_item_GetTitleFbName(item));
+        title = CharsToNSString(input_item_GetTitleFbName(inputItem));
 
     // If there is still not title, do not notify
-    if (unlikely([title length] == 0))
+    if (unlikely([title length] == 0)) {
         return;
+    }
 
     // Get artist name
-    NSString *artist = CharsToNSString(input_item_GetArtist(item));
+    NSString *artist = CharsToNSString(input_item_GetArtist(inputItem));
 
     // Get album name
-    NSString *album = CharsToNSString(input_item_GetAlbum(item));
+    NSString *album = CharsToNSString(input_item_GetAlbum(inputItem));
 
     // Get coverart path
     NSString *artPath = nil;
 
-    char *psz_arturl = input_item_GetArtURL(item);
+    char *psz_arturl = input_item_GetArtURL(inputItem);
     if (psz_arturl) {
         artPath = CharsToNSString(vlc_uri2path(psz_arturl));
         free(psz_arturl);
@@ -260,16 +266,6 @@ static inline NSString* CharsToNSString(char * _Nullable cStr)
 }
 
 /*
- * Called when the applications activity status changes
- */
-- (void)applicationActiveChange:(NSNotification *)n {
-    if (n.name == NSApplicationDidBecomeActiveNotification)
-        isInForeground = YES;
-    else if (n.name == NSApplicationDidResignActiveNotification)
-        isInForeground = NO;
-}
-
-/*
  * Called when the user interacts with a notification
  */
 - (void)userNotificationCenter:(NSUserNotificationCenter *)center
@@ -278,7 +274,9 @@ static inline NSString* CharsToNSString(char * _Nullable cStr)
     // Check if notification button ("Skip") was clicked
     if (notification.activationType == NSUserNotificationActivationTypeActionButtonClicked) {
         // Skip to next song
-        playlist_Next(pl_Get(interfaceThread));
+        vlc_playlist_Lock(_p_playlist);
+        vlc_playlist_Next(_p_playlist);
+        vlc_playlist_Unlock(_p_playlist);
     }
 }
 
@@ -289,10 +287,10 @@ static inline NSString* CharsToNSString(char * _Nullable cStr)
         didDeliverNotification:(NSUserNotification *)notification
 {
     // Only keep the most recent notification in the Notification Center
-    if (lastNotification)
-        [center removeDeliveredNotification:lastNotification];
+    if (_lastNotification)
+        [center removeDeliveredNotification:_lastNotification];
 
-    lastNotification = notification;
+    _lastNotification = notification;
 }
 
 /*
@@ -335,21 +333,6 @@ static inline NSString* CharsToNSString(char * _Nullable cStr)
         deliverNotification:notification];
 }
 
-/*
- * Cleanup
- */
-- (void)dealloc
-{
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
-
-    // Clear a remaining lastNotification in Notification Center, if any
-    if (lastNotification) {
-        [[NSUserNotificationCenter defaultUserNotificationCenter]
-            removeDeliveredNotification:lastNotification];
-        lastNotification = nil;
-    }
-}
-
 @end
 
 



More information about the vlc-commits mailing list