Compare commits
3 Commits
v0.3.0
...
10.9Support
| Author | SHA1 | Date | |
|---|---|---|---|
| 53a19b8886 | |||
| 23f94e3f4e | |||
| 88f4a96593 |
@@ -9,7 +9,6 @@
|
||||
/* Begin PBXBuildFile section */
|
||||
1C0BD0A51BF1A8E6004F4CF5 /* BGMAutoPauseMusicPrefs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C0BD0A41BF1A8E6004F4CF5 /* BGMAutoPauseMusicPrefs.mm */; };
|
||||
1C0BD0A81BF1B029004F4CF5 /* BGMPreferencesMenu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C0BD0A71BF1B029004F4CF5 /* BGMPreferencesMenu.mm */; };
|
||||
1C1108AE1C444F01003F625E /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1CB8B3421BBA75EF000E2DD1 /* MainMenu.xib */; };
|
||||
1C1465B81BCC3A73003AEFE6 /* BGMAutoPauseMusic.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C1465B71BCC3A73003AEFE6 /* BGMAutoPauseMusic.mm */; };
|
||||
1C1962E41BC94E15008A4DF7 /* CARingBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C1962E21BC94E15008A4DF7 /* CARingBuffer.cpp */; };
|
||||
1C1962E71BC94E91008A4DF7 /* BGMPlayThrough.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C1962E51BC94E91008A4DF7 /* BGMPlayThrough.cpp */; };
|
||||
@@ -51,6 +50,8 @@
|
||||
278D71E91CABB6FF00899CF9 /* BGMXPCHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 279597401C996E2000A002FB /* BGMXPCHelperTests.m */; };
|
||||
278D71F61CABBC3B00899CF9 /* BGMXPCHelperTests-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 278D71F51CABBC3B00899CF9 /* BGMXPCHelperTests-Info.plist */; };
|
||||
2795973B1C982E4E00A002FB /* BGMXPCListener.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2795973A1C982E4E00A002FB /* BGMXPCListener.mm */; };
|
||||
27977A0C1CD12DBB00C46C96 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1CB8B3421BBA75EF000E2DD1 /* MainMenu.xib */; };
|
||||
27977A0E1CD15F7500C46C96 /* FermataIcon.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 27977A0D1CD15F7500C46C96 /* FermataIcon.pdf */; };
|
||||
27D643BE1C9FB84C00737F6E /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 27D643BB1C9FB84C00737F6E /* Info.plist */; };
|
||||
27D643C01C9FB99200737F6E /* BGMXPCHelperService.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D643BA1C9FB84C00737F6E /* BGMXPCHelperService.m */; };
|
||||
27D643C11C9FB99200737F6E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D643BC1C9FB84C00737F6E /* main.m */; };
|
||||
@@ -166,6 +167,9 @@
|
||||
2795973A1C982E4E00A002FB /* BGMXPCListener.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BGMXPCListener.mm; sourceTree = "<group>"; };
|
||||
2795973C1C982E8C00A002FB /* BGMXPCListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BGMXPCListener.h; sourceTree = "<group>"; };
|
||||
279597401C996E2000A002FB /* BGMXPCHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BGMXPCHelperTests.m; sourceTree = "<group>"; };
|
||||
27977A0D1CD15F7500C46C96 /* FermataIcon.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = FermataIcon.pdf; path = Images.xcassets/FermataIcon.imageset/FermataIcon.pdf; sourceTree = "<group>"; };
|
||||
27A7DE9D1CCDBBC500ACE97D /* VLC_10.9.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLC_10.9.h; path = "Music Players/VLC_10.9.h"; sourceTree = "<group>"; };
|
||||
27B1777C1CCBB0D5000E7BD2 /* BGMPrefixHeader.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BGMPrefixHeader.pch; path = ../SharedSource/BGMPrefixHeader.pch; sourceTree = "<group>"; };
|
||||
27D643B41C9FABBD00737F6E /* BGM_Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BGM_Types.h; path = ../SharedSource/BGM_Types.h; sourceTree = "<group>"; };
|
||||
27D643B51C9FABBD00737F6E /* BGMXPCProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BGMXPCProtocols.h; path = ../SharedSource/BGMXPCProtocols.h; sourceTree = "<group>"; };
|
||||
27D643B91C9FB84C00737F6E /* BGMXPCHelperService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BGMXPCHelperService.h; path = BGMXPCHelper/BGMXPCHelperService.h; sourceTree = SOURCE_ROOT; };
|
||||
@@ -267,6 +271,7 @@
|
||||
1C4699401BD5BA1700F78043 /* SharedSource */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
27B1777C1CCBB0D5000E7BD2 /* BGMPrefixHeader.pch */,
|
||||
27D643B41C9FABBD00737F6E /* BGM_Types.h */,
|
||||
2771700F1CA0C83B00AB34B4 /* BGM_Utils.h */,
|
||||
27D643C41C9FBE5600737F6E /* BGM_TestUtils.h */,
|
||||
@@ -348,6 +353,7 @@
|
||||
1CB8B3391BBA75EF000E2DD1 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
27977A0D1CD15F7500C46C96 /* FermataIcon.pdf */,
|
||||
1CED61681C3081C2002CAFCF /* LICENSE */,
|
||||
1CC1DF951BE8607700FB8FE4 /* Images.xcassets */,
|
||||
1CB8B33A1BBA75EF000E2DD1 /* Info.plist */,
|
||||
@@ -390,6 +396,7 @@
|
||||
27379B851C7C54870084A24C /* iTunes.h */,
|
||||
27379B861C7C54870084A24C /* Spotify.h */,
|
||||
27379B871C7C552A0084A24C /* VLC.h */,
|
||||
27A7DE9D1CCDBBC500ACE97D /* VLC_10.9.h */,
|
||||
273F10DC1CC3CF9C00C1C6DA /* Vox.h */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
@@ -543,13 +550,14 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
27977A0C1CD12DBB00C46C96 /* MainMenu.xib in Resources */,
|
||||
2769728C1CAFCEE8007A2F7C /* post_install.sh in Resources */,
|
||||
2769728E1CAFCEFD007A2F7C /* com.bearisdriving.BGM.XPCHelper.plist.template in Resources */,
|
||||
27D643BE1C9FB84C00737F6E /* Info.plist in Resources */,
|
||||
1CED61691C3081C2002CAFCF /* LICENSE in Resources */,
|
||||
278D71F61CABBC3B00899CF9 /* BGMXPCHelperTests-Info.plist in Resources */,
|
||||
27977A0E1CD15F7500C46C96 /* FermataIcon.pdf in Resources */,
|
||||
1CC1DF961BE8607700FB8FE4 /* Images.xcassets in Resources */,
|
||||
1C1108AE1C444F01003F625E /* MainMenu.xib in Resources */,
|
||||
276972911CB16008007A2F7C /* safe_install_dir.sh in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -717,6 +725,7 @@
|
||||
GCC_C_LANGUAGE_STANDARD = c11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = s;
|
||||
GCC_PREFIX_HEADER = ../SharedSource/BGMPrefixHeader.pch;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"CoreAudio_Debug=1",
|
||||
@@ -724,7 +733,7 @@
|
||||
"CoreAudio_StopOnAssert=1",
|
||||
);
|
||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
@@ -753,7 +762,6 @@
|
||||
CLANG_USE_OPTIMIZATION_PROFILE = NO;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_UNROLL_LOOPS = YES;
|
||||
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
|
||||
INFOPLIST_FILE = BGMApp/Info.plist;
|
||||
@@ -812,6 +820,7 @@
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREFIX_HEADER = ../SharedSource/BGMPrefixHeader.pch;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"CoreAudio_Debug=1",
|
||||
@@ -819,7 +828,7 @@
|
||||
"CoreAudio_StopOnAssert=1",
|
||||
);
|
||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
@@ -871,6 +880,7 @@
|
||||
GCC_C_LANGUAGE_STANDARD = c11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = s;
|
||||
GCC_PREFIX_HEADER = ../SharedSource/BGMPrefixHeader.pch;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=0",
|
||||
"CoreAudio_Debug=0",
|
||||
@@ -878,7 +888,7 @@
|
||||
"CoreAudio_StopOnAssert=0",
|
||||
);
|
||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
@@ -906,7 +916,6 @@
|
||||
CLANG_USE_OPTIMIZATION_PROFILE = NO;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_UNROLL_LOOPS = YES;
|
||||
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
|
||||
INFOPLIST_FILE = BGMApp/Info.plist;
|
||||
@@ -925,7 +934,6 @@
|
||||
CLANG_USE_OPTIMIZATION_PROFILE = NO;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_UNROLL_LOOPS = YES;
|
||||
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
|
||||
INFOPLIST_FILE = BGMApp/Info.plist;
|
||||
|
||||
@@ -53,15 +53,34 @@ static float const kStatusBarIconPadding = 0.25;
|
||||
// Set the icon
|
||||
NSImage* icon = [NSImage imageNamed:@"FermataIcon"];
|
||||
if (icon != nil) {
|
||||
CGFloat lengthMinusPadding = [[statusBarItem button] frame].size.height * (1 - kStatusBarIconPadding);
|
||||
[icon setSize:NSMakeSize(lengthMinusPadding, lengthMinusPadding)];
|
||||
// Make the icon a "template image" so it gets drawn colour-inverted when it's highlighted or the status
|
||||
// bar's in dark mode
|
||||
[icon setTemplate:YES];
|
||||
statusBarItem.button.image = icon;
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9
|
||||
if ([statusBarItem respondsToSelector:@selector(button)]) {
|
||||
CGFloat lengthMinusPadding = statusBarItem.button.frame.size.height * (1 - kStatusBarIconPadding);
|
||||
[icon setSize:NSMakeSize(lengthMinusPadding, lengthMinusPadding)];
|
||||
|
||||
statusBarItem.button.image = icon;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// OS X 10.9 fallback.
|
||||
// TODO: It would be better to set this size dynamically, like we do for 10.10+.
|
||||
icon.size = NSMakeSize(16, 16);
|
||||
statusBarItem.image = icon;
|
||||
}
|
||||
} else {
|
||||
// If our icon is missing for some reason, fallback to a fermata character (1D110)
|
||||
statusBarItem.button.title = @"𝄐";
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9
|
||||
if ([statusBarItem respondsToSelector:@selector(button)]) {
|
||||
statusBarItem.button.title = @"𝄐";
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
statusBarItem.title = @"𝄐";
|
||||
}
|
||||
}
|
||||
|
||||
// Set the main menu
|
||||
|
||||
@@ -66,7 +66,7 @@ static float const kSlidersSnapWithin = 5;
|
||||
[[NSWorkspace sharedWorkspace] removeObserver:self forKeyPath:@"runningApplications" context:nil];
|
||||
}
|
||||
|
||||
- (void) insertMenuItemsForApps:(NSArray<NSRunningApplication*>*)apps {
|
||||
- (void) insertMenuItemsForApps:(BGMGeneric(NSArray, NSRunningApplication*)*)apps {
|
||||
NSAssert([NSThread isMainThread], @"insertMenuItemsForApps is not thread safe");
|
||||
|
||||
#ifndef NS_BLOCK_ASSERTIONS // If assertions are enabled
|
||||
@@ -127,7 +127,7 @@ static float const kSlidersSnapWithin = 5;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void) removeMenuItemsForApps:(NSArray<NSRunningApplication*>*)apps {
|
||||
- (void) removeMenuItemsForApps:(BGMGeneric(NSArray, NSRunningApplication*)*)apps {
|
||||
NSAssert([NSThread isMainThread], @"removeMenuItemsForApps is not thread safe");
|
||||
|
||||
NSInteger firstItemIndex = [bgmMenu indexOfItemWithTag:kAppVolumesMenuItemTag] + 1;
|
||||
@@ -188,8 +188,8 @@ static float const kSlidersSnapWithin = 5;
|
||||
|
||||
// KVO callback for the apps currently running on the system. Adds/removes the associated menu items.
|
||||
if ([keyPath isEqualToString:@"runningApplications"]) {
|
||||
NSArray<NSRunningApplication*>* newApps = [change objectForKey:NSKeyValueChangeNewKey];
|
||||
NSArray<NSRunningApplication*>* oldApps = [change objectForKey:NSKeyValueChangeOldKey];
|
||||
BGMGeneric(NSArray, NSRunningApplication*)* newApps = [change objectForKey:NSKeyValueChangeNewKey];
|
||||
BGMGeneric(NSArray, NSRunningApplication*)* oldApps = [change objectForKey:NSKeyValueChangeOldKey];
|
||||
|
||||
int changeKind = [[change valueForKey:NSKeyValueChangeKindKey] intValue];
|
||||
switch (changeKind) {
|
||||
|
||||
@@ -63,7 +63,16 @@ static int const kUnpauseDelayMSecs = 3000;
|
||||
audioDevices = inAudioDevices;
|
||||
wePaused = NO;
|
||||
|
||||
dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0);
|
||||
dispatch_queue_attr_t attr =
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9
|
||||
// Runtime fallback for older versions of OS X.
|
||||
(dispatch_queue_attr_make_with_qos_class != NULL ?
|
||||
dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0) :
|
||||
DISPATCH_QUEUE_SERIAL);
|
||||
#else
|
||||
DISPATCH_QUEUE_SERIAL;
|
||||
#endif
|
||||
|
||||
listenerQueue = dispatch_queue_create("com.bearisdriving.BGM.AutoPauseMusic.Listener", attr);
|
||||
pauseUnpauseMusicQueue = dispatch_queue_create("com.bearisdriving.BGM.AutoPauseMusic.PauseUnpauseMusic", attr);
|
||||
|
||||
@@ -81,7 +90,7 @@ static int const kUnpauseDelayMSecs = 3000;
|
||||
// To avoid retain cycle
|
||||
__unsafe_unretained BGMAutoPauseMusic* weakSelf = self;
|
||||
|
||||
listenerBlock = ^(UInt32 inNumberAddresses, const AudioObjectPropertyAddress * _Nonnull inAddresses) {
|
||||
listenerBlock = ^(UInt32 inNumberAddresses, const AudioObjectPropertyAddress * __nonnull inAddresses) {
|
||||
// inAddresses "may contain addresses for properties for which the listener is not signed up to receive notifications",
|
||||
// so we have to check them all
|
||||
for (int i = 0; i < inNumberAddresses; i++) {
|
||||
|
||||
@@ -391,8 +391,7 @@ void BGMPlayThrough::StopIfIdle()
|
||||
"queuedAt=", queuedAt);
|
||||
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, waitNsec),
|
||||
dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0),
|
||||
^{
|
||||
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
// Check the BGMPlayThrough instance hasn't been destructed since it queued this block
|
||||
if(mActive)
|
||||
{
|
||||
@@ -484,7 +483,16 @@ OSStatus BGMPlayThrough::BGMDeviceListenerProc(AudioObjectID inObjectID,
|
||||
{
|
||||
// TODO: This should be rare, but we still shouldn't dispatch on the IO thread because it isn't
|
||||
// real-time safe.
|
||||
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
|
||||
dispatch_async(dispatch_get_global_queue(
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9
|
||||
// Runtime fallback for older versions of OS X.
|
||||
(dispatch_queue_attr_make_with_qos_class != NULL ?
|
||||
QOS_CLASS_USER_INTERACTIVE :
|
||||
DISPATCH_QUEUE_PRIORITY_HIGH),
|
||||
#else
|
||||
DISPATCH_QUEUE_PRIORITY_HIGH,
|
||||
#endif
|
||||
0), ^{
|
||||
if(refCon->mActive)
|
||||
{
|
||||
DebugMsg("BGMPlayThrough::BGMDeviceListenerProc: Handling "
|
||||
@@ -502,7 +510,16 @@ OSStatus BGMPlayThrough::BGMDeviceListenerProc(AudioObjectID inObjectID,
|
||||
"kAudioDeviceCustomPropertyDeviceIsRunningSomewhereOtherThanBGMApp notification");
|
||||
|
||||
// These notifications don't need to be handled quickly, so we can always dispatch.
|
||||
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
|
||||
dispatch_async(dispatch_get_global_queue(
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9
|
||||
// Runtime fallback for older versions of OS X.
|
||||
(dispatch_queue_attr_make_with_qos_class != NULL ?
|
||||
QOS_CLASS_USER_INTERACTIVE :
|
||||
DISPATCH_QUEUE_PRIORITY_HIGH),
|
||||
#else
|
||||
DISPATCH_QUEUE_PRIORITY_HIGH,
|
||||
#endif
|
||||
0), ^{
|
||||
if(refCon->mActive)
|
||||
{
|
||||
refCon->StopIfIdle();
|
||||
|
||||
@@ -62,7 +62,7 @@ typedef BGMMusicPlayerBase<BGMMusicPlayerProtocol> BGMMusicPlayer;
|
||||
+ (id) initWithPIDFromNSNumber:(NSNumber*)pid;
|
||||
+ (id) initWithPIDFromCFNumber:(CFNumberRef)pid;
|
||||
// The pid of each instance of the music player app currently running
|
||||
+ (NSArray<NSNumber*>*) pidsOfRunningInstances;
|
||||
+ (BGMGeneric(NSArray, NSNumber*)*) pidsOfRunningInstances;
|
||||
|
||||
@required
|
||||
// The name of the music player, to be used in the UI
|
||||
@@ -104,7 +104,7 @@ typedef BGMMusicPlayerBase<BGMMusicPlayerProtocol> BGMMusicPlayer;
|
||||
|
||||
// If the music player application is running, the scripting bridge object representing it. Otherwise
|
||||
// nil.
|
||||
@property (readonly) __kindof SBApplication* __nullable sbApplication;
|
||||
@property (readonly) BGMKindOf(SBApplication*) __nullable sbApplication;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ static BGMMusicPlayer* sSelectedMusicPlayer;
|
||||
|
||||
void (^createSBApplication)(void) = ^{
|
||||
sbApplication = [SBApplication applicationWithBundleIdentifier:bundleID];
|
||||
sbApplication.delegate = self;
|
||||
((SBApplication*)sbApplication).delegate = self;
|
||||
};
|
||||
|
||||
BOOL (^isAboutThisMusicPlayer)(NSNotification*) = ^(NSNotification* note){
|
||||
|
||||
@@ -25,7 +25,12 @@
|
||||
#import "BGMVLC.h"
|
||||
|
||||
// Auto-generated Scripting Bridge header
|
||||
#import "VLC.h"
|
||||
#if __has_feature(objc_generics)
|
||||
// According to "man sdp", generics is required by headers generated for 10.11+ but not for headers generated for 10.10.
|
||||
#import "VLC.h"
|
||||
#else
|
||||
#import "VLC_10.9.h"
|
||||
#endif
|
||||
|
||||
// PublicUtility Includes
|
||||
#undef CoreAudio_ThreadStampMessages
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* VLC_10.9.h
|
||||
*
|
||||
* Generated with
|
||||
* sdef /Applications/VLC.app | sdp -fh -V 10.9 --basename VLC
|
||||
*/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <ScriptingBridge/ScriptingBridge.h>
|
||||
|
||||
|
||||
@class VLCItem, VLCApplication, VLCColor, VLCDocument, VLCWindow, VLCAttributeRun, VLCCharacter, VLCParagraph, VLCText, VLCAttachment, VLCWord, VLCPrintSettings;
|
||||
|
||||
enum VLCSavo {
|
||||
VLCSavoAsk = 'ask ' /* Ask the user whether or not to save the file. */,
|
||||
VLCSavoNo = 'no ' /* Do not save the file. */,
|
||||
VLCSavoYes = 'yes ' /* Save the file. */
|
||||
};
|
||||
typedef enum VLCSavo VLCSavo;
|
||||
|
||||
enum VLCEnum {
|
||||
VLCEnumStandard = 'lwst' /* Standard PostScript error handling */,
|
||||
VLCEnumDetailed = 'lwdt' /* print a detailed report of PostScript errors */
|
||||
};
|
||||
typedef enum VLCEnum VLCEnum;
|
||||
|
||||
@protocol VLCGenericMethods
|
||||
|
||||
- (void) closeSaving:(VLCSavo)saving savingIn:(NSURL *)savingIn; // Close an object.
|
||||
- (void) delete; // Delete an object.
|
||||
- (void) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy object(s) and put the copies at a new location.
|
||||
- (BOOL) exists; // Verify if an object exists.
|
||||
- (void) moveTo:(SBObject *)to; // Move object(s) to a new location.
|
||||
- (void) saveAs:(NSString *)as in:(NSURL *)in_; // Save an object.
|
||||
- (void) fullscreen; // Toggle between fullscreen and windowed mode.
|
||||
- (void) GetURL; // Get a URL
|
||||
- (void) mute; // Mute the audio
|
||||
- (void) next; // Go to the next item in the playlist or the next chapter in the DVD/VCD.
|
||||
- (void) OpenURL; // Open a URL
|
||||
- (void) play; // Start playing the current playlistitem or pause it when it is already playing.
|
||||
- (void) previous; // Go to the previous item in the playlist or the previous chapter in the DVD/VCD.
|
||||
- (void) stepBackward; // Step the current playlist item backward the specified step width (default is 2) (1=extraShort, 2=short, 3=medium, 4=long).
|
||||
- (void) stepForward; // Step the current playlist item forward the specified step width (default is 2) (1=extraShort, 2=short, 3=medium, 4=long).
|
||||
- (void) stop; // Stop playing the current playlistitem
|
||||
- (void) volumeDown; // Bring the volume down by one step. There are 32 steps from 0 to 400% volume.
|
||||
- (void) volumeUp; // Bring the volume up by one step. There are 32 steps from 0 to 400% volume.
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Standard Suite
|
||||
*/
|
||||
|
||||
// A scriptable object.
|
||||
@interface VLCItem : SBObject <VLCGenericMethods>
|
||||
|
||||
@property (copy) NSDictionary *properties; // All of the object's properties.
|
||||
|
||||
|
||||
@end
|
||||
|
||||
// An application's top level scripting object.
|
||||
@interface VLCApplication : SBApplication
|
||||
|
||||
- (SBElementArray *) documents;
|
||||
- (SBElementArray *) windows;
|
||||
|
||||
@property (readonly) BOOL frontmost; // Is this the frontmost (active) application?
|
||||
@property (copy, readonly) NSString *name; // The name of the application.
|
||||
@property (copy, readonly) NSString *version; // The version of the application.
|
||||
|
||||
- (VLCDocument *) open:(NSURL *)x; // Open an object.
|
||||
- (void) print:(NSURL *)x printDialog:(BOOL)printDialog withProperties:(VLCPrintSettings *)withProperties; // Print an object.
|
||||
- (void) quitSaving:(VLCSavo)saving; // Quit an application.
|
||||
|
||||
@end
|
||||
|
||||
// A color.
|
||||
@interface VLCColor : VLCItem
|
||||
|
||||
|
||||
@end
|
||||
|
||||
// A document.
|
||||
@interface VLCDocument : VLCItem
|
||||
|
||||
@property (readonly) BOOL modified; // Has the document been modified since the last save?
|
||||
@property (copy) NSString *name; // The document's name.
|
||||
@property (copy) NSString *path; // The document's path.
|
||||
|
||||
|
||||
@end
|
||||
|
||||
// A window.
|
||||
@interface VLCWindow : VLCItem
|
||||
|
||||
@property NSRect bounds; // The bounding rectangle of the window.
|
||||
@property (readonly) BOOL closeable; // Whether the window has a close box.
|
||||
@property (copy, readonly) VLCDocument *document; // The document whose contents are being displayed in the window.
|
||||
@property (readonly) BOOL floating; // Whether the window floats.
|
||||
- (NSInteger) id; // The unique identifier of the window.
|
||||
@property NSInteger index; // The index of the window, ordered front to back.
|
||||
@property (readonly) BOOL miniaturizable; // Whether the window can be miniaturized.
|
||||
@property BOOL miniaturized; // Whether the window is currently miniaturized.
|
||||
@property (readonly) BOOL modal; // Whether the window is the application's current modal window.
|
||||
@property (copy) NSString *name; // The full title of the window.
|
||||
@property (readonly) BOOL resizable; // Whether the window can be resized.
|
||||
@property (readonly) BOOL titled; // Whether the window has a title bar.
|
||||
@property BOOL visible; // Whether the window is currently visible.
|
||||
@property (readonly) BOOL zoomable; // Whether the window can be zoomed.
|
||||
@property BOOL zoomed; // Whether the window is currently zoomed.
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Text Suite
|
||||
*/
|
||||
|
||||
// This subdivides the text into chunks that all have the same attributes.
|
||||
@interface VLCAttributeRun : VLCItem
|
||||
|
||||
- (SBElementArray *) attachments;
|
||||
- (SBElementArray *) attributeRuns;
|
||||
- (SBElementArray *) characters;
|
||||
- (SBElementArray *) paragraphs;
|
||||
- (SBElementArray *) words;
|
||||
|
||||
@property (copy) NSColor *color; // The color of the first character.
|
||||
@property (copy) NSString *font; // The name of the font of the first character.
|
||||
@property NSInteger size; // The size in points of the first character.
|
||||
|
||||
|
||||
@end
|
||||
|
||||
// This subdivides the text into characters.
|
||||
@interface VLCCharacter : VLCItem
|
||||
|
||||
- (SBElementArray *) attachments;
|
||||
- (SBElementArray *) attributeRuns;
|
||||
- (SBElementArray *) characters;
|
||||
- (SBElementArray *) paragraphs;
|
||||
- (SBElementArray *) words;
|
||||
|
||||
@property (copy) NSColor *color; // The color of the first character.
|
||||
@property (copy) NSString *font; // The name of the font of the first character.
|
||||
@property NSInteger size; // The size in points of the first character.
|
||||
|
||||
|
||||
@end
|
||||
|
||||
// This subdivides the text into paragraphs.
|
||||
@interface VLCParagraph : VLCItem
|
||||
|
||||
- (SBElementArray *) attachments;
|
||||
- (SBElementArray *) attributeRuns;
|
||||
- (SBElementArray *) characters;
|
||||
- (SBElementArray *) paragraphs;
|
||||
- (SBElementArray *) words;
|
||||
|
||||
@property (copy) NSColor *color; // The color of the first character.
|
||||
@property (copy) NSString *font; // The name of the font of the first character.
|
||||
@property NSInteger size; // The size in points of the first character.
|
||||
|
||||
|
||||
@end
|
||||
|
||||
// Rich (styled) text
|
||||
@interface VLCText : VLCItem
|
||||
|
||||
- (SBElementArray *) attachments;
|
||||
- (SBElementArray *) attributeRuns;
|
||||
- (SBElementArray *) characters;
|
||||
- (SBElementArray *) paragraphs;
|
||||
- (SBElementArray *) words;
|
||||
|
||||
@property (copy) NSColor *color; // The color of the first character.
|
||||
@property (copy) NSString *font; // The name of the font of the first character.
|
||||
@property NSInteger size; // The size in points of the first character.
|
||||
|
||||
|
||||
@end
|
||||
|
||||
// Represents an inline text attachment. This class is used mainly for make commands.
|
||||
@interface VLCAttachment : VLCText
|
||||
|
||||
@property (copy) NSString *fileName; // The path to the file for the attachment
|
||||
|
||||
|
||||
@end
|
||||
|
||||
// This subdivides the text into words.
|
||||
@interface VLCWord : VLCItem
|
||||
|
||||
- (SBElementArray *) attachments;
|
||||
- (SBElementArray *) attributeRuns;
|
||||
- (SBElementArray *) characters;
|
||||
- (SBElementArray *) paragraphs;
|
||||
- (SBElementArray *) words;
|
||||
|
||||
@property (copy) NSColor *color; // The color of the first character.
|
||||
@property (copy) NSString *font; // The name of the font of the first character.
|
||||
@property NSInteger size; // The size in points of the first character.
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VLC suite
|
||||
*/
|
||||
|
||||
// VLC's top level scripting object
|
||||
@interface VLCApplication (VLCSuite)
|
||||
|
||||
@property NSInteger audioVolume; // The volume of the current playlist item from 0 to 4, where 4 is 400%
|
||||
@property NSInteger currentTime; // The current time of the current playlist item in seconds.
|
||||
@property (readonly) NSInteger durationOfCurrentItem; // The duration of the current playlist item in seconds.
|
||||
@property BOOL fullscreenMode; // indicates wheter fullscreen is enabled or not
|
||||
@property (readonly) BOOL muted; // Is VLC currently muted?
|
||||
@property (copy, readonly) NSString *nameOfCurrentItem; // Name of the current playlist item.
|
||||
@property (copy, readonly) NSString *pathOfCurrentItem; // Path to the current playlist item.
|
||||
@property (readonly) BOOL playing; // Is VLC playing an item?
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Type Definitions
|
||||
*/
|
||||
|
||||
@interface VLCPrintSettings : SBObject <VLCGenericMethods>
|
||||
|
||||
@property NSInteger copies; // the number of copies of a document to be printed
|
||||
@property BOOL collating; // Should printed copies be collated?
|
||||
@property NSInteger startingPage; // the first page of the document to be printed
|
||||
@property NSInteger endingPage; // the last page of the document to be printed
|
||||
@property NSInteger pagesAcross; // number of logical pages laid across a physical page
|
||||
@property NSInteger pagesDown; // number of logical pages laid out down a physical page
|
||||
@property (copy) NSDate *requestedPrintTime; // the time at which the desktop printer should print the document
|
||||
@property VLCEnum errorHandling; // how errors are handled
|
||||
@property (copy) NSString *faxNumber; // for fax number
|
||||
@property (copy) NSString *targetPrinter; // for target printer
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -36,7 +36,7 @@ static NSInteger const kPrefsMenuAutoPauseHeaderTag = 1;
|
||||
BGMAudioDeviceManager* audioDevices;
|
||||
NSMenuItem* toggleAutoPauseMusicMenuItem;
|
||||
NSMenu* prefsMenu;
|
||||
NSArray<NSMenuItem*>* musicPlayerMenuItems;
|
||||
BGMGeneric(NSArray, NSMenuItem*)* musicPlayerMenuItems;
|
||||
}
|
||||
|
||||
- (id) initWithPreferencesMenu:(NSMenu*)inPrefsMenu
|
||||
@@ -94,7 +94,7 @@ static NSInteger const kPrefsMenuAutoPauseHeaderTag = 1;
|
||||
if (selectedPID != NULL &&
|
||||
[mpClass respondsToSelector:@selector(pidsOfRunningInstances)] &&
|
||||
[mpClass respondsToSelector:@selector(initWithPIDFromNSNumber:)]) {
|
||||
NSArray<NSNumber*>* mpPIDs = [mpClass pidsOfRunningInstances];
|
||||
BGMGeneric(NSArray, NSNumber*)* mpPIDs = [mpClass pidsOfRunningInstances];
|
||||
for (NSNumber* mpPID in mpPIDs) {
|
||||
if (CFEqual((__bridge CFNumberRef)mpPID, selectedPID)) {
|
||||
DebugMsg("BGMAutoPauseMusicPrefs::initSelectedMusicPlayer: Selected music player on driver was %s (found by pid)",
|
||||
|
||||
@@ -33,7 +33,7 @@ static NSInteger const kOutputDeviceMenuItemTag = 2;
|
||||
|
||||
@implementation BGMOutputDevicePrefs {
|
||||
BGMAudioDeviceManager* audioDevices;
|
||||
NSMutableArray<NSMenuItem*>* outputDeviceMenuItems;
|
||||
BGMGeneric(NSMutableArray, NSMenuItem*)* outputDeviceMenuItems;
|
||||
}
|
||||
|
||||
- (id) initWithAudioDevices:(BGMAudioDeviceManager*)inAudioDevices {
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
#pragma clang assume_nonnull begin
|
||||
|
||||
@interface BGMPreferencesMenu : NSObject <NSMenuDelegate>
|
||||
|
||||
@@ -41,5 +41,5 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
#pragma clang assume_nonnull end
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#import "BGMOutputDevicePrefs.h"
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
#pragma clang assume_nonnull begin
|
||||
|
||||
// Interface Builder tags
|
||||
static NSInteger const kToggleAutoPauseMusicMenuItemTag = 2;
|
||||
@@ -127,5 +127,5 @@ static NSInteger const kAboutPanelCopyrightLabelTag = 2;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
#pragma clang assume_nonnull end
|
||||
|
||||
|
||||
@@ -530,13 +530,14 @@
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREFIX_HEADER = ../SharedSource/BGMPrefixHeader.pch;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"CoreAudio_Debug=1",
|
||||
"CoreAudio_UseSysLog=1",
|
||||
"CoreAudio_StopOnAssert=1",
|
||||
);
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
@@ -549,6 +550,7 @@
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -563,13 +565,14 @@
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = s;
|
||||
GCC_PREFIX_HEADER = ../SharedSource/BGMPrefixHeader.pch;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=0",
|
||||
"CoreAudio_Debug=0",
|
||||
"CoreAudio_UseSysLog=1",
|
||||
"CoreAudio_StopOnAssert=0",
|
||||
);
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
@@ -581,6 +584,7 @@
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// This file is part of Background Music.
|
||||
//
|
||||
// Background Music is free software: you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation, either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// Background Music is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Background Music. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//
|
||||
// BGMPrefixHeader.pch
|
||||
// SharedSource
|
||||
//
|
||||
// Copyright © 2016 Kyle Neideck
|
||||
//
|
||||
|
||||
#ifndef __SharedSource__BGMPrefixHeader__
|
||||
#define __SharedSource__BGMPrefixHeader__
|
||||
|
||||
#if !(__has_feature(nullability))
|
||||
#define __nullable
|
||||
#define __nonnull
|
||||
#endif
|
||||
|
||||
#if __has_feature(objc_generics)
|
||||
#define BGMGeneric(typename, ...) typename<__VA_ARGS__>
|
||||
#else
|
||||
#define BGMGeneric(typename, ...) typename
|
||||
#endif
|
||||
|
||||
#if __has_feature(objc_kindof)
|
||||
#define BGMKindOf(typename) __kindof typename
|
||||
#else
|
||||
#define BGMKindOf(typename) id
|
||||
#endif
|
||||
|
||||
#endif /* __SharedSource__BGMPrefixHeader__ */
|
||||
|
||||
+21
-3
@@ -56,6 +56,9 @@ DRIVER_DIR="Background Music Device.driver"
|
||||
XPC_HELPER_PATH="$(BGMApp/BGMXPCHelper/safe_install_dir.sh)"
|
||||
XPC_HELPER_DIR="BGMXPCHelper.xpc"
|
||||
|
||||
NIB_PATH="Contents/Resources/Base.lproj"
|
||||
NIB_NAME="MainMenu.nib"
|
||||
|
||||
bold_face() {
|
||||
echo $(tput bold)$*$(tput sgr0)
|
||||
}
|
||||
@@ -187,7 +190,7 @@ show_spinner
|
||||
# BGMXPCHelper
|
||||
|
||||
echo "[2/3] Installing $(bold_face ${XPC_HELPER_DIR}) to $(bold_face ${XPC_HELPER_PATH})." \
|
||||
| tee -a ${LOG_FILE}
|
||||
| tee -a "${LOG_FILE}"
|
||||
|
||||
(set +e;
|
||||
sudo xcodebuild -project BGMApp/BGMApp.xcodeproj \
|
||||
@@ -203,7 +206,7 @@ show_spinner
|
||||
# BGMApp
|
||||
|
||||
echo "[3/3] Installing $(bold_face ${APP_DIR}) to $(bold_face ${APP_PATH})." \
|
||||
| tee -a ${LOG_FILE}
|
||||
| tee -a "${LOG_FILE}"
|
||||
|
||||
(set +e;
|
||||
sudo xcodebuild -project BGMApp/BGMApp.xcodeproj \
|
||||
@@ -221,10 +224,25 @@ show_spinner
|
||||
# same build directory we have to run xcodebuild as root to install BGMApp as well.)
|
||||
sudo chown -R "$(whoami):admin" "${APP_PATH}/${APP_DIR}"
|
||||
|
||||
# For some reason, Xcode 6 doesn't always build the .xib. So we do it ourselves.
|
||||
if ! [[ -e "${APP_PATH}/${APP_DIR}/${NIB_PATH}/${NIB_NAME}" ]]; then
|
||||
echo "${NIB_NAME} is missing from ${APP_PATH}/${APP_DIR}/${NIB_PATH}/${NIB_NAME}. Compiling" \
|
||||
"it with ibtool." >> "${LOG_FILE}"
|
||||
|
||||
IBTOOL=$(xcrun --find ibtool 2>/dev/null || which ibtool)
|
||||
if [[ -x "${IBTOOL}" ]]; then
|
||||
mkdir -p "${APP_PATH}/${APP_DIR}/${NIB_PATH}"
|
||||
"${IBTOOL}" --compile "${APP_PATH}/${APP_DIR}/${NIB_PATH}/${NIB_NAME}" \
|
||||
BGMApp/BGMApp/Base.lproj/MainMenu.xib
|
||||
else
|
||||
echo "ERROR: ibtool not found (or not executable)." | tee -a "${LOG_FILE}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Restart coreaudiod.
|
||||
|
||||
echo "Restarting coreaudiod to load the virtual audio device." \
|
||||
| tee -a ${LOG_FILE}
|
||||
| tee -a "${LOG_FILE}"
|
||||
|
||||
# The extra or-clauses are fallback versions of the command that restarts coreaudiod. Apparently
|
||||
# some of these commands don't work with older versions of launchctl, so I figure there's no harm in
|
||||
|
||||
Reference in New Issue
Block a user