From 4eb7053b5e3b4eed62394ee189cfe1de4b6c7d88 Mon Sep 17 00:00:00 2001 From: Filipe Moreira Date: Wed, 30 Sep 2026 15:48:50 -0300 Subject: [PATCH] chore: remove every reference to MultiMonitorTool and SoundVolumeView 1.6 controls displays and audio with Windows' own APIs and bundles none of the NirSoft tools, but the code, comments, tests and docs still named them. - AppPaths no longer deletes the old tools from the tools folder at startup. - Comments in CoreAudio, NativeDisplays, AudioNaming, DisplayIdentity and ConsoleEngine now say what the formats are ("the format 1.5 saved") instead of naming the tool that used to write them. The formats themselves do not change, so settings and backups made by 1.5 keep working. - Two test names that cited the tools are renamed; docs/TESTING.md drops the check that the tools folder is cleaned. Kept on purpose: the released changelog sections (they record what those versions did) and THIRD_PARTY_NOTICES.md (the notice for the 1.5 releases that did ship the tools). Co-Authored-By: Claude Sonnet 5.5 --- CHANGELOG.en-US.md | 1 + CHANGELOG.md | 1 + docs/TESTING.md | 7 +++---- src/ConsoleMode/Native/CoreAudio.cs | 6 +++--- src/ConsoleMode/Native/NativeDisplays.cs | 4 ++-- src/ConsoleMode/Services/AppPaths.cs | 6 ------ src/ConsoleMode/Services/AudioNaming.cs | 6 +++--- src/ConsoleMode/Services/ConsoleEngine.cs | 5 ++--- src/ConsoleMode/Services/DisplayIdentity.cs | 6 +++--- tests/ConsoleMode.Tests/AudioNamingTests.cs | 2 +- tests/ConsoleMode.Tests/DisplayIdentityTests.cs | 4 ++-- 11 files changed, 21 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index cb8afce..32d3f97 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -12,6 +12,7 @@ English (US) release notes, mirroring CHANGELOG.md (Brazilian Portuguese). Befor ### Behind the scenes - Publishing a stable release now also opens the update PR on winget (`winget install lippdev.ConsoleMode`). Test versions are skipped. (#106) +- The code no longer mentions MultiMonitorTool or SoundVolumeView, and the cleanup of their old files in the `tools` folder is gone: anyone updating straight from 1.5 keeps those two files until they delete them by hand. (#119) ## [1.6.0-alpha.2] ### Changes diff --git a/CHANGELOG.md b/CHANGELOG.md index 75825b3..764a51f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Notas em português do Brasil; a versão em inglês (Estados Unidos) fica em `CH ### Por trás dos panos - Publicar uma versão estável agora também abre o PR de atualização no winget (`winget install lippdev.ConsoleMode`). Versões de teste ficam de fora. (#106) +- O código não cita mais o MultiMonitorTool nem o SoundVolumeView, e a limpeza dos arquivos antigos deles na pasta `tools` saiu: quem atualiza direto da 1.5 mantém esses dois arquivos até apagá-los à mão. (#119) ## [1.6.0-alpha.2] ### Mudanças diff --git a/docs/TESTING.md b/docs/TESTING.md index cc2fb1f..6d93202 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -116,21 +116,20 @@ Pré-condições: Ajustes → Interface = **Automático** (padrão). ## Áudio com código próprio (issue #91) -Pré-condições: 1.6 instalada por cima da 1.5, com a configuração da 1.5 (saída de áudio escolhida). A 1.6 não usa mais o SoundVolumeView; o arquivo antigo em `tools` é apagado ao abrir o app. +Pré-condições: 1.6 instalada por cima da 1.5, com a configuração da 1.5 (saída de áudio escolhida). - [ ] 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: ______ +- [ ] A saída que já estava escolhida na 1.5 continua selecionada depois de atualizar (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: ______ - [ ] Ao restaurar a mesa, o som volta para a saída de antes do modo console. Resultado: ______ -- [ ] A pasta `tools` não tem mais `SoundVolumeView.exe` nem `MultiMonitorTool.exe` depois de abrir o app. Resultado: ______ ## Telas com código próprio (issue #91) -Pré-condições: 1.6 instalada por cima da 1.5, com a configuração da 1.5 (tela de jogo e telas a esconder escolhidas). Anote antes, na 1.5, como o mapa de telas aparece, para comparar. A 1.6 não usa mais o MultiMonitorTool; o arquivo antigo em `tools` é apagado ao abrir o app. +Pré-condições: 1.6 instalada por cima da 1.5, com a configuração da 1.5 (tela de jogo e telas a esconder escolhidas). Anote antes, na 1.5, como o mapa de telas aparece, para comparar. ### Lista e identidade diff --git a/src/ConsoleMode/Native/CoreAudio.cs b/src/ConsoleMode/Native/CoreAudio.cs index 61cf9f6..ca9d978 100644 --- a/src/ConsoleMode/Native/CoreAudio.cs +++ b/src/ConsoleMode/Native/CoreAudio.cs @@ -4,9 +4,9 @@ namespace ConsoleMode.Native; /// /// Windows Core Audio (MMDevice API) for the output devices: list, switch the default, enable a -/// disabled one, volume and mute. Replaces SoundVolumeView (issue #91). +/// disabled one, volume and mute (issue #91). /// Switching the default output uses IPolicyConfig, which Windows doesn't document but has kept -/// stable since Windows 7; the Control Panel, SoundVolumeView, EarTrumpet and AudioSwitcher use it. +/// stable since Windows 7; the Control Panel, EarTrumpet and AudioSwitcher use it. /// internal static class CoreAudio { @@ -24,7 +24,7 @@ public sealed record Endpoint(string Id, string Name, string AdapterName, bool I // PKEY_DeviceInterface_FriendlyName: the adapter ("Realtek(R) Audio", "NVIDIA High Definition Audio"). private static readonly PropertyKey InterfaceFriendlyNameKey = new(new Guid("026e516e-b814-414b-83cd-856d6fef4822"), 2); - /// Active, disabled and unplugged outputs (the same set SoundVolumeView listed). + /// Active, disabled and unplugged outputs. public static List ListRenderEndpoints() { var result = new List(); diff --git a/src/ConsoleMode/Native/NativeDisplays.cs b/src/ConsoleMode/Native/NativeDisplays.cs index f72b45e..d8a69ae 100644 --- a/src/ConsoleMode/Native/NativeDisplays.cs +++ b/src/ConsoleMode/Native/NativeDisplays.cs @@ -7,8 +7,8 @@ namespace ConsoleMode.Native; /// -/// Displays through Windows' own APIs (CCD, ChangeDisplaySettingsEx, DDC/CI via dxva2), replacing -/// MultiMonitorTool (issue #91). Monitors are named by their GDI source (\\.\DISPLAYn) like before. +/// Displays through Windows' own APIs (CCD, ChangeDisplaySettingsEx, DDC/CI via dxva2) (issue #91). +/// Monitors are named by their GDI source (\\.\DISPLAYn), the same names 1.5 saved. /// internal static class NativeDisplays { diff --git a/src/ConsoleMode/Services/AppPaths.cs b/src/ConsoleMode/Services/AppPaths.cs index 701bbc5..5475015 100644 --- a/src/ConsoleMode/Services/AppPaths.cs +++ b/src/ConsoleMode/Services/AppPaths.cs @@ -98,12 +98,6 @@ public static void Initialize() try { File.Copy(rtssBeside, rtssDest, true); } catch { /* ignore */ } } - // Up to 1.5 the NirSoft tools were extracted here; 1.6 is all our own code (issue #91). - foreach (var name in new[] { "MultiMonitorTool.exe", "SoundVolumeView.exe" }) - { - try { File.Delete(Path.Combine(ToolsDir, name)); } catch { /* in use or read-only: harmless */ } - } - RtssCliPath = FirstExisting(Path.Combine(ToolsDir, "rtss-cli.exe"), Path.Combine(ExeDir, "rtss-cli.exe")); ConfigPath = Path.Combine(DataDir, "config.json"); diff --git a/src/ConsoleMode/Services/AudioNaming.cs b/src/ConsoleMode/Services/AudioNaming.cs index 5853aee..6cba623 100644 --- a/src/ConsoleMode/Services/AudioNaming.cs +++ b/src/ConsoleMode/Services/AudioNaming.cs @@ -1,14 +1,14 @@ namespace ConsoleMode.Services; /// -/// Names and IDs of audio outputs, shared by the SoundVolumeView and the native (Core Audio) -/// backends so the saved setting (AudioDeviceId) and the restore backup work with either. +/// Names and IDs of audio outputs. The format is the one 1.5 saved (AudioDeviceId in +/// config.json and the restore backup), so both keep working after an update. /// Pure, so it's tested. /// public static class AudioNaming { /// - /// SoundVolumeView's "Command-Line Friendly ID" for an output: + /// The "friendly ID" of an output, as saved since 1.5: /// {adapter}\Device\{endpoint}\Render, e.g. Realtek(R) Audio\Device\Speakers\Render. /// public static string FriendlyId(string adapterName, string endpointName) => diff --git a/src/ConsoleMode/Services/ConsoleEngine.cs b/src/ConsoleMode/Services/ConsoleEngine.cs index 4148f74..c360d9d 100644 --- a/src/ConsoleMode/Services/ConsoleEngine.cs +++ b/src/ConsoleMode/Services/ConsoleEngine.cs @@ -508,9 +508,8 @@ private void UpdatePendingTarget() } /// - /// 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. + /// Switching the output is best effort: a Core Audio error is logged and the session goes on, + /// instead of rolling back the whole start after the screens were already switched. /// private bool TrySetOutput(string friendlyId) { diff --git a/src/ConsoleMode/Services/DisplayIdentity.cs b/src/ConsoleMode/Services/DisplayIdentity.cs index 27af1fb..8da9441 100644 --- a/src/ConsoleMode/Services/DisplayIdentity.cs +++ b/src/ConsoleMode/Services/DisplayIdentity.cs @@ -4,7 +4,7 @@ namespace ConsoleMode.Services; /// -/// One monitor in the layout backup (MultiMonitorTool's .cfg format, kept for compatibility). +/// One monitor in the layout backup (the .cfg format 1.5 wrote, kept so its backups can be restored). /// Orientation is DEVMODE.dmDisplayOrientation: 0 landscape, 1 = 90°, 2 = 180°, 3 = 270°. /// public sealed record LayoutEntry(string Name, string MonitorId, string Serial, int BitsPerPixel, @@ -15,7 +15,7 @@ public sealed record EdidInfo(string Name, string Serial, int PreferredWidth, in /// /// Monitor identity and layout-file helpers for the native display backend (issue #91). They -/// produce the same values MultiMonitorTool did, so saved settings and backups keep working. +/// produce the same values 1.5 saved, so saved settings and backups keep working. /// Pure, so it's tested. /// public static class DisplayIdentity @@ -37,7 +37,7 @@ public static bool TryParseDevicePath(string? devicePath, out string hardwareId, } /// - /// MultiMonitorTool's "Monitor ID" (the device ID Windows gives the monitor), e.g. + /// The monitor ID saved since 1.5 (the device ID Windows gives the monitor), e.g. /// MONITOR\GSM5B7F\{4d36e96e-e325-11ce-bfc1-08002be10318}\0004; the last part is the /// monitor's driver key. It's what MonitorInfo.StableId saves in config.json. /// diff --git a/tests/ConsoleMode.Tests/AudioNamingTests.cs b/tests/ConsoleMode.Tests/AudioNamingTests.cs index fbda216..d707e1b 100644 --- a/tests/ConsoleMode.Tests/AudioNamingTests.cs +++ b/tests/ConsoleMode.Tests/AudioNamingTests.cs @@ -7,7 +7,7 @@ public sealed class AudioNamingTests [Theory] [InlineData("Realtek(R) Audio", "Speakers", @"Realtek(R) Audio\Device\Speakers\Render")] [InlineData("NVIDIA High Definition Audio", "LG TV SSCR2", @"NVIDIA High Definition Audio\Device\LG TV SSCR2\Render")] - public void Friendly_id_matches_the_one_saved_by_SoundVolumeView(string adapter, string endpoint, string expected) => + public void Friendly_id_matches_the_one_saved_by_1_5(string adapter, string endpoint, string expected) => Assert.Equal(expected, AudioNaming.FriendlyId(adapter, endpoint)); [Theory] diff --git a/tests/ConsoleMode.Tests/DisplayIdentityTests.cs b/tests/ConsoleMode.Tests/DisplayIdentityTests.cs index 774c3ab..0e2ffb6 100644 --- a/tests/ConsoleMode.Tests/DisplayIdentityTests.cs +++ b/tests/ConsoleMode.Tests/DisplayIdentityTests.cs @@ -18,7 +18,7 @@ public void Device_path_gives_the_hardware_id_and_the_device_instance() } [Fact] - public void Monitor_id_has_MultiMonitorTools_format() + public void Monitor_id_has_the_format_saved_by_1_5() { Assert.Equal(@"MONITOR\GSM5B7F\{4d36e96e-e325-11ce-bfc1-08002be10318}\0004", DisplayIdentity.MonitorId("GSM5B7F", @"{4d36e96e-e325-11ce-bfc1-08002be10318}\0004")); @@ -115,7 +115,7 @@ public void Layout_file_writes_landscape_when_no_orientation_is_given() [Fact] public void A_backup_made_by_1_5_is_written_back_unchanged() { - // The shape of a real 1.5 backup (MultiMonitorTool): a portrait side monitor and a TV that was off. + // The shape of a real 1.5 backup: a portrait side monitor and a TV that was off. string[] original = [ "[Monitor0]", @"Name=\\.\DISPLAY1", @"MonitorID=MONITOR\TCL1003\{4d36e96e-e325-11ce-bfc1-08002be10318}\0003",