Change:
One way of resolving this would be repeating the position information when I press any of the commands, even if there is no change. Another possibility would be to prevent the widget from refocusing when I am in the first / last element, and I try to move beyond that element. In that way pressing the next command will not produce any feedback if I am in the last one, and the previous will not produce any feedback if I am in the first one. Does it make sense? In any case, this would be a refinement, not something that would prevent someone from using the feature. Originally posted by in
Something else to consider when fine tuning the responses. Right now, position information is announced using an alert in macOS, and a status message in Windows. This is a situation where it makes sense to use an alert in all platforms so that screen readers prioritize this over other events. For example, right now JAWS is announcing position information after reannouncing the widget.
Huh, I'm using for all platforms here which appears to be platform agnostic I think it might just be a JAWS issue - does this repro when using NVDA?
It doesn't, but NVDA handles aria-live differently. You may be right dough. I'll debug NVDA on Monday and we'll know for sure which event it is seeing. JAWS may be simply prioritizing the focus event.
Friendly ping! Looks like this issue requires some further steps to be verified. Please provide us with the steps necessary to verify this issue.
Focus an accessible view for which there are several elements (like chat responses or notifications). Verify that if you are on the first or last element, pressing next or previous does not result in repeated alerts. it should not notify the screen reader user as nothing has changed.
Note to verifier there's an issue to disable these actions when they cannot be taken, which is the better fix.
Verified. With NVDA, if I press enter on the Next button while on the last chat response, the focus goes back to the response text instead of staying on the button, though that might be by design.

Discussion:
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { AccessibilityVerbositySettingId, accessibilityHelpIsShown, accessibleViewIsShown } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; <del> import { Action2, MenuId } from 'vs/platform/actions/common/actions'; </del> <ins> import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; </ins> import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';

static id: 'editor.action.accessibleViewNext'; constructor() { super({ <del> id: AccessibleViewNextAction.id, </del> <ins> id: 'editor.action.accessibleViewNext', </ins> precondition: accessibleViewIsShown, keybinding: { primary: KeyMod.Alt | KeyCode.BracketRight,

accessor.get(IAccessibleViewService).next(); } } <ins> registerAction2(AccessibleViewNextAction); </ins> class AccessibleViewPreviousAction extends Action2 { static id: 'editor.action.accessibleViewPrevious'; constructor() { super({ <del> id: AccessibleViewPreviousAction.id, </del> <ins> id: 'editor.action.accessibleViewPrevious', </ins> precondition: accessibleViewIsShown, keybinding: { primary: KeyMod.Alt | KeyCode.BracketLeft,

}); } run(accessor: ServicesAccessor, ...args: unknown[]): void { <del> accessor.get(IAccessibleViewService).next(); </del> <ins> accessor.get(IAccessibleViewService).previous(); </ins> } } <ins> registerAction2(AccessibleViewPreviousAction); </ins> function registerCommand<T extends Command>(command: T): T { command.register();

import { QuickQuestionMode } from 'vs/workbench/contrib/chat/browser/actions/quickQuestionActions/quickQuestionAction'; import { alertFocusChange } from 'vs/workbench/contrib/accessibility/browser/accessibility.contribution'; import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; <ins> import { ChatWelcomeMessageModel } from 'vs/workbench/contrib/chat/common/chatModel'; import { IMarkdownString } from 'vs/base/common/htmlContent'; </ins> // Register configuration const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);

} widget.focus(focusedItem); <del> const responseContent = isResponseVM(focusedItem) ? focusedItem.response.value : undefined; </del> <ins> const isWelcome = focusedItem instanceof ChatWelcomeMessageModel; let responseContent = isResponseVM(focusedItem) ? focusedItem.response.value : undefined; if (isWelcome) { const welcomeReplyContents = []; for (const content of focusedItem.content) { if (Array.isArray(content)) { welcomeReplyContents.push(...content.map(m => m.message)); } else { welcomeReplyContents.push((content as IMarkdownString).value); } } responseContent = welcomeReplyContents.join('n'); } </ins> if (!responseContent) { return false; }

accessibleViewService.show({ verbositySettingKey: AccessibilityVerbositySettingId.Chat, <del> provideContent(): string { return responseContent; }, </del> <ins> provideContent(): string { return responseContent!; }, </ins> onClose() { verifiedWidget.reveal(focusedItem); if (chatInputFocused) {