Skip to content
Merged
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
1 change: 1 addition & 0 deletions docs/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ Pré-condições: 1.6 instalada por cima da 1.5, com a configuração da 1.5 (sa
- [ ] Ajustes → Saída de áudio lista as mesmas saídas que na 1.5, com os mesmos nomes, e as desativadas aparecem com o sufixo "[Desabilitado]". Resultado: ______
- [ ] A saída que já estava escolhida com o SoundVolumeView continua selecionada depois de atualizar da 1.5 (o ID salvo é o mesmo). Resultado: ______
- [ ] Entrar no modo console com uma saída fixa (ex.: HDMI da TV): o som passa para ela, inclusive em apps de chamada (papel "comunicações"). O log mostra `Áudio: saída padrão = …`. Resultado: ______
- [ ] Se a troca de saída falhar (ex.: o dispositivo some no meio), a sessão continua e o log mostra `Áudio: não foi possível trocar para …`; a mesa não é desfeita. Resultado: ______
- [ ] "A que aparecer ao conectar (TV)" com a TV começando **desligada**: quando a TV liga, o som vai para o HDMI dela. Resultado: ______
- [ ] Uma saída **desabilitada** em Configurações → Som: escolhê-la liga a saída e o som vai para ela. Resultado: ______
- [ ] Menu da sessão (Select + Y): o volume inicial é o do Windows; ◀/▶ muda de 5 em 5 e tira o mudo; A alterna o mudo. Resultado: ______
Expand Down
32 changes: 26 additions & 6 deletions src/ConsoleMode/Services/ConsoleEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public void Start(AppConfig config, MonitorInfo? focusInfo, Func<ScreenRect?, bo
var target = devices.FirstOrDefault(d => d.FriendlyId == config.AudioDeviceId);
if (target is { IsActive: true })
{
Audio.SetOutput(config.AudioDeviceId);
TrySetOutput(config.AudioDeviceId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this switch fails, State.AudioDeviceId still contains the configured target set earlier in Start, but the OS default remains on the previous output. The session menu treats this field as the current output for its label, selection, and volume/mute actions, so it can show and control the wrong device.

Technical details
# Keep session audio state accurate after a failed startup switch

## Affected sites
- `src/ConsoleMode/Services/ConsoleEngine.cs:45` — initializes `State.AudioDeviceId` to the configured target before the switch attempt.
- `src/ConsoleMode/Services/ConsoleEngine.cs:141` — now ignores the failed `TrySetOutput` result and continues with that target in state.
- `src/ConsoleMode/ViewModels/MainViewModel.SessionMenu.cs:131-145` — treats `State.AudioDeviceId` as the current output for the menu label, volume, and mute.
- `src/ConsoleMode/ViewModels/MainViewModel.SessionMenu.cs:202-204` — marks that target as selected in the output picker.

## Required outcome
- After a failed startup switch, the session menu's displayed/selected output and volume/mute operations must correspond to the actual current output, rather than the requested target that failed.

CompleteAudioWatch();
}
else
Expand Down Expand Up @@ -465,9 +465,11 @@ private void UpdateAutoSwitch()

var pick = Audio.PickNewDevice(newly, State.AudioDeviceHint, focus);
if (pick is null) return;
Audio.SetOutput(pick.FriendlyId);
State.AudioDeviceId = pick.FriendlyId;
State.LastAudioSwitchName = pick.Name;
if (TrySetOutput(pick.FriendlyId))
{
State.AudioDeviceId = pick.FriendlyId;
State.LastAudioSwitchName = pick.Name;
}
CompleteAudioWatch();
}

Expand All @@ -477,8 +479,26 @@ private void UpdatePendingTarget()
var devices = Audio.GetDevices(true);
var target = devices.FirstOrDefault(d => d.FriendlyId == State.AudioDeviceId);
if (target is not { IsActive: true }) return;
Audio.SetOutput(target.FriendlyId);
State.LastAudioSwitchName = target.Name;
if (TrySetOutput(target.FriendlyId)) State.LastAudioSwitchName = target.Name;
CompleteAudioWatch();
}

/// <summary>
/// Switching the output is best effort, as it was with SoundVolumeView (its failures were ignored):
/// a Core Audio error is logged and the session goes on, instead of rolling back the whole start
/// after the screens were already switched.
/// </summary>
private bool TrySetOutput(string friendlyId)
{
try
{
Audio.SetOutput(friendlyId);
return true;
}
catch (Exception ex)
{
AppLog.Write($"Áudio: não foi possível trocar para {friendlyId}: {ex.Message}");
return false;
}
}
}
Loading