v4.1: two screen-reader fixes — silent start-in-tray, announce on restore

- Starting straight into the tray (StartMinimised / --minimized) no longer plays the "minimise"
  cue; only a genuine user minimise does (the startup path passes playCue:false)
- Restoring the window from the tray now lands focus on a real named control on the active tab so
  NVDA announces it, instead of resting on the role-less QuietTabControl and surfacing silently
- Shared the focus-a-leaf-for-announcement helper between the main window and Preferences

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ednunp
2026-06-13 15:59:59 +01:00
co-authored by Claude Opus 4.8
parent a408d2b56e
commit 5abbeefe29
7 changed files with 73 additions and 54 deletions
+13 -1
View File
@@ -606,6 +606,16 @@ public sealed class MainForm : Form
{
if (InvokeRequired) { BeginInvoke(new Action(RestoreFromTray)); return; }
trayController.Restore();
// Land focus on a real, named control on whichever tab is showing, so NVDA announces
// something when the window comes back from the tray. Without this, focus rests on the
// QuietTabControl (deliberately role-less / nameless) and a screen reader has nothing to
// read, so the window surfaces silently — the same issue the Preferences dialog had.
// Deferred so it runs after the show/foreground settles.
BeginInvoke(new Action(() =>
{
if (IsDisposed) return;
WinEventNotifier.AnnounceByFocusingLeaf(this, mainTabControl.SelectedTab, mainTabControl);
}));
}
catch { /* best-effort — surfacing the window is a convenience, not load-critical */ }
}
@@ -1265,7 +1275,9 @@ public sealed class MainForm : Form
startNextInstanceMinimized = false;
if (minimizeThisInstance)
{
BeginInvoke(() => trayController.Minimize());
// playCue:false — starting up in the tray (StartMinimised / --minimized) isn't the
// user choosing to minimise, so it must not sound the "minimise" cue.
BeginInvoke(() => trayController.Minimize(playCue: false));
}
// Kick off UPnP discovery if the user has the box ticked. Off by default; the