Skip to content

Commit 0d28b2e

Browse files
authored
Merge pull request microsoft#189090 from microsoft/merogge/alert-focus-change
alert when focus changes for chat responses/ notifications in the accessible view
2 parents b5a4613 + 074b93d commit 0d28b2e

File tree

3 files changed

+27
-0
lines changed

3 files changed

+27
-0
lines changed

src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { IListService, WorkbenchList } from 'vs/platform/list/browser/listServic
2828
import { NotificationFocusedContext } from 'vs/workbench/common/contextkeys';
2929
import { IAccessibleViewService, AccessibleViewService, IAccessibleContentProvider, IAccessibleViewOptions, AccessibleViewType, accessibleViewIsShown } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
3030
import { IHoverService } from 'vs/workbench/services/hover/browser/hover';
31+
import { alert } from 'vs/base/browser/ui/aria/aria';
3132

3233
registerAccessibilityConfiguration();
3334
registerSingleton(IAccessibleViewService, AccessibleViewService, InstantiationType.Delayed);
@@ -173,13 +174,16 @@ class NotificationAccessibleViewContribution extends Disposable {
173174
}
174175
commandService.executeCommand('notifications.showList');
175176
let notificationIndex: number | undefined;
177+
let length: number | undefined;
176178
const list = listService.lastFocusedList;
177179
if (list instanceof WorkbenchList) {
178180
notificationIndex = list.indexOf(notification);
181+
length = list.length;
179182
}
180183
if (notificationIndex === undefined) {
181184
return false;
182185
}
186+
183187
function focusList(): void {
184188
commandService.executeCommand('notifications.showList');
185189
if (list && notificationIndex !== undefined) {
@@ -206,6 +210,7 @@ class NotificationAccessibleViewContribution extends Disposable {
206210
}
207211
focusList();
208212
list.focusNext();
213+
alertFocusChange(notificationIndex, length, 'next');
209214
renderAccessibleView();
210215
},
211216
previous(): void {
@@ -214,6 +219,7 @@ class NotificationAccessibleViewContribution extends Disposable {
214219
}
215220
focusList();
216221
list.focusPrevious();
222+
alertFocusChange(notificationIndex, length, 'previous');
217223
renderAccessibleView();
218224
},
219225
verbositySettingKey: AccessibilityVerbositySettingId.Notification,
@@ -249,3 +255,17 @@ class AccessibleViewNavigatorContribution extends Disposable {
249255
}
250256

251257
workbenchContributionsRegistry.registerWorkbenchContribution(AccessibleViewNavigatorContribution, LifecyclePhase.Eventually);
258+
259+
export function alertFocusChange(index: number | undefined, length: number | undefined, type: 'next' | 'previous'): void {
260+
if (index === undefined || length === undefined) {
261+
return;
262+
}
263+
const number = index + 1;
264+
265+
if (type === 'next' && number + 1 <= length) {
266+
alert(`Focused ${number + 1} of ${length}`);
267+
} else if (type === 'previous' && number - 1 > 0) {
268+
alert(`Focused ${number - 1} of ${length}`);
269+
}
270+
return;
271+
}

src/vs/workbench/contrib/accessibility/browser/accessibleView.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ export class AccessibleViewService extends Disposable implements IAccessibleView
271271
this._accessibleView = this._register(this._instantiationService.createInstance(AccessibleView));
272272
}
273273
this._accessibleView.show(provider);
274+
274275
}
275276
next(): void {
276277
this._accessibleView?.next();

src/vs/workbench/contrib/chat/browser/chat.contribution.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import { CONTEXT_IN_CHAT_SESSION } from 'vs/workbench/contrib/chat/common/chatCo
4444
import { ChatAccessibilityService } from 'vs/workbench/contrib/chat/browser/chatAccessibilityService';
4545
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
4646
import { QuickQuestionMode } from 'vs/workbench/contrib/chat/browser/actions/quickQuestionActions/quickQuestionAction';
47+
import { alertFocusChange } from 'vs/workbench/contrib/accessibility/browser/accessibility.contribution';
4748

4849
// Register configuration
4950
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
@@ -175,6 +176,9 @@ class ChatAccessibleViewContribution extends Disposable {
175176
if (!responseContent) {
176177
return false;
177178
}
179+
const responses = verifiedWidget.viewModel?.getItems().filter(i => isResponseVM(i));
180+
const length = responses?.length;
181+
const responseIndex = responses?.findIndex(i => i === focusedItem);
178182

179183
accessibleViewService.show({
180184
verbositySettingKey: AccessibilityVerbositySettingId.Chat,
@@ -189,10 +193,12 @@ class ChatAccessibleViewContribution extends Disposable {
189193
},
190194
next() {
191195
verifiedWidget.moveFocus(focusedItem, 'next');
196+
alertFocusChange(responseIndex, length, 'next');
192197
renderAccessibleView(accessibleViewService, widgetService, codeEditorService);
193198
},
194199
previous() {
195200
verifiedWidget.moveFocus(focusedItem, 'previous');
201+
alertFocusChange(responseIndex, length, 'previous');
196202
renderAccessibleView(accessibleViewService, widgetService, codeEditorService);
197203
},
198204
options: { ariaLabel: nls.localize('chatAccessibleView', "Chat Accessible View"), type: AccessibleViewType.View }

0 commit comments

Comments
 (0)