Skip to content

Commit 0987474

Browse files
authored
Merge pull request microsoft#185153 from microsoft/merogge/dupe-speech
prevent screen reader from reading a user's chat request on enter
2 parents 00d5eaa + 5a6e4ed commit 0987474

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

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

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import { CONTEXT_CHAT_INPUT_HAS_TEXT, CONTEXT_IN_CHAT_INPUT } from 'vs/workbench
3131
import { IChatReplyFollowup } from 'vs/workbench/contrib/chat/common/chatService';
3232
import { IChatWidgetHistoryService } from 'vs/workbench/contrib/chat/common/chatWidgetHistoryService';
3333
import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution';
34+
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
35+
import { isMacintosh } from 'vs/base/common/platform';
3436

3537
const $ = dom.$;
3638

@@ -59,6 +61,8 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
5961
private followupsDisposables = this._register(new DisposableStore());
6062

6163
private _inputEditor!: CodeEditorWidget;
64+
private _inputEditorElement!: HTMLElement;
65+
6266
public get inputEditor() {
6367
return this._inputEditor;
6468
}
@@ -78,7 +82,8 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
7882
@IInstantiationService private readonly instantiationService: IInstantiationService,
7983
@IContextKeyService private readonly contextKeyService: IContextKeyService,
8084
@IConfigurationService private readonly configurationService: IConfigurationService,
81-
@IKeybindingService private readonly keybindingService: IKeybindingService
85+
@IKeybindingService private readonly keybindingService: IKeybindingService,
86+
@IAccessibilityService private readonly accessibilityService: IAccessibilityService
8287
) {
8388
super();
8489

@@ -148,8 +153,25 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
148153
this.history.add(editorValue);
149154
}
150155

151-
this._inputEditor.focus();
156+
if (this.accessibilityService.isScreenReaderOptimized() && isMacintosh) {
157+
this._acceptInputForVoiceover();
158+
} else {
159+
this._inputEditor.focus();
160+
this._inputEditor.setValue('');
161+
}
162+
}
163+
164+
private _acceptInputForVoiceover(): void {
165+
const domNode = this._inputEditor.getDomNode();
166+
if (!domNode) {
167+
return;
168+
}
169+
// Remove the input editor from the DOM temporarily to prevent VoiceOver
170+
// from reading the cleared text (the request) to the user.
171+
this._inputEditorElement.removeChild(domNode);
152172
this._inputEditor.setValue('');
173+
this._inputEditorElement.appendChild(domNode);
174+
this._inputEditor.focus();
153175
}
154176

155177
render(container: HTMLElement, initialValue: string, widget: IChatWidget) {
@@ -181,8 +203,8 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
181203
options.suggest = { showIcons: false };
182204
options.scrollbar = { ...(options.scrollbar ?? {}), vertical: 'hidden' };
183205

184-
const inputEditorElement = dom.append(inputContainer, $('.interactive-input-editor'));
185-
this._inputEditor = this._register(scopedInstantiationService.createInstance(CodeEditorWidget, inputEditorElement, options, getSimpleCodeEditorWidgetOptions()));
206+
this._inputEditorElement = dom.append(inputContainer, $('.interactive-input-editor'));
207+
this._inputEditor = this._register(scopedInstantiationService.createInstance(CodeEditorWidget, this._inputEditorElement, options, getSimpleCodeEditorWidgetOptions()));
186208

187209
this._register(this._inputEditor.onDidChangeModelContent(() => {
188210
const currentHeight = Math.min(this._inputEditor.getContentHeight(), INPUT_EDITOR_MAX_HEIGHT);

0 commit comments

Comments
 (0)