Announce the outcome of a Delete in both remembered lists through the screen reader
Deleting a remembered app (or peer) was SILENT to NVDA: the next row lands on the same list index the deleted one had and the list already has focus, so no focus/selection event fires - nothing to announce (Ed, 2026-07-26: deleting foobar said nothing). FocusAndAnnounceAfterDelete now follows the focus move with a Tolk line through the existing ScreenReader channel (the house pattern for feedback the screen reader can't observe): '<deleted row> removed. <row now under focus>.' - or that the list is empty. No dialog, no popup; applied to the remembered applications AND remembered peers lists so the two stay identical. Gate 60/60. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -3475,9 +3475,11 @@ public sealed class MainForm : Form
|
|||||||
if (args.KeyCode == Keys.Delete)
|
if (args.KeyCode == Keys.Delete)
|
||||||
{
|
{
|
||||||
var prevIndex = rememberedPeersList.SelectedIndex;
|
var prevIndex = rememberedPeersList.SelectedIndex;
|
||||||
|
var deletedLabel = (rememberedPeersList.SelectedItem as RememberedPeerItem)?.ToString();
|
||||||
RemoveSelectedRememberedPeer(rememberedPeersList);
|
RemoveSelectedRememberedPeer(rememberedPeersList);
|
||||||
SyncAllPeerLists();
|
SyncAllPeerLists();
|
||||||
FocusListItemAfterDelete(rememberedPeersList, prevIndex);
|
if (deletedLabel is not null) FocusAndAnnounceAfterDelete(rememberedPeersList, deletedLabel, prevIndex);
|
||||||
|
else FocusListItemAfterDelete(rememberedPeersList, prevIndex);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
args.SuppressKeyPress = true;
|
args.SuppressKeyPress = true;
|
||||||
}
|
}
|
||||||
@@ -3750,8 +3752,9 @@ public sealed class MainForm : Form
|
|||||||
args.SuppressKeyPress = true;
|
args.SuppressKeyPress = true;
|
||||||
if (rememberedAppsList.SelectedItem is not AudioAppChoice choice) return;
|
if (rememberedAppsList.SelectedItem is not AudioAppChoice choice) return;
|
||||||
var prevIndex = rememberedAppsList.SelectedIndex;
|
var prevIndex = rememberedAppsList.SelectedIndex;
|
||||||
|
var deletedLabel = choice.ToString() ?? choice.ProcessName; // announce what the row read as
|
||||||
RemoveRememberedApplication(choice.ProcessName);
|
RemoveRememberedApplication(choice.ProcessName);
|
||||||
FocusListItemAfterDelete(rememberedAppsList, prevIndex);
|
FocusAndAnnounceAfterDelete(rememberedAppsList, deletedLabel, prevIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reconcile the app list on a slow timer so entries appear/disappear as apps open and close,
|
// Reconcile the app list on a slow timer so entries appear/disappear as apps open and close,
|
||||||
@@ -7503,6 +7506,20 @@ public sealed class MainForm : Form
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>After a Delete in a remembered list: focus the next item AND speak the outcome through
|
||||||
|
/// the screen reader. The speech is load-bearing, not decoration: the next item usually lands on the
|
||||||
|
/// SAME index the deleted one had, and the list already has focus — so no focus or selection event
|
||||||
|
/// fires and NVDA would otherwise say nothing at all (Ed, 2026-07-26: deleting foobar gave silence).
|
||||||
|
/// Speaks "«deleted» removed." plus the row now under focus, or that the list is empty.</summary>
|
||||||
|
private static void FocusAndAnnounceAfterDelete(CheckedListBox list, string deletedLabel, int prevIndex)
|
||||||
|
{
|
||||||
|
FocusListItemAfterDelete(list, prevIndex);
|
||||||
|
var now = list.SelectedItem?.ToString();
|
||||||
|
ScreenReader.Speak(string.IsNullOrWhiteSpace(now)
|
||||||
|
? $"{deletedLabel} removed. The list is empty."
|
||||||
|
: $"{deletedLabel} removed. {now}.");
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// After deleting an item from a CheckedListBox, focus the next sensible item so NVDA
|
/// After deleting an item from a CheckedListBox, focus the next sensible item so NVDA
|
||||||
/// announces the new selection. If something exists at the same index that the deleted
|
/// announces the new selection. If something exists at the same index that the deleted
|
||||||
|
|||||||
Reference in New Issue
Block a user