v3.4: handle-leak fix, Realtek ASIO block, device notifications, quick profile switch, hotkey announcements
Freezes the v3.4 feature set (everything since the v3.3 public release): - Fix the receiver handle leak: the 3-second device-refresh timer reopened the configured ASIO driver every tick, and Realtek's ASIO driver leaks Event+Mutant handles on every open. Cache the ASIO probe per driver so it is opened once. - Realtek ASIO block: detect a Realtek ASIO driver, offer once to disable it, and never touch it again if disabled; Options-menu toggle to reverse. Global config. - Device hot-plug is event-driven (AudioDeviceChangeNotifier) instead of a 3s poll; debounced refresh, falls back to polling if registration fails. - Quick profile switch: new global hotkey opens an NVDA-friendly popup of all profiles (current marked); Enter/click switches; plays a new "profile menu open" cue with Preferences mute + custom-sound. - Announce assigned global hotkeys on the controls/menu items they drive (NVDA reads "press X anywhere"). File > Open already had Ctrl+O. - Held-back changes folded in: config-folder migration, codec-column fix, Tailscale endpoint network-prune, empty-password guard, and the handle-leak diagnostics (ProcessSelfMeter, HandleTypeProbe). Version bumped to 3.4.0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
fc451ba3e3
commit
dd70613017
@@ -24,6 +24,11 @@ internal static class Program
|
||||
|
||||
ApplicationConfiguration.Initialize();
|
||||
|
||||
// Relocate any pre-2026-06-07 config/profiles into config\ before anything reads them.
|
||||
// Idempotent and best-effort; also upgrades users coming from an older build. The result
|
||||
// is shown to the user once (after the single-instance guard) if files actually moved.
|
||||
var layoutMigration = RemSound.Core.AppConfig.MigrateLegacyLayoutIfNeeded();
|
||||
|
||||
// Single-instance guard. RemSound must never run as two copies at once: with the
|
||||
// auto-updater relaunching the app, a copy that didn't exit cleanly used to leave two
|
||||
// (then more) copies running, each playing received audio — Andre's "stacked and
|
||||
@@ -74,6 +79,14 @@ internal static class Program
|
||||
// is per-thread and modifier-aware: bare F1 only, so Shift/Ctrl/Alt+F1 stay free.
|
||||
HelpLauncher.Install();
|
||||
|
||||
// One-time "your settings moved" notice — only the launch that actually relocated files
|
||||
// shows it (idempotent migration ⇒ MovedAnything is false on every later launch). Shown
|
||||
// here, after the guard and before the profile picker, so the user reads it once up front.
|
||||
if (layoutMigration.MovedAnything)
|
||||
{
|
||||
ShowLayoutMigrationNotice(layoutMigration);
|
||||
}
|
||||
|
||||
// Outer loop: lets ProfileManagementDialog change the profiles folder mid-session.
|
||||
// When that happens, MainForm sets ReloadFromScratch=true, we re-read AppConfig, build
|
||||
// a fresh ProfileStore, and re-show ProfileSelectionDialog so the user picks a profile
|
||||
@@ -229,4 +242,30 @@ internal static class Program
|
||||
if (!reloadFromScratch) return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>One-time, Windows-native notice telling the user their config/profiles were moved
|
||||
/// into the new <c>config\</c> folder. Only called when a real migration happened. TaskDialog
|
||||
/// (not a hand-rolled Form) so a screen reader reads the whole message automatically.</summary>
|
||||
private static void ShowLayoutMigrationNotice(RemSound.Core.AppConfig.LayoutMigrationResult migration)
|
||||
{
|
||||
var moved = new System.Collections.Generic.List<string>();
|
||||
if (migration.MovedGlobalConfig) moved.Add("- Your settings are now in: config\\global config.json");
|
||||
if (migration.MovedProfiles) moved.Add("- Your saved profiles are now in: config\\profiles\\");
|
||||
|
||||
var page = new TaskDialogPage
|
||||
{
|
||||
Caption = "RemSound settings location",
|
||||
Heading = "Your settings now live in a \"config\" folder",
|
||||
Text = "To keep the RemSound folder tidy, this update moved your existing settings into a new "
|
||||
+ "\"config\" folder inside RemSound:\n\n"
|
||||
+ string.Join("\n", moved)
|
||||
+ "\n\nNothing was lost and RemSound works exactly as before. You will only see this message once.",
|
||||
Icon = TaskDialogIcon.Information,
|
||||
Buttons = { TaskDialogButton.OK },
|
||||
DefaultButton = TaskDialogButton.OK,
|
||||
AllowCancel = true,
|
||||
};
|
||||
try { TaskDialog.ShowDialog(page); }
|
||||
catch { /* a notice must never stop RemSound from starting */ }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user