Bug: if v3.1 installed via auto-update on a profile with StartMinimised on, the tray icon's hover tooltip got stuck at the initial "RemSound - starting up" string. The snapshot tick was running and SetTooltip was being called every second with the live state, but Windows shell kept showing the original cached text on hover. The fix-by-workaround was a hide-then-re-show cycle which forced the shell to rebuild the icon registration with the latest NotifyIcon.Text. Root cause: NotifyIcon.Text values set BEFORE the icon's first NIM_ADD (i.e. while Visible=false) become the shell's "initial" tooltip when the icon eventually appears. Subsequent NIM_MODIFY calls from text changes DO propagate, but the shell tends to keep showing the original text on hover - presumably a tooltip-cache eviction quirk. In the resume-after-update-with-StartMinimised flow, the window briefly shows then BeginInvokes a Minimize that flips Visible=true before the snapshot timer has had a chance to fire, so the shell registers with the stale "starting up" string. Fix: drop the hard-coded "starting up" initial text from the controller ctor entirely. The controller now takes a Func<string> buildTooltip callback from MainForm and calls it in Minimize() right before flipping Visible=true, so the shell's NIM_ADD sees current live state instead of a stale string. The 1 Hz snapshot tick keeps working for ongoing live updates while the icon is visible. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
103 lines
6.2 KiB
XML
103 lines
6.2 KiB
XML
<Project Sdk="Microsoft.NET.Sdk">
|
|
<PropertyGroup>
|
|
<OutputType>WinExe</OutputType>
|
|
<TargetFramework>net10.0-windows</TargetFramework>
|
|
<Nullable>enable</Nullable>
|
|
<ImplicitUsings>enable</ImplicitUsings>
|
|
<UseWindowsForms>true</UseWindowsForms>
|
|
<RootNamespace>RemSound.App</RootNamespace>
|
|
<AssemblyName>RemSound</AssemblyName>
|
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
|
<ApplicationHighDpiMode>SystemAware</ApplicationHighDpiMode>
|
|
<!-- Release version. The self-updater (RemSoundUpdater) compares this against the
|
|
tag_name on the latest GitHub release; bump it on every public release. The
|
|
AssemblyVersion / FileVersion default to this value, and Assembly.GetName().Version
|
|
is what the About dialog and the updater both read. -->
|
|
<Version>3.1.1</Version>
|
|
</PropertyGroup>
|
|
|
|
<ItemGroup>
|
|
<ProjectReference Include="..\RemSound.Core\RemSound.Core.csproj" />
|
|
<ProjectReference Include="..\RemSound.Sender\RemSound.Sender.csproj" />
|
|
<ProjectReference Include="..\RemSound.Receiver\RemSound.Receiver.csproj" />
|
|
<PackageReference Include="NAudio" Version="2.3.0" />
|
|
<!-- LAME wrapper for MP3 encoding. Pulled in for the recording feature. The native
|
|
libmp3lame.dll ships with the package and is copied to the output folder. -->
|
|
<PackageReference Include="NAudio.Lame" Version="2.1.0" />
|
|
<!-- OGG container writer that wraps Concentus-encoded Opus. Same Concentus the wire
|
|
path already uses (transitive dep), so the recording-side OGG-Opus output is
|
|
byte-for-byte the same encoder we'd send on a live Opus stream. -->
|
|
<PackageReference Include="Concentus.Oggfile" Version="1.0.7" />
|
|
<!-- Pure-managed FLAC encoder (Flake). Same encoder CUETools uses; no native DLL,
|
|
no P/Invoke. Lossless, ships as managed IL, smaller files than WAV (~50%) without
|
|
sample-data loss. -->
|
|
<PackageReference Include="CUETools.Codecs.FLAKE" Version="1.0.5" />
|
|
<!-- UPnP / NAT-PMP / PCP client library for automatically opening the audio port on
|
|
the user's router so peers on the public internet can reach this machine without
|
|
manual port forwarding. Cross-protocol — picks whichever the router speaks. Used
|
|
under the AppConfig.UpnpEnabled toggle, off by default. -->
|
|
<PackageReference Include="Mono.Nat" Version="3.0.4" />
|
|
<!-- Native libopus binaries that Concentus 2.0+ auto-detects at runtime and routes
|
|
encode/decode calls through. Without this package Concentus uses its pure-managed
|
|
C# fallback, which `new`s ~15 working buffers per encode call (issue #22 on the
|
|
Concentus repo, open since 2018) and produces ~4.5 MB/s of GC pressure per
|
|
encoding lane at 10 ms frames. Switching to native via this package keeps the
|
|
encoder state allocated once (C-side) and reuses it across calls. Same encoder
|
|
settings, bit-for-bit identical audio output. Installed at the top-level project
|
|
(per the package's install guidance) so `dotnet publish` correctly trims native
|
|
binaries for irrelevant RIDs from the release output. 2026-05-23. -->
|
|
<PackageReference Include="Concentus.Native" Version="1.5.2" />
|
|
<!-- Explicit pin for the transitive Concentus.Native.NetCore. The parent package
|
|
declares a minimum version of 1.5.1, but 1.5.1 was never published to nuget.org —
|
|
only 1.5.2 was. NuGet still resolves correctly (it picks 1.5.2) but emits NU1603
|
|
as a warning, which our TreatWarningsAsErrors policy promotes to an error.
|
|
Pinning explicitly skips that warning and is self-documenting. -->
|
|
<PackageReference Include="Concentus.Native.NetCore" Version="1.5.2" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup>
|
|
<!-- All cue sounds live in a sounds\ subfolder under the publish output (moved out of
|
|
the install-root flat layout 2026-05-28). Default cue WAVs ship inside that folder;
|
|
user-supplied custom cue paths set in Preferences override the defaults at runtime.
|
|
Filenames containing a space (e.g. "record start.wav") are preserved verbatim on
|
|
copy so the load-by-filename path in TryLoadCueSound finds them exactly as written. -->
|
|
<Content Include="..\..\sounds\connect.wav">
|
|
<Link>sounds\connect.wav</Link>
|
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
</Content>
|
|
<Content Include="..\..\sounds\disconnect.wav">
|
|
<Link>sounds\disconnect.wav</Link>
|
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
</Content>
|
|
<Content Include="..\..\sounds\record start.wav">
|
|
<Link>sounds\record start.wav</Link>
|
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
</Content>
|
|
<Content Include="..\..\sounds\record stop.wav">
|
|
<Link>sounds\record stop.wav</Link>
|
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
</Content>
|
|
<!-- New cues introduced 2026-05-28: save.wav fires after a successful Save / Save As;
|
|
profile.wav fires immediately after a profile finishes loading. Both default WAVs
|
|
to be supplied by the project owner; absent files are gracefully ignored at load
|
|
time (the cue just doesn't play) so the build is fine without them. -->
|
|
<Content Include="..\..\sounds\save.wav" Condition="Exists('..\..\sounds\save.wav')">
|
|
<Link>sounds\save.wav</Link>
|
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
</Content>
|
|
<Content Include="..\..\sounds\profile.wav" Condition="Exists('..\..\sounds\profile.wav')">
|
|
<Link>sounds\profile.wav</Link>
|
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
</Content>
|
|
<!-- User manual. F1 anywhere in the app opens this via the user's default browser
|
|
(HelpLauncher.OpenManual). The PreserveNewest mode means a fresh publish overwrites
|
|
the published copy whenever the source is newer; manually-edited copies inside
|
|
publish/ get clobbered, which is correct (publish is build output, not config). -->
|
|
<Content Include="..\..\readme.html">
|
|
<Link>readme.html</Link>
|
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
</Content>
|
|
</ItemGroup>
|
|
</Project>
|