Fix UPnP close-hang, and add mnemonics to every dialog's buttons (Andre)

UPnP close hang:
- RouterPortMapper.Stop()/Dispose() does a SYNCHRONOUS DeletePortMap call to the router
  (plus StopDiscovery). When the router is slow or unresponsive that blocks — and it ran on
  the UI thread in FormClosing, so enabling UPnP could make RemSound impossible to close
  (Andre, this morning; his logs show UPnP teardown taking several seconds even on a good
  run). Moved the router teardown into the same bounded background-task pattern already used
  for the ASIO audio dispose: UPnP + audio now tear down off the UI thread, in parallel, under
  one 3s cap. Anything unfinished is reclaimed on process exit, so the window always closes.

Mnemonics on dialog buttons:
- Andre flagged the "RemSound is already running" dialog (single-instance) having no shortcut
  keys. Its three TaskDialog buttons had no & mnemonics; added Alt+S / Alt+F / Alt+C.
- Swept every dialog. Custom TaskDialog buttons and Form OK/Cancel/Close buttons that lacked
  mnemonics now have them: single-instance (Switch/Force/Cancel), save-onto-read-only
  (Save/Cancel), Add EQ band, Change/Manage profile password, Quick profile switch (Close),
  Rename peer (OK), About (Close). Cancel stays on Esc in the few dialogs where Alt+C is
  already taken (Rename peer's Clear, Service profile's peers list) — by design, not a miss.
- The rest already had mnemonics (Keyboard-shortcut import, Update-install notice, Profile
  selection, Recording settings). The dialog-accessibility gate (mnemonic uniqueness + names)
  stays green, so nothing collides.

Gate 46/46.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ednunp
2026-07-18 09:17:49 +01:00
co-authored by Claude Opus 4.8
parent a433645fd4
commit 8fe52047be
8 changed files with 32 additions and 20 deletions
+1 -1
View File
@@ -80,7 +80,7 @@ internal sealed class QuickProfileSwitchDialog
AutoSize = true,
Padding = new Padding(0, 8, 0, 0),
};
var closeButton = new Button { Text = "Close", AutoSize = true, DialogResult = DialogResult.Cancel, TabIndex = 1 };
var closeButton = new Button { Text = "&Close", AutoSize = true, DialogResult = DialogResult.Cancel, TabIndex = 1 };
buttons.Controls.Add(closeButton);
root.Controls.Add(buttons, 0, 2);