Compare commits
43 Commits
gh-actions
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 3d4e1bff10 | |||
| 1c743053c6 | |||
| de1a9fa413 | |||
| 12a7deb15f | |||
| e6375b0919 | |||
| 029cb2f5f8 | |||
| 2ac8a1afd1 | |||
| 784bb249a9 | |||
| 51e1266532 | |||
| 4b7caeeb54 | |||
| 7e592ebb2b | |||
| 0aea54f0c5 | |||
| 9407ee36d2 | |||
| 9058e3c556 | |||
| a8f4ace099 | |||
| 610f15c556 | |||
| 62174be95e | |||
| 48bdcd1a64 | |||
| cb6f38821e | |||
| b96fcb7a47 | |||
| ad14e1b0a4 | |||
| 61be8bead4 | |||
| 8b2bf56eca | |||
| e655d571e0 | |||
| 9257d50b15 | |||
| 3097f4b621 | |||
| 73f221e423 | |||
| 7d700b3de5 | |||
| 014a6eecc8 | |||
| 2cc3faaebb | |||
| 5000c64084 | |||
| 4fc776e4a6 | |||
| ca3c497940 | |||
| 08837fcdca | |||
| 076514c83a | |||
| 8090f12204 | |||
| bd38207146 | |||
| d92d9e6d29 | |||
| d048287140 | |||
| c89566d212 | |||
| c68e05244c | |||
| 1fdf47cd12 | |||
| 4608f4bbac |
@@ -22,7 +22,7 @@ assignees: ''
|
||||
|
||||
**Versions**
|
||||
> Please complete the following information.
|
||||
- Background Music: [e.g. "0.3.2" or "0.4.0-SNAPSHOT-c0ab98b". `Preferences > About Background Music`]
|
||||
- Background Music: [e.g. "0.4.3" or "0.4.0-SNAPSHOT-c0ab98b". `Preferences > About Background Music`]
|
||||
- macOS: [e.g. "11.3 Beta (20E5172i)" or "Big Sur". ` > About This Mac`]
|
||||
|
||||
**Hardware**
|
||||
@@ -43,8 +43,7 @@ assignees: ''
|
||||
> Tips
|
||||
> (Delete this section before posting.)
|
||||
> - https://github.com/kyleneideck/BackgroundMusic#troubleshooting
|
||||
> - Try the latest SNAPSHOT version from https://github.com/kyleneideck/BackgroundMusic/releases
|
||||
> - Especially if you're using macOS Big Sur.
|
||||
> - If your bug is one of common issues, consider leaving a comment or a +1 (👍) on an existing issue:
|
||||
> - Try the latest SNAPSHOT version from https://github.com/kyleneideck/BackgroundMusic/releases (if it's newer than the latest non-SNAPSHOT release).
|
||||
> - If your bug is one of these common issues, consider leaving a comment or a +1 (👍) on an existing issue:
|
||||
> - Background Music currently only supports audio devices with two channels. Bluetooth devices often only have one.
|
||||
> - Volumes having no effect for certain apps: Microsoft Teams ([workaround](https://github.com/kyleneideck/BackgroundMusic/issues/268#issuecomment-604977210)), Zoom ([workaround](https://github.com/kyleneideck/BackgroundMusic/issues/396#issuecomment-741992157)), Discord ([workaround](https://github.com/kyleneideck/BackgroundMusic/issues/210#issuecomment-507048957), [see also](https://github.com/kyleneideck/BackgroundMusic/issues/267#issuecomment-617327850)), Chrome (sometimes)
|
||||
|
||||
@@ -1443,7 +1443,7 @@
|
||||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CFLAGS = "-fno-omit-frame-pointer";
|
||||
@@ -1553,7 +1553,7 @@
|
||||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CFLAGS = "-fno-omit-frame-pointer";
|
||||
@@ -1635,7 +1635,7 @@
|
||||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
OTHER_CFLAGS = "";
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
@@ -1715,7 +1715,6 @@
|
||||
DEVELOPMENT_TEAM = "";
|
||||
INFOPLIST_FILE = "BGMAppTests/UITests/BGMAppUITests-Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.bearisdriving.BGM.AppUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@@ -1733,7 +1732,6 @@
|
||||
DEVELOPMENT_TEAM = "";
|
||||
INFOPLIST_FILE = "BGMAppTests/UITests/BGMAppUITests-Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.bearisdriving.BGM.AppUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@@ -1752,7 +1750,6 @@
|
||||
DEVELOPMENT_TEAM = "";
|
||||
INFOPLIST_FILE = "BGMAppTests/UITests/BGMAppUITests-Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.bearisdriving.BGM.AppUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
||||
@@ -23,13 +23,11 @@
|
||||
// Sets up and tears down the app.
|
||||
//
|
||||
|
||||
// Local Includes
|
||||
#import "BGMAudioDeviceManager.h"
|
||||
#import "BGMAppVolumesController.h"
|
||||
|
||||
// System Includes
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@class BGMAudioDeviceManager;
|
||||
@class BGMAppVolumesController;
|
||||
|
||||
// Tags for UI elements in MainMenu.xib
|
||||
static NSInteger const kVolumesHeadingMenuItemTag = 3;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
// Local Includes
|
||||
#import "BGM_Utils.h"
|
||||
#import "BGMAppVolumes.h"
|
||||
#import "BGMAppVolumesController.h"
|
||||
#import "BGMAutoPauseMusic.h"
|
||||
#import "BGMAutoPauseMenuItem.h"
|
||||
@@ -234,6 +235,66 @@ static NSString* const kOptShowDockIcon = @"--show-dock-icon";
|
||||
}
|
||||
}
|
||||
|
||||
- (void) menuWillOpen:(NSMenu*)menu {
|
||||
if (@available(macOS 10.16, *)) {
|
||||
// Set menu offset and check for any active menu items
|
||||
float menuOffset = 12.0;
|
||||
for (NSMenuItem* menuItem in self.bgmMenu.itemArray) {
|
||||
if (menuItem.state == NSControlStateValueOn && menuItem.indentationLevel == 0) {
|
||||
menuOffset += 10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Align volume output device and slider
|
||||
for (NSView* subview in self.outputVolumeView.subviews) {
|
||||
CGRect newSubview = subview.frame;
|
||||
newSubview.origin.x = menuOffset;
|
||||
subview.frame = newSubview;
|
||||
}
|
||||
|
||||
// Align system sounds and app volumes
|
||||
double appIconTitleOffset = 0;
|
||||
for (NSMenuItem* menuItem in self.bgmMenu.itemArray) {
|
||||
if (menuItem.view.subviews.count == 7 || menuItem.view.subviews.count == 3) {
|
||||
NSTextField* appTitle;
|
||||
NSImageView* appIcon;
|
||||
|
||||
for (NSView* subview in menuItem.view.subviews) {
|
||||
if (menuItem.view.subviews.count == 3) {
|
||||
// System sounds
|
||||
if ([subview isKindOfClass:[NSTextField class]]) {
|
||||
appTitle = (NSTextField*)subview;
|
||||
}
|
||||
if ([subview isKindOfClass:[NSImageView class]]) {
|
||||
appIcon = (NSImageView*)subview;
|
||||
}
|
||||
} else if (menuItem.view.subviews.count == 7) {
|
||||
// App volumes
|
||||
if ([subview isKindOfClass:[BGMAVM_AppNameLabel class]]) {
|
||||
appTitle = (NSTextField*)subview;
|
||||
}
|
||||
if ([subview isKindOfClass:[BGMAVM_AppIcon class]]) {
|
||||
appIcon = (NSImageView*)subview;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (appIconTitleOffset == 0) {
|
||||
appIconTitleOffset = appTitle.frame.origin.x - appIcon.frame.origin.x;
|
||||
}
|
||||
|
||||
CGRect newAppIcon = appIcon.frame;
|
||||
newAppIcon.origin.x = menuOffset;
|
||||
appIcon.frame = newAppIcon;
|
||||
CGRect newAppTitle = appTitle.frame;
|
||||
newAppTitle.origin.x = menuOffset + appIconTitleOffset;
|
||||
appTitle.frame = newAppTitle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setUpMainMenu {
|
||||
autoPauseMenuItem =
|
||||
[[BGMAutoPauseMenuItem alloc] initWithMenuItem:self.autoPauseMenuItemUnwrapped
|
||||
|
||||
@@ -57,6 +57,8 @@ BGMAudioDevice::~BGMAudioDevice()
|
||||
bool BGMAudioDevice::CanBeOutputDeviceInBGMApp() const
|
||||
{
|
||||
CFStringRef uid = CopyDeviceUID();
|
||||
assert(uid != nullptr);
|
||||
|
||||
bool isNullDevice = CFEqual(uid, CFSTR(kBGMNullDeviceUID));
|
||||
CFRelease(uid);
|
||||
|
||||
@@ -340,6 +342,9 @@ bool BGMAudioDevice::IsBGMDevice(bool inIncludeUISoundsInstance) const
|
||||
{
|
||||
// Check the device's UID to see whether it's BGMDevice.
|
||||
CFStringRef uid = CopyDeviceUID();
|
||||
if (uid == nullptr) {
|
||||
return isBGMDevice;
|
||||
}
|
||||
|
||||
isBGMDevice =
|
||||
CFEqual(uid, CFSTR(kBGMDeviceUID)) ||
|
||||
|
||||
@@ -241,7 +241,11 @@ BGMBackgroundMusicDevice::ResponsibleBundleIDsOf(CACFString inParentBundleID)
|
||||
// Skype
|
||||
{ "com.skype.skype", { "com.skype.skype.Helper" } },
|
||||
// Google Chrome
|
||||
{ "com.google.Chrome", { "com.google.Chrome.helper" } }
|
||||
{ "com.google.Chrome", { "com.google.Chrome.helper" } },
|
||||
// Microsoft Edge
|
||||
{ "com.microsoft.edgemac", { "com.microsoft.edgemac.helper" } },
|
||||
// Arc
|
||||
{ "company.thebrowser.Browser", { "company.thebrowser.browser.helper" } }
|
||||
};
|
||||
|
||||
// Parallels' VM "dock helper" apps have bundle IDs like
|
||||
|
||||
@@ -894,7 +894,7 @@ void BGMPlayThrough::HandleBGMDeviceIsRunning(BGMPlayThrough* refCon)
|
||||
|
||||
DebugMsg("BGMPlayThrough::HandleBGMDeviceIsRunning: "
|
||||
"BGMDevice is %srunning somewhere other than BGMApp",
|
||||
isRunningSomewhereOtherThanBGMApp ? "" : " not");
|
||||
isRunningSomewhereOtherThanBGMApp ? "" : "not ");
|
||||
|
||||
if(isRunningSomewhereOtherThanBGMApp)
|
||||
{
|
||||
@@ -933,9 +933,8 @@ void BGMPlayThrough::HandleBGMDeviceIsRunningSomewhereOtherThanBGMApp(BGMPlay
|
||||
// static
|
||||
bool BGMPlayThrough::IsRunningSomewhereOtherThanBGMApp(const BGMAudioDevice& inBGMDevice)
|
||||
{
|
||||
return CFBooleanGetValue(
|
||||
static_cast<CFBooleanRef>(
|
||||
inBGMDevice.GetPropertyData_CFType(kBGMRunningSomewhereOtherThanBGMAppAddress)));
|
||||
auto type = inBGMDevice.GetPropertyData_CFType(kBGMRunningSomewhereOtherThanBGMAppAddress);
|
||||
return type && CFBooleanGetValue(static_cast<CFBooleanRef>(type));
|
||||
}
|
||||
|
||||
#pragma mark IOProcs
|
||||
|
||||
@@ -125,10 +125,17 @@ static CGFloat const kVolumeIconAdditionalVerticalPadding = 0.075;
|
||||
- (void) initIcons {
|
||||
// Load the icons.
|
||||
fermataIcon = [NSImage imageNamed:@"FermataIcon"];
|
||||
volumeIcon0SoundWaves = [NSImage imageNamed:@"Volume0"];
|
||||
volumeIcon1SoundWave = [NSImage imageNamed:@"Volume1"];
|
||||
volumeIcon2SoundWaves = [NSImage imageNamed:@"Volume2"];
|
||||
volumeIcon3SoundWaves = [NSImage imageNamed:@"Volume3"];
|
||||
if (@available(macOS 11.0, *)) {
|
||||
volumeIcon0SoundWaves = [NSImage imageWithSystemSymbolName:@"speaker.fill" accessibilityDescription:nil];
|
||||
volumeIcon1SoundWave = [NSImage imageWithSystemSymbolName:@"speaker.wave.1.fill" accessibilityDescription:nil];
|
||||
volumeIcon2SoundWaves = [NSImage imageWithSystemSymbolName:@"speaker.wave.2.fill" accessibilityDescription:nil];
|
||||
volumeIcon3SoundWaves = [NSImage imageWithSystemSymbolName:@"speaker.wave.3.fill" accessibilityDescription:nil];
|
||||
} else {
|
||||
volumeIcon0SoundWaves = [NSImage imageNamed:@"Volume0"];
|
||||
volumeIcon1SoundWave = [NSImage imageNamed:@"Volume1"];
|
||||
volumeIcon2SoundWaves = [NSImage imageNamed:@"Volume2"];
|
||||
volumeIcon3SoundWaves = [NSImage imageNamed:@"Volume3"];
|
||||
}
|
||||
|
||||
// Set the icons' sizes.
|
||||
NSRect statusBarItemFrame;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22505"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -85,7 +85,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="269" height="47"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField identifier="AppName" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Xmd-bg-huG" customClass="BGMAVM_AppNameLabel">
|
||||
<textField identifier="AppName" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Xmd-bg-huG" customClass="BGMAVM_AppNameLabel">
|
||||
<rect key="frame" x="42" y="28" width="115" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="truncatingTail" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="App name here" usesSingleLineMode="YES" id="ZHF-ZW-Oqg">
|
||||
@@ -102,7 +102,7 @@
|
||||
<slider verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="I1l-Ci-4md" customClass="BGMAVM_VolumeSlider">
|
||||
<rect key="frame" x="163" y="27" width="74" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<sliderCell key="cell" controlSize="small" continuous="YES" state="on" alignment="left" maxValue="100" doubleValue="50" tickMarkPosition="above" sliderType="linear" id="Jmg-df-9Xl"/>
|
||||
<sliderCell key="cell" controlSize="mini" continuous="YES" state="on" alignment="left" maxValue="100" doubleValue="50" tickMarkPosition="above" sliderType="linear" id="Jmg-df-9Xl"/>
|
||||
<accessibility description="Volume"/>
|
||||
</slider>
|
||||
<slider toolTip="Pan" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2mh-uO-kOV" customClass="BGMAVM_PanSlider">
|
||||
@@ -111,7 +111,7 @@
|
||||
<sliderCell key="cell" controlSize="mini" continuous="YES" state="on" alignment="left" minValue="-100" maxValue="100" tickMarkPosition="below" numberOfTickMarks="1" sliderType="linear" id="ccM-Mt-93g"/>
|
||||
<accessibility description="Pan"/>
|
||||
</slider>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" tag="1" springLoaded="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vTG-n6-GxY" customClass="BGMAVM_ShowMoreControlsButton">
|
||||
<button tag="1" springLoaded="YES" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vTG-n6-GxY" customClass="BGMAVM_ShowMoreControlsButton">
|
||||
<rect key="frame" x="243" y="27" width="16" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<contentFilters>
|
||||
@@ -127,7 +127,7 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField identifier="PanLeft" toolTip="Pan" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9jc-9i-jw2">
|
||||
<textField identifier="PanLeft" toolTip="Pan" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9jc-9i-jw2">
|
||||
<rect key="frame" x="162" y="-1" width="12" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="L" id="hgE-7A-bez">
|
||||
@@ -136,7 +136,7 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="PanRight" toolTip="Pan" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1lZ-hX-6Kl">
|
||||
<textField identifier="PanRight" toolTip="Pan" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1lZ-hX-6Kl">
|
||||
<rect key="frame" x="228" y="-1" width="12" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="R" id="lzr-NO-0Na">
|
||||
@@ -148,16 +148,16 @@
|
||||
</subviews>
|
||||
<point key="canvasLocation" x="117" y="-45"/>
|
||||
</customView>
|
||||
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" hidesOnDeactivate="YES" visibleAtLaunch="NO" animationBehavior="default" id="Cf4-3V-gl1" customClass="NSPanel">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" utility="YES"/>
|
||||
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" hidesOnDeactivate="YES" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="Cf4-3V-gl1" customClass="NSPanel">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" utility="YES" nonactivatingPanel="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" topStrut="YES"/>
|
||||
<rect key="contentRect" x="248" y="350" width="1002" height="335"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1512" height="920"/>
|
||||
<view key="contentView" id="HlB-hX-Y0Y">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1002" height="335"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="r51-dd-LGP">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="r51-dd-LGP">
|
||||
<rect key="frame" x="71" y="125" width="240" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Background Music" id="Dw2-nu-eBQ">
|
||||
@@ -166,16 +166,16 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" tag="1" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ekc-h0-I43">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" tag="1" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ekc-h0-I43">
|
||||
<rect key="frame" x="71" y="100" width="240" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Version 0.4.0" id="FDH-7l-wFf">
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Version 0.4.3" id="FDH-7l-wFf">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="L5P-Lw-aCd">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="L5P-Lw-aCd">
|
||||
<rect key="frame" x="413" y="298" width="270" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Licensed under GPL v2 or any later version." id="ETh-En-bzX">
|
||||
@@ -188,7 +188,7 @@
|
||||
<rect key="frame" x="383" y="93" width="5" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" tag="3" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nx6-kQ-N8Z" customClass="BGMLinkField">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" tag="3" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nx6-kQ-N8Z" customClass="BGMLinkField">
|
||||
<rect key="frame" x="36" y="50" width="310" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" tag="3" title="https://github.com/kyleneideck/BackgroundMusic" placeholderString="" id="VOb-5X-o3R">
|
||||
@@ -216,11 +216,11 @@
|
||||
<scrollView fixedFrame="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eqz-ap-PAC">
|
||||
<rect key="frame" x="415" y="45" width="567" height="245"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" id="Cdb-RA-YK0">
|
||||
<clipView key="contentView" drawsBackground="NO" id="Cdb-RA-YK0">
|
||||
<rect key="frame" x="1" y="1" width="565" height="243"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textView ambiguous="YES" editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" id="LSG-PF-cl8">
|
||||
<textView editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" id="LSG-PF-cl8">
|
||||
<rect key="frame" x="-6" y="0.0" width="577" height="243"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -243,7 +243,7 @@
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6qu-yI-r00">
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6qu-yI-r00">
|
||||
<rect key="frame" x="413" y="20" width="203" height="11"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="The AirPlay Logo is a trademark of Apple Inc." id="lx7-k3-q16">
|
||||
@@ -252,20 +252,29 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" tag="2" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Vy4-dv-jQB">
|
||||
<rect key="frame" x="18" y="75" width="346" height="17"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" tag="2" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Vy4-dv-jQB">
|
||||
<rect key="frame" x="18" y="75" width="155" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Copyright © 2016-2021 Background Music contributors" placeholderString="" id="ctF-95-uVu">
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Copyright © 2016-2024" placeholderString="" id="ctF-95-uVu">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" tag="4" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tRj-QC-GuQ" customClass="BGMLinkField">
|
||||
<rect key="frame" x="168" y="75" width="194" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" alignment="left" tag="3" title="Background Music contributors" placeholderString="" allowsEditingTextAttributes="YES" usesSingleLineMode="YES" id="UC2-MX-fML">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" red="0.20000000000000001" green="0.40000000000000002" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-200" y="232.5"/>
|
||||
</window>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" allowsCharacterPickerTouchBarItem="YES" id="IoN-sN-cCx">
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" allowsCharacterPickerTouchBarItem="YES" id="IoN-sN-cCx">
|
||||
<rect key="frame" x="0.0" y="0.0" width="471" height="180"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" drawsBackground="YES" id="Ay8-8n-FHi">
|
||||
@@ -284,10 +293,10 @@
|
||||
<slider identifier="Output Volume" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9Ru-Sc-dqC" userLabel="Output Volume Slider">
|
||||
<rect key="frame" x="20" y="4" width="220" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="1" tickMarkPosition="above" sliderType="linear" id="MzM-fe-nKb"/>
|
||||
<sliderCell key="cell" controlSize="small" continuous="YES" state="on" alignment="left" maxValue="1" tickMarkPosition="above" sliderType="linear" id="MzM-fe-nKb"/>
|
||||
<accessibility description="Output Volume" help="Sets the volume of your audio output device." identifier="Output Volume"/>
|
||||
</slider>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wfC-C6-SLv">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wfC-C6-SLv">
|
||||
<rect key="frame" x="20" y="25" width="226" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Volume" id="60O-ju-B5C">
|
||||
@@ -306,10 +315,10 @@
|
||||
<slider identifier="System Sounds Volume" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gyd-WV-2ju" userLabel="Output Volume Slider">
|
||||
<rect key="frame" x="163" y="0.0" width="74" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<sliderCell key="cell" controlSize="small" continuous="YES" state="on" alignment="left" maxValue="1" doubleValue="1" tickMarkPosition="above" sliderType="linear" id="VDn-d8-XK3"/>
|
||||
<sliderCell key="cell" controlSize="mini" continuous="YES" state="on" alignment="left" maxValue="1" doubleValue="1" tickMarkPosition="above" sliderType="linear" id="VDn-d8-XK3"/>
|
||||
<accessibility description="System Sounds Volume" help="Volume of alerts, notification sounds, etc. Usually short. Can be played by any app."/>
|
||||
</slider>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="iKs-df-Hp6">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="iKs-df-Hp6">
|
||||
<rect key="frame" x="42" y="1" width="86" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="System Sounds" id="ATK-L8-s8z">
|
||||
@@ -333,53 +342,54 @@
|
||||
<image name="buttonCell:IXo-C7-3uE:image" width="1" height="1">
|
||||
<mutableData key="keyedArchiveRepresentation">
|
||||
YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05T
|
||||
S2V5ZWRBcmNoaXZlctEICVRyb290gAGuCwwZGh8UJCgpMDM2PD9VJG51bGzWDQ4PEBESExQVFhcYVk5T
|
||||
S2V5ZWRBcmNoaXZlctEICVRyb290gAGuCwwZGh8UJCkqMTQ3PUBVJG51bGzWDQ4PEBESExQVFhcYVk5T
|
||||
U2l6ZV5OU1Jlc2l6aW5nTW9kZVYkY2xhc3NcTlNJbWFnZUZsYWdzVk5TUmVwc1dOU0NvbG9ygAIQAIAN
|
||||
EiDDAACAA4ALVnsxLCAxfdIbDxweWk5TLm9iamVjdHOhHYAEgArSGw8gI6IhIoAFgAaACdIlDyYnXxAU
|
||||
TlNUSUZGUmVwcmVzZW50YXRpb26AB4AITxEIxE1NACoAAAAKAAAAEAEAAAMAAAABAAEAAAEBAAMAAAAB
|
||||
AAEAAAECAAMAAAACAAgACAEDAAMAAAABAAEAAAEGAAMAAAABAAEAAAEKAAMAAAABAAEAAAERAAQAAAAB
|
||||
AAAACAESAAMAAAABAAEAAAEVAAMAAAABAAIAAAEWAAMAAAABAAEAAAEXAAQAAAABAAAAAgEcAAMAAAAB
|
||||
AAEAAAEoAAMAAAABAAIAAAFSAAMAAAABAAEAAAFTAAMAAAACAAEAAYdzAAcAAAf0AAAA0AAAAAAAAAf0
|
||||
YXBwbAIgAABtbnRyR1JBWVhZWiAH0AACAA4ADAAAAABhY3NwQVBQTAAAAABub25lAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAVkZXNjAAAAwAAAAG9kc2NtAAABMAAABmZjcHJ0AAAHmAAAADh3dHB0AAAH0AAAABRrVFJD
|
||||
AAAH5AAAAA5kZXNjAAAAAAAAABVHZW5lcmljIEdyYXkgUHJvZmlsZQAAAAAAAAAAAAAAFUdlbmVyaWMg
|
||||
R3JheSBQcm9maWxlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
bWx1YwAAAAAAAAAfAAAADHNrU0sAAAAqAAABhGVuVVMAAAAoAAABrmNhRVMAAAAsAAAB1nZpVk4AAAAs
|
||||
AAACAnB0QlIAAAAqAAACLnVrVUEAAAAsAAACWGZyRlUAAAAqAAAChGh1SFUAAAAuAAACrnpoVFcAAAAQ
|
||||
AAAC3G5iTk8AAAAsAAAC7GtvS1IAAAAYAAADGGNzQ1oAAAAkAAADMGhlSUwAAAAgAAADVHJvUk8AAAAk
|
||||
AAADdGRlREUAAAA6AAADmGl0SVQAAAAuAAAD0nN2U0UAAAAuAAAEAHpoQ04AAAAQAAAELmphSlAAAAAW
|
||||
AAAEPmVsR1IAAAAkAAAEVHB0UE8AAAA4AAAEeG5sTkwAAAAqAAAEsGVzRVMAAAAoAAAE2nRoVEgAAAAk
|
||||
AAAFAnRyVFIAAAAiAAAFJmZpRkkAAAAsAAAFSGhySFIAAAA6AAAFdHBsUEwAAAA2AAAFrnJ1UlUAAAAm
|
||||
AAAF5GFyRUcAAAAoAAAGCmRhREsAAAA0AAAGMgBWAWEAZQBvAGIAZQBjAG4A/QAgAHMAaQB2AP0AIABw
|
||||
AHIAbwBmAGkAbABHAGUAbgBlAHIAaQBjACAARwByAGEAeQAgAFAAcgBvAGYAaQBsAGUAUABlAHIAZgBp
|
||||
AGwAIABkAGUAIABnAHIAaQBzACAAZwBlAG4A6AByAGkAYwBDHqUAdQAgAGgA7ABuAGgAIABNAOAAdQAg
|
||||
AHgA4QBtACAAQwBoAHUAbgBnAFAAZQByAGYAaQBsACAAQwBpAG4AegBhACAARwBlAG4A6QByAGkAYwBv
|
||||
BBcEMAQzBDAEOwRMBD0EOAQ5ACAEPwRABD4ERAQwBDkEOwAgAEcAcgBhAHkAUAByAG8AZgBpAGwAIABn
|
||||
AOkAbgDpAHIAaQBxAHUAZQAgAGcAcgBpAHMAwQBsAHQAYQBsAOEAbgBvAHMAIABzAHoA/AByAGsAZQAg
|
||||
AHAAcgBvAGYAaQBskBp1KHBwlo6Ccl9pY8+P8ABHAGUAbgBlAHIAaQBzAGsAIABnAHIA5QB0AG8AbgBl
|
||||
AHAAcgBvAGYAaQBsx3y8GAAgAEcAcgBhAHkAINUEuFzTDMd8AE8AYgBlAGMAbgD9ACABYQBlAGQA/QAg
|
||||
AHAAcgBvAGYAaQBsBeQF6AXVBeQF2QXcACAARwByAGEAeQAgBdsF3AXcBdkAUAByAG8AZgBpAGwAIABn
|
||||
AHIAaQAgAGcAZQBuAGUAcgBpAGMAQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAARwByAGEAdQBzAHQAdQBm
|
||||
AGUAbgAtAFAAcgBvAGYAaQBsAFAAcgBvAGYAaQBsAG8AIABnAHIAaQBnAGkAbwAgAGcAZQBuAGUAcgBp
|
||||
AGMAbwBHAGUAbgBlAHIAaQBzAGsAIABnAHIA5QBzAGsAYQBsAGUAcAByAG8AZgBpAGxmbpAacHBepmPP
|
||||
j/Blh072TgCCLDCwMOwwpDDXMO0w1TChMKQw6wOTA7UDvQO5A7oDzAAgA8ADwQO/A8YDrwO7ACADswO6
|
||||
A8EDuQBQAGUAcgBmAGkAbAAgAGcAZQBuAOkAcgBpAGMAbwAgAGQAZQAgAGMAaQBuAHoAZQBuAHQAbwBz
|
||||
AEEAbABnAGUAbQBlAGUAbgAgAGcAcgBpAGoAcwBwAHIAbwBmAGkAZQBsAFAAZQByAGYAaQBsACAAZwBy
|
||||
AGkAcwAgAGcAZQBuAOkAcgBpAGMAbw5CDhsOIw5EDh8OJQ5MDioONQ5ADhcOMg4XDjEOSA4nDkQOGwBH
|
||||
AGUAbgBlAGwAIABHAHIAaQAgAFAAcgBvAGYAaQBsAGkAWQBsAGUAaQBuAGUAbgAgAGgAYQByAG0AYQBh
|
||||
AHAAcgBvAGYAaQBpAGwAaQBHAGUAbgBlAHIAaQENAGsAaQAgAHAAcgBvAGYAaQBsACAAcwBpAHYAaQBo
|
||||
ACAAdABvAG4AbwB2AGEAVQBuAGkAdwBlAHIAcwBhAGwAbgB5ACAAcAByAG8AZgBpAGwAIABzAHoAYQBy
|
||||
AG8BWwBjAGkEHgQxBEkEOAQ5ACAEQQQ1BEAESwQ5ACAEPwRABD4ERAQ4BDsETAZFBkQGQQAgBioGOQYx
|
||||
BkoGQQAgAEcAcgBhAHkAIAYnBkQGOQYnBkUARwBlAG4AZQByAGUAbAAgAGcAcgDlAHQAbwBuAGUAYgBl
|
||||
AHMAawByAGkAdgBlAGwAcwBlAAB0ZXh0AAAAAENvcHlyaWdodCAyMDA3IEFwcGxlIEluYy4sIGFsbCBy
|
||||
aWdodHMgcmVzZXJ2ZWQuAFhZWiAAAAAAAADzUQABAAAAARbMY3VydgAAAAAAAAABAc0AANIqKywtWiRj
|
||||
bGFzc25hbWVYJGNsYXNzZXNfEBBOU0JpdG1hcEltYWdlUmVwoywuL1pOU0ltYWdlUmVwWE5TT2JqZWN0
|
||||
0iorMTJXTlNBcnJheaIxL9IqKzQ1Xk5TTXV0YWJsZUFycmF5ozQxL9M3OA85OjtXTlNXaGl0ZVxOU0Nv
|
||||
bG9yU3BhY2VEMCAwABADgAzSKis9PldOU0NvbG9yoj0v0iorQEFXTlNJbWFnZaJALwAIABEAGgAkACkA
|
||||
MgA3AEkATABRAFMAYgBoAHUAfACLAJIAnwCmAK4AsACyALQAuQC7AL0AxADJANQA1gDYANoA3wDiAOQA
|
||||
5gDoAO0BBAEGAQgJ0AnVCeAJ6Qn8CgAKCwoUChkKIQokCikKOAo8CkMKSwpYCl0KXwphCmYKbgpxCnYK
|
||||
fgAAAAAAAAIBAAAAAAAAAEIAAAAAAAAAAAAAAAAAAAqBA
|
||||
EiDDAACAA4ALVnsxLCAxfdIbDxweWk5TLm9iamVjdHOhHYAEgArSGw8gI6IhIoAFgAaACdMPJSYnKBRf
|
||||
EBROU1RJRkZSZXByZXNlbnRhdGlvbl8QGU5TSW50ZXJuYWxMYXlvdXREaXJlY3Rpb26ACIAHTxEIxE1N
|
||||
ACoAAAAKAAAAEAEAAAMAAAABAAEAAAEBAAMAAAABAAEAAAECAAMAAAACAAgACAEDAAMAAAABAAEAAAEG
|
||||
AAMAAAABAAEAAAEKAAMAAAABAAEAAAERAAQAAAABAAAACAESAAMAAAABAAEAAAEVAAMAAAABAAIAAAEW
|
||||
AAMAAAABAAEAAAEXAAQAAAABAAAAAgEcAAMAAAABAAEAAAEoAAMAAAABAAIAAAFSAAMAAAABAAEAAAFT
|
||||
AAMAAAACAAEAAYdzAAcAAAf0AAAA0AAAAAAAAAf0YXBwbAIgAABtbnRyR1JBWVhZWiAH0AACAA4ADAAA
|
||||
AABhY3NwQVBQTAAAAABub25lAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVkZXNjAAAAwAAAAG9kc2NtAAABMAAA
|
||||
BmZjcHJ0AAAHmAAAADh3dHB0AAAH0AAAABRrVFJDAAAH5AAAAA5kZXNjAAAAAAAAABVHZW5lcmljIEdy
|
||||
YXkgUHJvZmlsZQAAAAAAAAAAAAAAFUdlbmVyaWMgR3JheSBQcm9maWxlAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbWx1YwAAAAAAAAAfAAAADHNrU0sAAAAqAAABhGVu
|
||||
VVMAAAAoAAABrmNhRVMAAAAsAAAB1nZpVk4AAAAsAAACAnB0QlIAAAAqAAACLnVrVUEAAAAsAAACWGZy
|
||||
RlUAAAAqAAAChGh1SFUAAAAuAAACrnpoVFcAAAAQAAAC3G5iTk8AAAAsAAAC7GtvS1IAAAAYAAADGGNz
|
||||
Q1oAAAAkAAADMGhlSUwAAAAgAAADVHJvUk8AAAAkAAADdGRlREUAAAA6AAADmGl0SVQAAAAuAAAD0nN2
|
||||
U0UAAAAuAAAEAHpoQ04AAAAQAAAELmphSlAAAAAWAAAEPmVsR1IAAAAkAAAEVHB0UE8AAAA4AAAEeG5s
|
||||
TkwAAAAqAAAEsGVzRVMAAAAoAAAE2nRoVEgAAAAkAAAFAnRyVFIAAAAiAAAFJmZpRkkAAAAsAAAFSGhy
|
||||
SFIAAAA6AAAFdHBsUEwAAAA2AAAFrnJ1UlUAAAAmAAAF5GFyRUcAAAAoAAAGCmRhREsAAAA0AAAGMgBW
|
||||
AWEAZQBvAGIAZQBjAG4A/QAgAHMAaQB2AP0AIABwAHIAbwBmAGkAbABHAGUAbgBlAHIAaQBjACAARwBy
|
||||
AGEAeQAgAFAAcgBvAGYAaQBsAGUAUABlAHIAZgBpAGwAIABkAGUAIABnAHIAaQBzACAAZwBlAG4A6ABy
|
||||
AGkAYwBDHqUAdQAgAGgA7ABuAGgAIABNAOAAdQAgAHgA4QBtACAAQwBoAHUAbgBnAFAAZQByAGYAaQBs
|
||||
ACAAQwBpAG4AegBhACAARwBlAG4A6QByAGkAYwBvBBcEMAQzBDAEOwRMBD0EOAQ5ACAEPwRABD4ERAQw
|
||||
BDkEOwAgAEcAcgBhAHkAUAByAG8AZgBpAGwAIABnAOkAbgDpAHIAaQBxAHUAZQAgAGcAcgBpAHMAwQBs
|
||||
AHQAYQBsAOEAbgBvAHMAIABzAHoA/AByAGsAZQAgAHAAcgBvAGYAaQBskBp1KHBwlo6Ccl9pY8+P8ABH
|
||||
AGUAbgBlAHIAaQBzAGsAIABnAHIA5QB0AG8AbgBlAHAAcgBvAGYAaQBsx3y8GAAgAEcAcgBhAHkAINUE
|
||||
uFzTDMd8AE8AYgBlAGMAbgD9ACABYQBlAGQA/QAgAHAAcgBvAGYAaQBsBeQF6AXVBeQF2QXcACAARwBy
|
||||
AGEAeQAgBdsF3AXcBdkAUAByAG8AZgBpAGwAIABnAHIAaQAgAGcAZQBuAGUAcgBpAGMAQQBsAGwAZwBl
|
||||
AG0AZQBpAG4AZQBzACAARwByAGEAdQBzAHQAdQBmAGUAbgAtAFAAcgBvAGYAaQBsAFAAcgBvAGYAaQBs
|
||||
AG8AIABnAHIAaQBnAGkAbwAgAGcAZQBuAGUAcgBpAGMAbwBHAGUAbgBlAHIAaQBzAGsAIABnAHIA5QBz
|
||||
AGsAYQBsAGUAcAByAG8AZgBpAGxmbpAacHBepmPPj/Blh072TgCCLDCwMOwwpDDXMO0w1TChMKQw6wOT
|
||||
A7UDvQO5A7oDzAAgA8ADwQO/A8YDrwO7ACADswO6A8EDuQBQAGUAcgBmAGkAbAAgAGcAZQBuAOkAcgBp
|
||||
AGMAbwAgAGQAZQAgAGMAaQBuAHoAZQBuAHQAbwBzAEEAbABnAGUAbQBlAGUAbgAgAGcAcgBpAGoAcwBw
|
||||
AHIAbwBmAGkAZQBsAFAAZQByAGYAaQBsACAAZwByAGkAcwAgAGcAZQBuAOkAcgBpAGMAbw5CDhsOIw5E
|
||||
Dh8OJQ5MDioONQ5ADhcOMg4XDjEOSA4nDkQOGwBHAGUAbgBlAGwAIABHAHIAaQAgAFAAcgBvAGYAaQBs
|
||||
AGkAWQBsAGUAaQBuAGUAbgAgAGgAYQByAG0AYQBhAHAAcgBvAGYAaQBpAGwAaQBHAGUAbgBlAHIAaQEN
|
||||
AGsAaQAgAHAAcgBvAGYAaQBsACAAcwBpAHYAaQBoACAAdABvAG4AbwB2AGEAVQBuAGkAdwBlAHIAcwBh
|
||||
AGwAbgB5ACAAcAByAG8AZgBpAGwAIABzAHoAYQByAG8BWwBjAGkEHgQxBEkEOAQ5ACAEQQQ1BEAESwQ5
|
||||
ACAEPwRABD4ERAQ4BDsETAZFBkQGQQAgBioGOQYxBkoGQQAgAEcAcgBhAHkAIAYnBkQGOQYnBkUARwBl
|
||||
AG4AZQByAGUAbAAgAGcAcgDlAHQAbwBuAGUAYgBlAHMAawByAGkAdgBlAGwAcwBlAAB0ZXh0AAAAAENv
|
||||
cHlyaWdodCAyMDA3IEFwcGxlIEluYy4sIGFsbCByaWdodHMgcmVzZXJ2ZWQuAFhZWiAAAAAAAADzUQAB
|
||||
AAAAARbMY3VydgAAAAAAAAABAc0AANIrLC0uWiRjbGFzc25hbWVYJGNsYXNzZXNfEBBOU0JpdG1hcElt
|
||||
YWdlUmVwoy0vMFpOU0ltYWdlUmVwWE5TT2JqZWN00issMjNXTlNBcnJheaIyMNIrLDU2Xk5TTXV0YWJs
|
||||
ZUFycmF5ozUyMNM4OQ86OzxXTlNXaGl0ZVxOU0NvbG9yU3BhY2VEMCAwABADgAzSKyw+P1dOU0NvbG9y
|
||||
oj4w0issQUJXTlNJbWFnZaJBMAAIABEAGgAkACkAMgA3AEkATABRAFMAYgBoAHUAfACLAJIAnwCmAK4A
|
||||
sACyALQAuQC7AL0AxADJANQA1gDYANoA3wDiAOQA5gDoAO8BBgEiASQBJgnuCfMJ/goHChoKHgopCjIK
|
||||
Nwo/CkIKRwpWCloKYQppCnYKewp9Cn8KhAqMCo8KlAqcAAAAAAAAAgEAAAAAAAAAQwAAAAAAAAAAAAAA
|
||||
AAAACp8
|
||||
</mutableData>
|
||||
</image>
|
||||
</resources>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.4.0</string>
|
||||
<string>0.4.3</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
@@ -33,7 +33,7 @@
|
||||
<key>NSAppleScriptEnabled</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2016-2021 Background Music contributors</string>
|
||||
<string>Copyright © 2016-2024 Background Music contributors</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// BGMAboutPanel.m
|
||||
// BGMApp
|
||||
//
|
||||
// Copyright © 2016 Kyle Neideck
|
||||
// Copyright © 2016, 2024 Kyle Neideck
|
||||
//
|
||||
|
||||
// Self Include
|
||||
@@ -35,6 +35,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
static NSInteger const kVersionLabelTag = 1;
|
||||
static NSInteger const kCopyrightLabelTag = 2;
|
||||
static NSInteger const kProjectWebsiteLabelTag = 3;
|
||||
static NSInteger const kContributorsLabelTag = 4;
|
||||
|
||||
@implementation BGMAboutPanel {
|
||||
NSPanel* aboutPanel;
|
||||
@@ -42,6 +43,7 @@ static NSInteger const kProjectWebsiteLabelTag = 3;
|
||||
NSTextField* versionLabel;
|
||||
NSTextField* copyrightLabel;
|
||||
NSTextField* websiteLabel;
|
||||
NSTextField* contributorsLabel;
|
||||
|
||||
NSTextView* licenseView;
|
||||
}
|
||||
@@ -53,6 +55,7 @@ static NSInteger const kProjectWebsiteLabelTag = 3;
|
||||
versionLabel = [[aboutPanel contentView] viewWithTag:kVersionLabelTag];
|
||||
copyrightLabel = [[aboutPanel contentView] viewWithTag:kCopyrightLabelTag];
|
||||
websiteLabel = [[aboutPanel contentView] viewWithTag:kProjectWebsiteLabelTag];
|
||||
contributorsLabel = [[aboutPanel contentView] viewWithTag:kContributorsLabelTag];
|
||||
|
||||
licenseView = inLicenseView;
|
||||
|
||||
@@ -83,7 +86,10 @@ static NSInteger const kProjectWebsiteLabelTag = 3;
|
||||
[[bundle infoDictionary] objectForKey:@"NSHumanReadableCopyright"];
|
||||
|
||||
if (copyrightNotice) {
|
||||
copyrightLabel.stringValue = (NSString*)copyrightNotice;
|
||||
// Remove the part that we replace with a link.
|
||||
copyrightLabel.stringValue =
|
||||
[((NSString*)copyrightNotice) stringByReplacingOccurrencesOfString:contributorsLabel.stringValue
|
||||
withString:@""];
|
||||
}
|
||||
|
||||
// Project website link label
|
||||
@@ -97,6 +103,18 @@ static NSInteger const kProjectWebsiteLabelTag = 3;
|
||||
attributes:@{ NSLinkAttributeName: projectURL,
|
||||
NSFontAttributeName: linkFont }];
|
||||
|
||||
// Contributors link label
|
||||
// TODO: Proper credits (i.e. in the app instead of just a link)
|
||||
contributorsLabel.selectable = YES;
|
||||
contributorsLabel.allowsEditingTextAttributes = YES;
|
||||
|
||||
NSString* contributorsURL = [NSString stringWithUTF8String:kBGMContributorsURL];
|
||||
NSFont* cLinkFont = contributorsLabel.font ? contributorsLabel.font : [NSFont labelFontOfSize:0.0];
|
||||
contributorsLabel.attributedStringValue =
|
||||
[[NSAttributedString alloc] initWithString:contributorsLabel.stringValue
|
||||
attributes:@{ NSLinkAttributeName: contributorsURL,
|
||||
NSFontAttributeName: cLinkFont }];
|
||||
|
||||
// Load the text of the license into the text view
|
||||
NSString* __nullable licensePath = [bundle pathForResource:@"LICENSE" ofType:nil];
|
||||
|
||||
@@ -122,9 +140,25 @@ static NSInteger const kProjectWebsiteLabelTag = 3;
|
||||
|
||||
- (void) show {
|
||||
DebugMsg("BGMAboutPanel::showAboutPanel: Opening \"About Background Music\" panel");
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
// We have to make aboutPanel visible before calling [NSApp activateIgnoringOtherApps:YES]
|
||||
// or the app won't be activated the first time (not sure why it only happens the first
|
||||
// time) and aboutPanel won't open. WindowServer logs this explanation:
|
||||
// 0[SetFrontProcessWithInfo]: CPS: Rejecting the request for pid 1234 due to the activation count being 0; launch ts=19302059379458, current time=19314267188375, window count = 0.
|
||||
[aboutPanel setIsVisible:YES];
|
||||
[aboutPanel makeKeyAndOrderFront:self];
|
||||
|
||||
// On macOS 14.4, aboutPanel needs "Release When Closed" unchecked in MainMenu.xib. Otherwise,
|
||||
// aboutPanel will never open again if you click the close button.
|
||||
|
||||
// This is deprecated for NSApplication.activate, but that stops aboutPanel from ever being shown.
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
DebugMsg("BGMAboutPanel::showAboutPanel: Finished opening panel. "
|
||||
"aboutPanel.isVisible %d, aboutPanel.isKeyWindow %d, NSApp.isActive %d",
|
||||
aboutPanel.isVisible,
|
||||
aboutPanel.isKeyWindow,
|
||||
NSApp.isActive);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
|
||||
#import "BGMAppDelegate.h"
|
||||
|
||||
// Local Includes
|
||||
#import "BGMAudioDeviceManager.h"
|
||||
#import "BGMAppVolumesController.h"
|
||||
|
||||
// Local Includes
|
||||
#import "BGMASOutputDevice.h"
|
||||
#import "BGMASApplication.h"
|
||||
|
||||
@@ -140,20 +140,20 @@ sleep 2
|
||||
# don't work with older versions of launchctl, so I figure there's no harm in trying a bunch of different ways until
|
||||
# one works.
|
||||
(sudo launchctl kickstart -k system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo killall coreaudiod &>/dev/null || \
|
||||
sudo launchctl kill SIGTERM system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo launchctl kill TERM system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo launchctl kill 15 system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo launchctl kill -15 system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
(sudo launchctl unload "${coreaudiod_plist}" &>/dev/null && \
|
||||
sudo launchctl load "${coreaudiod_plist}" &>/dev/null) || \
|
||||
sudo killall coreaudiod &>/dev/null)
|
||||
sudo launchctl load "${coreaudiod_plist}" &>/dev/null))
|
||||
|
||||
echo "..."
|
||||
sleep 3
|
||||
|
||||
# TODO: What if they only have one audio device?
|
||||
echo ""
|
||||
echo "${bold}Done! Toggle your audio output device in the Sound section of System Preferences to finish" \
|
||||
echo "${bold}Done! Toggle your audio output device in the Sound section of System Settings to finish" \
|
||||
"uninstalling. (Or just restart your computer.)${normal}"
|
||||
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
// Make the "Background Music wants to use the microphone" dialog appear every time so the test
|
||||
// doesn't need logic to handle both cases.
|
||||
// TODO: Commented out to check if CI builds can grant access by modifying TCC.db.
|
||||
// TODO: Commented out until acceptMicrophoneAuthorizationDialog work again. See below.
|
||||
// if (@available(macOS 10.15.4, *)) {
|
||||
// [app resetAuthorizationStatusForResource:XCUIProtectedResourceMicrophone];
|
||||
// }
|
||||
@@ -84,18 +84,19 @@
|
||||
// Launch BGMApp.
|
||||
[app launch];
|
||||
|
||||
// TODO: Commented out to check if CI builds can grant access by modifying TCC.db.
|
||||
// TODO: This doesn't seem to be working on macOS 12.4 (21F79). You can click OK manually for
|
||||
// now.
|
||||
// [self acceptMicrophoneAuthorizationDialog];
|
||||
|
||||
if (![icon waitForExistenceWithTimeout:20.0]) {
|
||||
if (![icon waitForExistenceWithTimeout:20.0]) {
|
||||
// The status bar icon/button has this type when using older versions of XCTest, so try
|
||||
// both. (Actually, it might depend on the macOS or Xcode version. I'm not sure.)
|
||||
XCUIElement* iconOldType =
|
||||
[app.menuBars childrenMatchingType:XCUIElementTypeMenuBarItem].element;
|
||||
if ([iconOldType waitForExistenceWithTimeout:20.0]) {
|
||||
NSLog(@"icon = iconOldType");
|
||||
icon = iconOldType;
|
||||
}
|
||||
[app.menuBars childrenMatchingType:XCUIElementTypeMenuBarItem].element;
|
||||
if ([iconOldType waitForExistenceWithTimeout:20.0]) {
|
||||
NSLog(@"icon = iconOldType");
|
||||
icon = iconOldType;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for the initial elements.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python2.7
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This file is part of Background Music.
|
||||
#
|
||||
@@ -19,7 +19,7 @@
|
||||
# skip-ui-tests.py
|
||||
# BGMAppUITests
|
||||
#
|
||||
# Copyright (c) 2017 Kyle Neideck
|
||||
# Copyright (c) 2017, 2024 Kyle Neideck
|
||||
#
|
||||
# Disables the UI tests. This is mainly useful on CI systems that don't support UI tests.
|
||||
#
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.4.0</string>
|
||||
<string>0.4.3</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2016-2021 Background Music contributors</string>
|
||||
<string>Copyright © 2016-2024 Background Music contributors</string>
|
||||
<key>XPCService</key>
|
||||
<dict>
|
||||
<key>ServiceType</key>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// BGMDebugLogging.c
|
||||
// PublicUtility
|
||||
//
|
||||
// Copyright © 2020 Kyle Neideck
|
||||
// Copyright © 2020, 2024 Kyle Neideck
|
||||
//
|
||||
|
||||
// Self Include
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
// We don't bother synchronising accesses of gDebugLoggingIsEnabled because it isn't really
|
||||
// necessary and would complicate code that accesses it on realtime threads.
|
||||
int BGMDebugLoggingIsEnabled()
|
||||
int BGMDebugLoggingIsEnabled(void)
|
||||
{
|
||||
return gDebugLoggingIsEnabled;
|
||||
}
|
||||
|
||||
@@ -59,13 +59,15 @@ full barrier.
|
||||
#if TARGET_OS_WIN32
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(_InterlockedOr)
|
||||
#pragma intrinsic(_InterlockedOr)
|
||||
#pragma intrinsic(_InterlockedAnd)
|
||||
#else
|
||||
#include <CoreFoundation/CFBase.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
inline void CAMemoryBarrier()
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
@@ -196,6 +198,8 @@ inline bool CAAtomicTestAndSetBarrier(int bitToSet, void* theAddress)
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// int32_t flavors -- for C++ only since we can't overload in C
|
||||
// CFBase.h defines SInt32 as signed int which is similar to int32_t. If CFBase.h is included, then
|
||||
// this will generate redefinition error. But on Mac, CFBase.h, still includes MacTypes.h where
|
||||
@@ -243,6 +247,9 @@ inline int32_t CAAtomicDecrement32Barrier(volatile int32_t* theValue)
|
||||
}
|
||||
#endif // __cplusplus && !__LP64__
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
|
||||
#if __LP64__
|
||||
inline bool CAAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue )
|
||||
{
|
||||
@@ -259,6 +266,8 @@ inline bool CAAtomicCompareAndSwapPtrBarrier(void *__oldValue, void *__newValue,
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
/* Spinlocks. These use memory barriers as required to synchronize access to shared
|
||||
* memory protected by the lock. The lock operation spins, but employs various strategies
|
||||
* to back off if the lock is held, making it immune to most priority-inversion livelocks.
|
||||
@@ -273,6 +282,9 @@ bool CASpinLockTry( volatile CASpinLock *__lock );
|
||||
void CASpinLockLock( volatile CASpinLock *__lock );
|
||||
void CASpinLockUnlock( volatile CASpinLock *__lock );
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
|
||||
inline void CASpinLockLock( volatile CASpinLock *__lock )
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
@@ -301,5 +313,6 @@ inline bool CASpinLockTry( volatile CASpinLock *__lock )
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
#endif // __CAAtomic_h__
|
||||
|
||||
@@ -98,29 +98,6 @@ public:
|
||||
static bool IsCongruentElement(AudioObjectPropertyElement inElement1, AudioObjectPropertyElement inElement2) { return (inElement1 == inElement2) || (inElement1 == kAudioObjectPropertyElementWildcard) || (inElement2 == kAudioObjectPropertyElementWildcard); }
|
||||
static bool IsCongruentAddress(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) { return IsCongruentScope(inAddress1.mScope, inAddress2.mScope) && IsCongruentSelector(inAddress1.mSelector, inAddress2.mSelector) && IsCongruentElement(inAddress1.mElement, inAddress2.mElement); }
|
||||
static bool IsCongruentLessThanAddress(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) { bool theAnswer = false; if(!IsCongruentScope(inAddress1.mScope, inAddress2.mScope)) { theAnswer = inAddress1.mScope < inAddress2.mScope; } else if(!IsCongruentSelector(inAddress1.mSelector, inAddress2.mSelector)) { theAnswer = inAddress1.mSelector < inAddress2.mSelector; } else if(!IsCongruentElement(inAddress1.mElement, inAddress2.mElement)) { theAnswer = inAddress1.mElement < inAddress2.mElement; } return theAnswer; }
|
||||
|
||||
// STL Helpers
|
||||
public:
|
||||
struct EqualTo : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
|
||||
{
|
||||
bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsSameAddress(inAddress1, inAddress2); }
|
||||
};
|
||||
|
||||
struct LessThan : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
|
||||
{
|
||||
bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsLessThanAddress(inAddress1, inAddress2); }
|
||||
};
|
||||
|
||||
struct CongruentEqualTo : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
|
||||
{
|
||||
bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsCongruentAddress(inAddress1, inAddress2); }
|
||||
};
|
||||
|
||||
struct CongruentLessThan : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
|
||||
{
|
||||
bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsCongruentLessThanAddress(inAddress1, inAddress2); }
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
@@ -157,11 +134,8 @@ public:
|
||||
const AudioObjectPropertyAddress* GetItems() const { return &(*mAddressList.begin()); }
|
||||
AudioObjectPropertyAddress* GetItems() { return &(*mAddressList.begin()); }
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
bool HasItem(const AudioObjectPropertyAddress& inAddress) const { AddressList::const_iterator theIterator = std::find_if(mAddressList.begin(), mAddressList.end(), std::bind1st(CAPropertyAddress::CongruentEqualTo(), inAddress)); return theIterator != mAddressList.end(); }
|
||||
bool HasExactItem(const AudioObjectPropertyAddress& inAddress) const { AddressList::const_iterator theIterator = std::find_if(mAddressList.begin(), mAddressList.end(), std::bind1st(CAPropertyAddress::EqualTo(), inAddress)); return theIterator != mAddressList.end(); }
|
||||
#pragma clang diagnostic pop
|
||||
bool HasItem(const AudioObjectPropertyAddress& inAddress) const { AddressList::const_iterator theIterator = std::find_if(mAddressList.begin(), mAddressList.end(), [&inAddress](const CAPropertyAddress& addr) { return CAPropertyAddress::IsCongruentAddress(addr, inAddress); }); return theIterator != mAddressList.end(); }
|
||||
bool HasExactItem(const AudioObjectPropertyAddress& inAddress) const { AddressList::const_iterator theIterator = std::find_if(mAddressList.begin(), mAddressList.end(), [&inAddress](const CAPropertyAddress& addr) { return CAPropertyAddress::IsSameAddress(addr, inAddress); }); return theIterator != mAddressList.end(); }
|
||||
|
||||
void AppendItem(const AudioObjectPropertyAddress& inAddress) { mAddressList.push_back(inAddress); }
|
||||
void AppendUniqueItem(const AudioObjectPropertyAddress& inAddress) { if(!HasItem(inAddress)) { mAddressList.push_back(inAddress); } }
|
||||
@@ -169,7 +143,7 @@ public:
|
||||
void InsertItemAtIndex(UInt32 inIndex, const AudioObjectPropertyAddress& inAddress) { if(inIndex < mAddressList.size()) { AddressList::iterator theIterator = mAddressList.begin(); std::advance(theIterator, static_cast<int>(inIndex)); mAddressList.insert(theIterator, inAddress); } else { mAddressList.push_back(inAddress); } }
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
void EraseExactItem(const AudioObjectPropertyAddress& inAddress) { AddressList::iterator theIterator = std::find_if(mAddressList.begin(), mAddressList.end(), std::bind1st(CAPropertyAddress::EqualTo(), inAddress)); if(theIterator != mAddressList.end()) { mAddressList.erase(theIterator); } }
|
||||
void EraseExactItem(const AudioObjectPropertyAddress& inAddress) { AddressList::iterator theIterator = std::find_if(mAddressList.begin(), mAddressList.end(), [&inAddress](const CAPropertyAddress& addr) { return CAPropertyAddress::IsSameAddress(addr, inAddress); }); if(theIterator != mAddressList.end()) { mAddressList.erase(theIterator); } }
|
||||
#pragma clang diagnostic pop
|
||||
void EraseItemAtIndex(UInt32 inIndex) { if(inIndex < mAddressList.size()) { AddressList::iterator theIterator = mAddressList.begin(); std::advance(theIterator, static_cast<int>(inIndex)); mAddressList.erase(theIterator); } }
|
||||
void EraseAllItems() { mAddressList.clear(); }
|
||||
|
||||
@@ -712,7 +712,7 @@
|
||||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
WARNING_CFLAGS = "-Wpartial-availability";
|
||||
@@ -780,7 +780,7 @@
|
||||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
WARNING_CFLAGS = "-Wpartial-availability";
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// BGM_XPCHelper.m
|
||||
// BGMDriver
|
||||
//
|
||||
// Copyright © 2016, 2017, 2020 Kyle Neideck
|
||||
// Copyright © 2016, 2017, 2020, 2024 Kyle Neideck
|
||||
// Copyright © 2020 Aleksey Yurkevich
|
||||
//
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
static const UInt64 REMOTE_CALL_DEFAULT_TIMEOUT_SECS = 30;
|
||||
|
||||
static NSXPCConnection* CreateXPCHelperConnection()
|
||||
static NSXPCConnection* CreateXPCHelperConnection(void)
|
||||
{
|
||||
// Create a connection to BGMXPCHelper's Mach service. If it isn't already running, launchd will start BGMXPCHelper when we send
|
||||
// a message to this connection.
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.4.0</string>
|
||||
<string>0.4.3</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
@@ -37,7 +37,7 @@
|
||||
</array>
|
||||
</dict>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2016-2021 Background Music contributors</string>
|
||||
<string>Copyright © 2016-2024 Background Music contributors</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
|
||||
@@ -59,13 +59,15 @@ full barrier.
|
||||
#if TARGET_OS_WIN32
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(_InterlockedOr)
|
||||
#pragma intrinsic(_InterlockedOr)
|
||||
#pragma intrinsic(_InterlockedAnd)
|
||||
#else
|
||||
#include <CoreFoundation/CFBase.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
inline void CAMemoryBarrier()
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
@@ -195,6 +197,7 @@ inline bool CAAtomicTestAndSetBarrier(int bitToSet, void* theAddress)
|
||||
return OSAtomicTestAndSetBarrier(bitToSet, (volatile void *)theAddress);
|
||||
#endif
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// int32_t flavors -- for C++ only since we can't overload in C
|
||||
// CFBase.h defines SInt32 as signed int which is similar to int32_t. If CFBase.h is included, then
|
||||
@@ -243,6 +246,9 @@ inline int32_t CAAtomicDecrement32Barrier(volatile int32_t* theValue)
|
||||
}
|
||||
#endif // __cplusplus && !__LP64__
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
|
||||
#if __LP64__
|
||||
inline bool CAAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue )
|
||||
{
|
||||
@@ -258,6 +264,7 @@ inline bool CAAtomicCompareAndSwapPtrBarrier(void *__oldValue, void *__newValue,
|
||||
return CAAtomicCompareAndSwap32Barrier((int32_t)__oldValue, (int32_t)__newValue, (int32_t *)__theValue);
|
||||
#endif
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
/* Spinlocks. These use memory barriers as required to synchronize access to shared
|
||||
* memory protected by the lock. The lock operation spins, but employs various strategies
|
||||
@@ -273,6 +280,9 @@ bool CASpinLockTry( volatile CASpinLock *__lock );
|
||||
void CASpinLockLock( volatile CASpinLock *__lock );
|
||||
void CASpinLockUnlock( volatile CASpinLock *__lock );
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
|
||||
inline void CASpinLockLock( volatile CASpinLock *__lock )
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
@@ -301,5 +311,7 @@ inline bool CASpinLockTry( volatile CASpinLock *__lock )
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
|
||||
#endif // __CAAtomic_h__
|
||||
|
||||
@@ -160,6 +160,8 @@ public:
|
||||
|
||||
static bool compare_and_swap(T *oldvalue, T *newvalue, T **pvalue)
|
||||
{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
#if TARGET_OS_MAC
|
||||
#if __LP64__
|
||||
return ::OSAtomicCompareAndSwap64Barrier(int64_t(oldvalue), int64_t(newvalue), (int64_t *)pvalue);
|
||||
@@ -172,6 +174,7 @@ public:
|
||||
//return ::CompareAndSwap(UInt32(oldvalue), UInt32(newvalue), (UInt32 *)pvalue);
|
||||
return CAAtomicCompareAndSwap32Barrier(SInt32(oldvalue), SInt32(newvalue), (SInt32*)pvalue);
|
||||
#endif
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -101,6 +101,8 @@ public:
|
||||
|
||||
// STL Helpers
|
||||
public:
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
struct EqualTo : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
|
||||
{
|
||||
bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsSameAddress(inAddress1, inAddress2); }
|
||||
@@ -120,6 +122,7 @@ public:
|
||||
{
|
||||
bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsCongruentLessThanAddress(inAddress1, inAddress2); }
|
||||
};
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ the virtual device to the real output device and a few other things. The virtual
|
||||
## Summary
|
||||
|
||||
From the user's perspective, BGMDevice appears as one input device and one output device, both named "Background Music".
|
||||
They're shown in `System Preferences > Sound` along with the real audio devices.
|
||||
They're shown in `System Settings > Sound` along with the real audio devices.
|
||||
|
||||
When you start BGMApp, it sets BGMDevice as your system's default output device so the system (i.e. Core Audio) will
|
||||
start sending all<sup id="a2">[2](#f2)</sup> your audio data to BGMDriver. BGMDriver plays that audio on BGMDevice's
|
||||
|
||||
+3
-2
@@ -38,12 +38,13 @@
|
||||
(Audio will stop working until the next step, so you might want to pause any running audio apps.)
|
||||
|
||||
```shell
|
||||
sudo launchctl kickstart -kp system/com.apple.audio.coreaudiod
|
||||
sudo killall coreaudiod
|
||||
```
|
||||
|
||||
or, if that fails
|
||||
|
||||
```shell
|
||||
sudo killall coreaudiod
|
||||
sudo launchctl kickstart -kp system/com.apple.audio.coreaudiod
|
||||
```
|
||||
- Run `Background Music.app`.
|
||||
|
||||
|
||||
+3
-3
@@ -9,14 +9,14 @@
|
||||
<sup>(Open `/Applications/Utilities/Terminal.app` and paste the following at the prompt.)</sup>
|
||||
|
||||
```shell
|
||||
sudo launchctl kickstart -kp system/com.apple.audio.coreaudiod
|
||||
sudo killall coreaudiod
|
||||
```
|
||||
or, if that fails
|
||||
|
||||
```shell
|
||||
sudo killall coreaudiod
|
||||
sudo launchctl kickstart -kp system/com.apple.audio.coreaudiod
|
||||
```
|
||||
- Go to the Sound section in System Preferences and change your default output device at least once. (If you only have
|
||||
- Go to the Sound section in System Settings and change your default output device at least once. (If you only have
|
||||
one device now, either use `Audio MIDI Setup.app` to create a temporary aggregate device, restart any audio apps that
|
||||
have stopped working or just restart your system.)
|
||||
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
[Overview](#overview)<br/>
|
||||
[Auto-pause music](#auto-pause-music)<br/>
|
||||
[Application volume](#application-volume)<br/>
|
||||
[Recording system audio](#recording-system-audio)<br/>
|
||||
[Download](#download)<br/>
|
||||
[Recording system audio](#recording-system-audio)<br/>
|
||||
[Download](#download)<br/>
|
||||
[Run / Configure](#run--configure)<br/>
|
||||
[Build and Install](#installing-from-source-code)</br>
|
||||
[Uninstall](#uninstall)<br/>
|
||||
[Troubleshooting](#troubleshooting)<br/>
|
||||
[Related Projects](#related-projects)<br/>
|
||||
[License](#license)<br/>
|
||||
[Troubleshooting](#troubleshooting)<br/>
|
||||
[Related Projects](#related-projects)<br/>
|
||||
[License](#license)<br/>
|
||||
|
||||
# Overview
|
||||
|
||||
@@ -40,11 +41,11 @@ The auto-pause feature currently supports following music players:
|
||||
+ [Decibel](https://sbooth.org/Decibel/)
|
||||
+ [Hermes](http://hermesapp.org/)
|
||||
+ [Swinsian](https://swinsian.com/)
|
||||
+ [GPMDP](https://www.googleplaymusicdesktopplayer.com/)
|
||||
+ [GPMDP](https://www.googleplaymusicdesktopplayer.com/)
|
||||
|
||||
Adding support for a new music player is usually straightforward.<sup id="a1">[1](#f1)</sup> If you don't know how to program, or just don't feel
|
||||
like it, feel free to [create an issue](https://github.com/kyleneideck/BackgroundMusic/issues/new). Otherwise, see
|
||||
[BGMMusicPlayer.h](BGMApp/BGMApp/Music%20Players/BGMMusicPlayer.h).
|
||||
[BGMMusicPlayer.h](BGMApp/BGMApp/Music%20Players/BGMMusicPlayer.h).
|
||||
|
||||
## Application volume
|
||||
|
||||
@@ -61,25 +62,22 @@ the **Background Music** device. You can create the aggregate device using the *
|
||||
|
||||
# Download
|
||||
|
||||
**Requires macOS 10.10+**.
|
||||
**Requires macOS 10.13+**.
|
||||
|
||||
You can download the current version of **Background Music** using the following options. We also have [snapshot builds](https://github.com/kyleneideck/BackgroundMusic/releases).
|
||||
|
||||
| ⚠️ Version 0.3.2 doesn't work on macOS Big Sur. Try this snapshot version: [0.4.0-SNAPSHOT-b38f6dd](https://github.com/kyleneideck/BackgroundMusic/releases/tag/0.4.0-SNAPSHOT-b38f6dd) |
|
||||
|------------- |
|
||||
|
||||
### Option 1
|
||||
|
||||
Download **version 0.3.2**:
|
||||
Download **version 0.4.3**:
|
||||
|
||||
<a href="https://github.com/kyleneideck/BackgroundMusic/releases/download/v0.3.2/BackgroundMusic-0.3.2.pkg"><img
|
||||
<a href="https://github.com/kyleneideck/BackgroundMusic/releases/download/v0.4.3/BackgroundMusic-0.4.3.pkg"><img
|
||||
src="Images/README/pkg-icon.png" width="32" height="32" align="absmiddle" />
|
||||
BackgroundMusic-0.3.2.pkg</a> (571 KB)
|
||||
BackgroundMusic-0.4.3.pkg</a> (771 KB)
|
||||
|
||||
> <sub>MD5: 7f34d9e6595566f3ba14e7afc89c86a2</sub><br/>
|
||||
> <sub>SHA256: 0cd7b488b5ab97a1ecb496e484a6c209c29f35ab503e6f73b45e56719a7aba18</sub><br/>
|
||||
> <sub>MD5: 8c3bfe26c9cdf27365b9843f719ef188</sub><br/>
|
||||
> <sub>SHA256: c1c48a37c83af44ce50bee68879856c96b2f6c97360ce461b1c7d653515be7fd</sub><br/>
|
||||
> <sub>PGP:
|
||||
> [sig](https://github.com/kyleneideck/BackgroundMusic/releases/download/v0.3.2/BackgroundMusic-0.3.2.pkg.asc),
|
||||
> [sig](https://github.com/kyleneideck/BackgroundMusic/releases/download/v0.4.3/BackgroundMusic-0.4.3.pkg.asc),
|
||||
> [key (0595DF814E41A6F69334C5E2CAA8D9B8E39EC18C)](https://bearisdriving.com/kyle-neideck.gpg)</sub>
|
||||
|
||||
### Option 2
|
||||
@@ -90,17 +88,19 @@ Install using [Homebrew](https://brew.sh/) by running the following command in *
|
||||
brew install --cask background-music
|
||||
```
|
||||
|
||||
If you want the snapshot version, run:
|
||||
# Run / Configure
|
||||
|
||||
```bash
|
||||
brew tap homebrew/cask-versions
|
||||
brew install --cask background-music-pre
|
||||
```
|
||||
Just run `Applications > Background Music.app`! **Background Music** sets itself as your default output device under
|
||||
`System Settings > Sound` when it starts up (and sets it back on Quit).
|
||||
|
||||
### Launch at Startup (Optional)
|
||||
|
||||
Add **Background Music** to `System Settings > General > Login Items`.
|
||||
|
||||
# Installing from Source Code
|
||||
|
||||
**Background Music** usually takes less than a minute to build. You need [Xcode](https://developer.apple.com/xcode/download/) version
|
||||
8 or higher.
|
||||
**Background Music** usually takes less than a minute to build. You need [Xcode](https://developer.apple.com/xcode/download/) version
|
||||
10 or higher.
|
||||
|
||||
### Option 1
|
||||
|
||||
@@ -147,12 +147,12 @@ To manually uninstall, see [MANUAL_UNINSTALL.md](https://github.com/kyleneideck/
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
If Background Music crashes and your audio stops working, open `System Preferences > Sound` and change your
|
||||
If Background Music crashes and your audio stops working, open `System Settings > Sound` and change your
|
||||
system's default output device to something other than the **Background Music device**. If it already is, then
|
||||
change the default device and then change it back again.
|
||||
|
||||
Make sure you allow "microphone access" when you first run Background Music. If you denied it, go to
|
||||
`System Preferences > Security & Privacy > Privacy > Microphone`, find Background Music in the list
|
||||
`System Settings > Security & Privacy > Privacy > Microphone`, find Background Music in the list
|
||||
and check the box next to it. Background Music doesn't actually listen to your microphone. It needs
|
||||
the permission because it gets your system audio from its virtual input device, which macOS counts
|
||||
as a microphone. (We're working on it in [#177](/../../issues/177).)
|
||||
@@ -169,16 +169,16 @@ meeting volume.
|
||||
|
||||
- **Only 2-channel (stereo) audio devices are currently supported for output.**
|
||||
|
||||
- **VLC pauses iTunes or Spotify when playing, and stops Background Music from unpausing your music afterward.**
|
||||
- **VLC pauses iTunes or Spotify when playing, and stops Background Music from unpausing your music afterward.**
|
||||
|
||||
- Under VLC's preferences, select **Show All**. Navigate to **Interface > Main interfaces > macosx** and change *Control external music players* to either *Do nothing* or *Pause and resume iTunes/Spotify*.
|
||||
- Under VLC's preferences, select **Show All**. Navigate to **Interface > Main interfaces > macosx** and change *Control external music players* to either *Do nothing* or *Pause and resume iTunes/Spotify*.
|
||||
|
||||
- **Skype pauses iTunes during calls.**
|
||||
- **Skype pauses iTunes during calls.**
|
||||
|
||||
- To disable this, uncheck *Pause iTunes during calls* on the **General** tab of **Skype**'s preferences.
|
||||
|
||||
- **Plugging in or unplugging headphones when Background Music isn't running causes silence in the system audio.**
|
||||
- Navigate to **System Preferences > Sound**. Click the **Output** tab and change your default output device to something other than the **Background Music** device. Alternatively, press **Option + Click** on the sound icon within the menu bar to select a different output device. This happens when macOS remembers that the **Background Music** device was your default audio device the last time you used (or didn't use) headphones.
|
||||
- **Plugging in or unplugging headphones when Background Music isn't running causes silence in the system audio.**
|
||||
- Navigate to **System Settings > Sound**. Click the **Output** tab and change your default output device to something other than the **Background Music** device. Alternatively, press **Option + Click** on the sound icon within the menu bar to select a different output device. This happens when macOS remembers that the **Background Music** device was your default audio device the last time you used (or didn't use) headphones.
|
||||
|
||||
- **[A Chrome bug](https://bugs.chromium.org/p/chromium/issues/detail?id=557620) stops Chrome from switching to the Background Music device after you open Background Music.**
|
||||
- Chrome's audio will still play, but **Background Music** won't be aware of it.
|
||||
@@ -220,7 +220,7 @@ Issues](https://github.com/kyleneideck/BackgroundMusic/issues).
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2016-2021 [Background Music contributors](https://github.com/kyleneideck/BackgroundMusic/graphs/contributors).
|
||||
Copyright © 2016-2024 [Background Music contributors](https://github.com/kyleneideck/BackgroundMusic/graphs/contributors).
|
||||
Licensed under [GPLv2](https://www.gnu.org/licenses/gpl-2.0.html), or any later version.
|
||||
|
||||
**Background Music** includes code from:
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// BGM_Types.h
|
||||
// SharedSource
|
||||
//
|
||||
// Copyright © 2016, 2017, 2019 Kyle Neideck
|
||||
// Copyright © 2016, 2017, 2019, 2024 Kyle Neideck
|
||||
//
|
||||
|
||||
#ifndef SharedSource__BGM_Types
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
static const char* const kBGMProjectURL = "https://github.com/kyleneideck/BackgroundMusic";
|
||||
static const char* const kBGMIssueTrackerURL = "https://github.com/kyleneideck/BackgroundMusic/issues";
|
||||
static const char* const kBGMContributorsURL = "https://github.com/kyleneideck/BackgroundMusic/graphs/contributors";
|
||||
|
||||
#pragma mark IDs
|
||||
|
||||
|
||||
+12
-2
@@ -19,7 +19,7 @@
|
||||
#
|
||||
# build_and_install.sh
|
||||
#
|
||||
# Copyright © 2016-2022 Kyle Neideck
|
||||
# Copyright © 2016-2022, 2024 Kyle Neideck
|
||||
# Copyright © 2016 Nick Jacques
|
||||
#
|
||||
# Builds and installs BGMApp, BGMDriver and BGMXPCHelper. Requires xcodebuild and Xcode.
|
||||
@@ -136,7 +136,7 @@ BUILD_FAILED_ERROR_MSG="A build command failed. Probably a compilation error."
|
||||
BGMAPP_FAILED_TO_START_ERROR_MSG="Background Music (${APP_PATH}/${APP_DIR}) didn't seem to start \
|
||||
up. It might just be taking a while.
|
||||
|
||||
If it didn't install correctly, you'll need to open the Sound control panel in System Preferences \
|
||||
If it didn't install correctly, you'll need to open the Sound control panel in System Settings \
|
||||
and change your output device at least once. Your sound probably won't work until you do. (Or you \
|
||||
restart your computer.)
|
||||
|
||||
@@ -641,6 +641,16 @@ if [[ "${XCODEBUILD_ACTION}" == "install" ]]; then
|
||||
SUDO="sudo"
|
||||
ACTIONING="Installing"
|
||||
DSTROOT_ARG="DSTROOT=/"
|
||||
# Work around an Xcode (15.2) bug where xcodebuild incorrectly detects a dependency cycle if
|
||||
# DSTROOT is set to /.
|
||||
for v in /Volumes/*; do
|
||||
if [[ "$(realpath "$v")" == "/" ]]; then
|
||||
DSTROOT_ARG="DSTROOT=$v"
|
||||
echo "Set DSTROOT_ARG to ${DSTROOT_ARG} to work around an Xcode bug." >> ${LOG_FILE}
|
||||
break
|
||||
fi
|
||||
done
|
||||
echo "DSTROOT_ARG: ${DSTROOT_ARG}." >> ${LOG_FILE}
|
||||
elif [[ "${XCODEBUILD_ACTION}" == "archive" ]]; then
|
||||
SUDO=""
|
||||
ACTIONING="Building and archiving"
|
||||
|
||||
+7
-1
@@ -21,6 +21,7 @@
|
||||
#
|
||||
# Copyright © 2017-2022 Kyle Neideck
|
||||
# Copyright © 2016, 2017 Takayama Fumihiko
|
||||
# Copyright © 2023 modue sp. z o.o.
|
||||
#
|
||||
# Builds Background Music and packages it into a .pkg file. Call this script with -d to use the
|
||||
# debug build configuration.
|
||||
@@ -141,7 +142,12 @@ fi
|
||||
echo "Compiling ListInputDevices"
|
||||
|
||||
if ! [[ $packaging_operation == "repackage" ]]; then
|
||||
swiftc pkg/ListInputDevices.swift -o pkg/ListInputDevices
|
||||
echo "Compiling ListInputDevices"
|
||||
swiftc pkg/ListInputDevices.swift -o pkg/ListInputDevices-x86_64 -target x86_64-apple-macos13.0
|
||||
swiftc pkg/ListInputDevices.swift -o pkg/ListInputDevices-arm64 -target arm64-apple-macos13.0
|
||||
# Combine the x86_64 and arm64 binaries into a universal binary.
|
||||
lipo -create pkg/ListInputDevices-x86_64 pkg/ListInputDevices-arm64 -output pkg/ListInputDevices
|
||||
rm pkg/ListInputDevices-x86_64 pkg/ListInputDevices-arm64
|
||||
fi
|
||||
|
||||
# --------------------------------------------------
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<volume-check>
|
||||
<allowed-os-versions>
|
||||
<!-- TODO: Get this from the Xcode project files instead of hardcoding it. -->
|
||||
<os-version min="10.9" />
|
||||
<os-version min="10.13" />
|
||||
</allowed-os-versions>
|
||||
</volume-check>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<pkg-ref id="com.bearisdriving.BGM"/>
|
||||
|
||||
<options customize="never" require-scripts="false" />
|
||||
<options customize="never" require-scripts="false" hostArchitectures="arm64,x86_64" />
|
||||
|
||||
<choices-outline>
|
||||
<line choice="default">
|
||||
|
||||
Executable → Regular
+28
-8
@@ -19,7 +19,8 @@
|
||||
#
|
||||
# postinstall
|
||||
#
|
||||
# Copyright © 2017-2022 Kyle Neideck
|
||||
# Copyright © 2017-2022, 2024 Kyle Neideck
|
||||
# Copyright © 2023 modue sp. z o.o.
|
||||
#
|
||||
|
||||
# Make sure we use the built-in versions of programs, for consistency. Probably not necessary
|
||||
@@ -31,6 +32,13 @@ function log {
|
||||
echo "$@"
|
||||
}
|
||||
|
||||
function log_output {
|
||||
while read line
|
||||
do
|
||||
log "$line"
|
||||
done < /dev/stdin
|
||||
}
|
||||
|
||||
coreaudiod_plist="/System/Library/LaunchDaemons/com.apple.audio.coreaudiod.plist"
|
||||
dest_volume="$3"
|
||||
xpc_helper_install_path="$(bash safe_install_dir.sh -y)"
|
||||
@@ -44,6 +52,17 @@ log "Installing BGMXPCHelper to $xpc_helper_install_path"
|
||||
rm -rf "${xpc_helper_install_path}/BGMXPCHelper.xpc"
|
||||
cp -Rf "BGMXPCHelper.xpc" "$xpc_helper_install_path"
|
||||
|
||||
# Remove the quarantine attribute from BGMXPCHelper. Since macOS 14.0, this is needed to keep
|
||||
# Gatekeeper from trying to show a permission prompt when BGMXPCHelper is launched. That would
|
||||
# fail because BGMXPCHelper is a daemon, and Gatekeeper would prevent it from launching.
|
||||
#
|
||||
# TODO: I think, ideally, we should use the new Service Management API to install BGMXPCHelper,
|
||||
# which would probably avoid this issue. See
|
||||
# <https://developer.apple.com/documentation/servicemanagement/updating_your_app_package_installer_to_use_the_new_service_management_api>.
|
||||
log "Removing com.apple.quarantine attribute from BGMXPCHelper."
|
||||
sudo xattr -dr com.apple.quarantine "${xpc_helper_install_path}/BGMXPCHelper.xpc" 2>&1 | log_output
|
||||
ls -lah@ "${xpc_helper_install_path}/BGMXPCHelper.xpc" 2>&1 | log_output
|
||||
|
||||
# TODO: Fail the install and show an error message if this fails.
|
||||
bash "post_install.sh" "$xpc_helper_install_path" "BGMXPCHelper.xpc/Contents/MacOS/BGMXPCHelper" "."
|
||||
|
||||
@@ -53,13 +72,14 @@ bash "post_install.sh" "$xpc_helper_install_path" "BGMXPCHelper.xpc/Contents/Mac
|
||||
# some of these commands don't work with older versions of launchctl, so I figure there's no
|
||||
# harm in trying a bunch of different ways (which should all work).
|
||||
(sudo launchctl kickstart -k system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
launchctl kill SIGTERM system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
launchctl kill TERM system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
launchctl kill 15 system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
launchctl kill -15 system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
(launchctl unload "$coreaudiod_plist" &>/dev/null && \
|
||||
launchctl load "$coreaudiod_plist" &>/dev/null) || \
|
||||
killall coreaudiod &>/dev/null) && \
|
||||
sudo launchctl kill SIGTERM system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo launchctl kill TERM system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo launchctl kill 15 system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo launchctl kill -15 system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo killall coreaudiod &>/dev/null || \
|
||||
(sudo launchctl unload "$coreaudiod_plist" &>/dev/null && \
|
||||
sudo launchctl load "$coreaudiod_plist" &>/dev/null)
|
||||
) && \
|
||||
sleep 2
|
||||
|
||||
# Wait until coreaudiod has restarted and BGMDevice is ready to use.
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ if [ "$user_prompt" == "y" ] || [ "$user_prompt" == "Y" ]; then
|
||||
# Invalidate sudo ticket
|
||||
sudo -k
|
||||
|
||||
# Open System Preferences and go to Sound > Output.
|
||||
# Open System Settings and go to Sound > Output.
|
||||
osascript -e 'tell application id "com.apple.systempreferences"
|
||||
activate
|
||||
reveal anchor "output" of pane id "com.apple.preference.sound"
|
||||
|
||||
Reference in New Issue
Block a user