Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions BGMApp/BGMApp/BGMAppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -369,12 +369,18 @@ - (void) initVolumesMenuSection {

- (void) applicationWillTerminate:(NSNotification*)aNotification {
#pragma unused (aNotification)

DebugMsg("BGMAppDelegate::applicationWillTerminate");

// Deactivate control sync and playthrough before changing the default device back. This
// prevents the default device change from triggering volume sync listeners that could leave
// the output device at the wrong volume. See
// https://github.com/kyleneideck/BackgroundMusic/issues/841
[audioDevices prepareForTermination];

// Change the user's default output device back.
NSError* error = [audioDevices unsetBGMDeviceAsOSDefault];

if (error) {
[self showSetDeviceAsDefaultError:error
message:@"Failed to reset your system's audio output device."
Expand Down
5 changes: 5 additions & 0 deletions BGMApp/BGMApp/BGMAudioDeviceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ static const int kBGMErrorCode_ReturningEarly = 2;
// Replace BGMDevice as the default device with the output device
- (NSError* __nullable) unsetBGMDeviceAsOSDefault;

// Prepare for app termination by deactivating control sync and playthrough before the default
// device is changed back. This prevents stale volume state from being left on the output device.
// Must be called before unsetBGMDeviceAsOSDefault.
- (void) prepareForTermination;

#ifdef __cplusplus
// The virtual device published by BGMDriver.
- (BGMBackgroundMusicDevice) bgmDevice;
Expand Down
27 changes: 27 additions & 0 deletions BGMApp/BGMApp/BGMAudioDeviceManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,33 @@ - (NSError* __nullable) setBGMDeviceAsOSDefault {
return nil;
}

- (void) prepareForTermination {
DebugMsg("BGMAudioDeviceManager::prepareForTermination: Deactivating control sync and "
"playthrough before termination");

@try {
[stateLock lock];

// Deactivate control sync BEFORE changing the default device. This removes the volume/mute
// listeners so that the default device change doesn't trigger any stale volume sync that
// could leave the output device at the wrong volume.
// See https://github.com/kyleneideck/BackgroundMusic/issues/841
BGMLogAndSwallowExceptions("BGMAudioDeviceManager::prepareForTermination", [&] {
deviceControlSync.Deactivate();
});

// Stop playthrough so we don't try to pass audio during shutdown.
BGMLogAndSwallowExceptions("BGMAudioDeviceManager::prepareForTermination", [&] {
playThrough.Deactivate();
});
BGMLogAndSwallowExceptions("BGMAudioDeviceManager::prepareForTermination", [&] {
playThrough_UISounds.Deactivate();
});
} @finally {
[stateLock unlock];
}
}

- (NSError* __nullable) unsetBGMDeviceAsOSDefault {
// Copy the devices so we can call the HAL without holding stateLock. See startPlayThroughSync.
BGMBackgroundMusicDevice* bgmDeviceCopy;
Expand Down
4 changes: 4 additions & 0 deletions BGMApp/BGMApp/BGMTermination.mm
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@
// it's better for things to work even if BGMXPCHelper isn't installed.
if(sAudioDevices)
{
// Deactivate control sync and playthrough before changing the default device back.
// This prevents the default device change from triggering volume sync that could leave
// the output device at the wrong volume.
[sAudioDevices prepareForTermination];
[sAudioDevices unsetBGMDeviceAsOSDefault];
}
}
Expand Down
23 changes: 23 additions & 0 deletions BGMApp/BGMApp/_uninstall-non-interactive.sh
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,29 @@ osascript -e 'tell application id "com.apple.finder"
|| rm -rf "${trash_dir}" \
|| true

# Clean up BGMDevice entries from macOS audio preferences to prevent persistent low volume
# after uninstall. See https://github.com/kyleneideck/BackgroundMusic/issues/841
echo "Cleaning up audio device preferences."
for plist_dir in "$HOME/Library/Preferences" "/Library/Preferences/Audio"; do
for plist in "com.apple.audio.DeviceSettings.plist" "com.apple.audio.SystemSettings.plist"; do
plist_path="${plist_dir}/${plist}"
if [ -f "${plist_path}" ]; then
# Remove entries keyed by BGMDevice UIDs
for uid in "BGMDevice" "BGMDevice_UISounds"; do
defaults delete "${plist_path}" "${uid}" &>/dev/null || true
done
fi
done
done
# Also clean up ByHost audio preferences
for byhost_plist in "$HOME/Library/Preferences/ByHost"/com.apple.audio.*.plist; do
if [ -f "${byhost_plist}" ]; then
for uid in "BGMDevice" "BGMDevice_UISounds"; do
defaults delete "${byhost_plist}" "${uid}" &>/dev/null || true
done
fi
done

echo "Restarting Core Audio."
# Wait a little because moving files to the trash plays a short sound.
sleep 2
Expand Down