Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
VLC
Manage
Activity
Members
Labels
Plan
Issues
4k
Issue boards
Milestones
Code
Merge requests
454
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Analyze
Contributor analytics
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
VideoLAN
VLC
Commits
98f8356b
Commit
98f8356b
authored
5 years ago
by
Felix Paul Kühne
Browse files
Options
Downloads
Patches
Plain Diff
notify: update macOS plugin to use the new playlist
parent
3cfc957b
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
modules/notify/osx_notifications.m
+87
-104
87 additions, 104 deletions
modules/notify/osx_notifications.m
with
87 additions
and
104 deletions
modules/notify/osx_notifications.m
+
87
−
104
View file @
98f8356b
...
...
@@ -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@videolanorg
>
* Felix Paul Kühne <fkuehne
@
videolan.org
*
Marvin Scholz <epirat07@gmail.com
>
* Authors:
Marvin Scholz <epirat07@gmail.com
>
* Felix Paul Kühne <fkuehne
#
videolan.org
>
*
Rafaël Carré <funman@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
)
current
InputDidChanged
:(
input_thread_t
*
_Nonnull
)
input
;
-
(
void
)
current
PlaylistItemChanged
:(
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
(
i
nputI
tem
));
// Fallback to item title or name
if
([
title
length
]
==
0
)
title
=
CharsToNSString
(
input_item_GetTitleFbName
(
item
));
title
=
CharsToNSString
(
input_item_GetTitleFbName
(
i
nputI
tem
));
// 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
(
i
nputI
tem
));
// Get album name
NSString
*
album
=
CharsToNSString
(
input_item_GetAlbum
(
item
));
NSString
*
album
=
CharsToNSString
(
input_item_GetAlbum
(
i
nputI
tem
));
// Get coverart path
NSString
*
artPath
=
nil
;
char
*
psz_arturl
=
input_item_GetArtURL
(
item
);
char
*
psz_arturl
=
input_item_GetArtURL
(
i
nputI
tem
);
if
(
psz_arturl
)
{
artPath
=
CharsToNSString
(
vlc_uri2path
(
psz_arturl
));
free
(
psz_arturl
);
...
...
@@ -259,16 +265,6 @@ static inline NSString* CharsToNSString(char * _Nullable cStr)
[
self
notifyWithTitle
:
title
description
:
desc
imagePath
:
artPath
];
}
/*
* 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
*/
...
...
@@ -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
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment