Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { localize } from '../../../../nls.js';
7
import { ConfigurationScope, Extensions, IConfigurationNode, IConfigurationPropertySchema, IConfigurationRegistry } from '../../../../platform/configuration/common/configurationRegistry.js';
8
import { Registry } from '../../../../platform/registry/common/platform.js';
9
import { RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
10
import { workbenchConfigurationNodeBase, Extensions as WorkbenchExtensions, IConfigurationMigrationRegistry, ConfigurationKeyValuePairs, ConfigurationMigration } from '../../../common/configuration.js';
11
import { AccessibilitySignal } from '../../../../platform/accessibilitySignal/browser/accessibilitySignalService.js';
12
import { AccessibilityVoiceSettingId, ISpeechService, SPEECH_LANGUAGES } from '../../speech/common/speechService.js';
13
import { Disposable } from '../../../../base/common/lifecycle.js';
14
import { IWorkbenchContribution } from '../../../common/contributions.js';
15
import { Event } from '../../../../base/common/event.js';
16
import { isDefined } from '../../../../base/common/types.js';
17
18
export const accessibilityHelpIsShown = new RawContextKey<boolean>('accessibilityHelpIsShown', false, true);
19
export const accessibleViewIsShown = new RawContextKey<boolean>('accessibleViewIsShown', false, true);
20
export const accessibleViewSupportsNavigation = new RawContextKey<boolean>('accessibleViewSupportsNavigation', false, true);
21
export const accessibleViewVerbosityEnabled = new RawContextKey<boolean>('accessibleViewVerbosityEnabled', false, true);
22
export const accessibleViewGoToSymbolSupported = new RawContextKey<boolean>('accessibleViewGoToSymbolSupported', false, true);
23
export const accessibleViewOnLastLine = new RawContextKey<boolean>('accessibleViewOnLastLine', false, true);
24
export const accessibleViewCurrentProviderId = new RawContextKey<string>('accessibleViewCurrentProviderId', undefined, undefined);
25
export const accessibleViewInCodeBlock = new RawContextKey<boolean>('accessibleViewInCodeBlock', undefined, undefined);
26
export const accessibleViewContainsCodeBlocks = new RawContextKey<boolean>('accessibleViewContainsCodeBlocks', undefined, undefined);
27
export const accessibleViewHasUnassignedKeybindings = new RawContextKey<boolean>('accessibleViewHasUnassignedKeybindings', undefined, undefined);
28
export const accessibleViewHasAssignedKeybindings = new RawContextKey<boolean>('accessibleViewHasAssignedKeybindings', undefined, undefined);
29
30
/**
31
* Miscellaneous settings tagged with accessibility and implemented in the accessibility contrib but
32
* were better to live under workbench for discoverability.
33
*/
34
export const enum AccessibilityWorkbenchSettingId {
35
DimUnfocusedEnabled = 'accessibility.dimUnfocused.enabled',
36
DimUnfocusedOpacity = 'accessibility.dimUnfocused.opacity',
37
HideAccessibleView = 'accessibility.hideAccessibleView',
38
AccessibleViewCloseOnKeyPress = 'accessibility.accessibleView.closeOnKeyPress'
39
}
40
41
export const enum ViewDimUnfocusedOpacityProperties {
42
Default = 0.75,
43
Minimum = 0.2,
44
Maximum = 1
45
}
46
47
export const enum AccessibilityVerbositySettingId {
48
Terminal = 'accessibility.verbosity.terminal',
49
DiffEditor = 'accessibility.verbosity.diffEditor',
50
MergeEditor = 'accessibility.verbosity.mergeEditor',
51
Chat = 'accessibility.verbosity.panelChat',
52
InlineChat = 'accessibility.verbosity.inlineChat',
53
TerminalChat = 'accessibility.verbosity.terminalChat',
54
InlineCompletions = 'accessibility.verbosity.inlineCompletions',
55
KeybindingsEditor = 'accessibility.verbosity.keybindingsEditor',
56
Notebook = 'accessibility.verbosity.notebook',
57
Editor = 'accessibility.verbosity.editor',
58
Hover = 'accessibility.verbosity.hover',
59
Notification = 'accessibility.verbosity.notification',
60
EmptyEditorHint = 'accessibility.verbosity.emptyEditorHint',
61
ReplEditor = 'accessibility.verbosity.replEditor',
62
Comments = 'accessibility.verbosity.comments',
63
DiffEditorActive = 'accessibility.verbosity.diffEditorActive',
64
Debug = 'accessibility.verbosity.debug',
65
Walkthrough = 'accessibility.verbosity.walkthrough',
66
SourceControl = 'accessibility.verbosity.sourceControl'
67
}
68
69
const baseVerbosityProperty: IConfigurationPropertySchema = {
70
type: 'boolean',
71
default: true,
72
tags: ['accessibility']
73
};
74
75
export const accessibilityConfigurationNodeBase = Object.freeze<IConfigurationNode>({
76
id: 'accessibility',
77
title: localize('accessibilityConfigurationTitle', "Accessibility"),
78
type: 'object'
79
});
80
81
export const soundFeatureBase: IConfigurationPropertySchema = {
82
'type': 'string',
83
'enum': ['auto', 'on', 'off'],
84
'default': 'auto',
85
'enumDescriptions': [
86
localize('sound.enabled.auto', "Enable sound when a screen reader is attached."),
87
localize('sound.enabled.on', "Enable sound."),
88
localize('sound.enabled.off', "Disable sound.")
89
],
90
tags: ['accessibility'],
91
};
92
93
const signalFeatureBase: IConfigurationPropertySchema = {
94
'type': 'object',
95
'tags': ['accessibility'],
96
additionalProperties: false,
97
default: {
98
sound: 'auto',
99
announcement: 'auto'
100
}
101
};
102
103
export const announcementFeatureBase: IConfigurationPropertySchema = {
104
'type': 'string',
105
'enum': ['auto', 'off'],
106
'default': 'auto',
107
'enumDescriptions': [
108
localize('announcement.enabled.auto', "Enable announcement, will only play when in screen reader optimized mode."),
109
localize('announcement.enabled.off', "Disable announcement.")
110
],
111
tags: ['accessibility'],
112
};
113
114
const defaultNoAnnouncement: IConfigurationPropertySchema = {
115
'type': 'object',
116
'tags': ['accessibility'],
117
additionalProperties: false,
118
'default': {
119
'sound': 'auto',
120
}
121
};
122
123
const configuration: IConfigurationNode = {
124
...accessibilityConfigurationNodeBase,
125
scope: ConfigurationScope.RESOURCE,
126
properties: {
127
[AccessibilityVerbositySettingId.Terminal]: {
128
description: localize('verbosity.terminal.description', 'Provide information about how to access the terminal accessibility help menu when the terminal is focused.'),
129
...baseVerbosityProperty
130
},
131
[AccessibilityVerbositySettingId.DiffEditor]: {
132
description: localize('verbosity.diffEditor.description', 'Provide information about how to navigate changes in the diff editor when it is focused.'),
133
...baseVerbosityProperty
134
},
135
[AccessibilityVerbositySettingId.Chat]: {
136
description: localize('verbosity.chat.description', 'Provide information about how to access the chat help menu when the chat input is focused.'),
137
...baseVerbosityProperty
138
},
139
[AccessibilityVerbositySettingId.InlineChat]: {
140
description: localize('verbosity.interactiveEditor.description', 'Provide information about how to access the inline editor chat accessibility help menu and alert with hints that describe how to use the feature when the input is focused.'),
141
...baseVerbosityProperty
142
},
143
[AccessibilityVerbositySettingId.InlineCompletions]: {
144
description: localize('verbosity.inlineCompletions.description', 'Provide information about how to access the inline completions hover and Accessible View.'),
145
...baseVerbosityProperty
146
},
147
[AccessibilityVerbositySettingId.KeybindingsEditor]: {
148
description: localize('verbosity.keybindingsEditor.description', 'Provide information about how to change a keybinding in the keybindings editor when a row is focused.'),
149
...baseVerbosityProperty
150
},
151
[AccessibilityVerbositySettingId.Notebook]: {
152
description: localize('verbosity.notebook', 'Provide information about how to focus the cell container or inner editor when a notebook cell is focused.'),
153
...baseVerbosityProperty
154
},
155
[AccessibilityVerbositySettingId.Hover]: {
156
description: localize('verbosity.hover', 'Provide information about how to open the hover in an Accessible View.'),
157
...baseVerbosityProperty
158
},
159
[AccessibilityVerbositySettingId.Notification]: {
160
description: localize('verbosity.notification', 'Provide information about how to open the notification in an Accessible View.'),
161
...baseVerbosityProperty
162
},
163
[AccessibilityVerbositySettingId.EmptyEditorHint]: {
164
description: localize('verbosity.emptyEditorHint', 'Provide information about relevant actions in an empty text editor.'),
165
...baseVerbosityProperty
166
},
167
[AccessibilityVerbositySettingId.ReplEditor]: {
168
description: localize('verbosity.replEditor.description', 'Provide information about how to access the REPL editor accessibility help menu when the REPL editor is focused.'),
169
...baseVerbosityProperty
170
},
171
[AccessibilityVerbositySettingId.Comments]: {
172
description: localize('verbosity.comments', 'Provide information about actions that can be taken in the comment widget or in a file which contains comments.'),
173
...baseVerbosityProperty
174
},
175
[AccessibilityVerbositySettingId.DiffEditorActive]: {
176
description: localize('verbosity.diffEditorActive', 'Indicate when a diff editor becomes the active editor.'),
177
...baseVerbosityProperty
178
},
179
[AccessibilityVerbositySettingId.Debug]: {
180
description: localize('verbosity.debug', 'Provide information about how to access the debug console accessibility help dialog when the debug console or run and debug viewlet is focused. Note that a reload of the window is required for this to take effect.'),
181
...baseVerbosityProperty
182
},
183
[AccessibilityVerbositySettingId.Walkthrough]: {
184
description: localize('verbosity.walkthrough', 'Provide information about how to open the walkthrough in an Accessible View.'),
185
...baseVerbosityProperty
186
},
187
[AccessibilityWorkbenchSettingId.AccessibleViewCloseOnKeyPress]: {
188
markdownDescription: localize('terminal.integrated.accessibleView.closeOnKeyPress', "On keypress, close the Accessible View and focus the element from which it was invoked."),
189
type: 'boolean',
190
default: true
191
},
192
[AccessibilityVerbositySettingId.SourceControl]: {
193
description: localize('verbosity.scm', 'Provide information about how to access the source control accessibility help menu when the input is focused.'),
194
...baseVerbosityProperty
195
},
196
'accessibility.signalOptions.volume': {
197
'description': localize('accessibility.signalOptions.volume', "The volume of the sounds in percent (0-100)."),
198
'type': 'number',
199
'minimum': 0,
200
'maximum': 100,
201
'default': 70,
202
'tags': ['accessibility']
203
},
204
'accessibility.signalOptions.debouncePositionChanges': {
205
'description': localize('accessibility.signalOptions.debouncePositionChanges', "Whether or not position changes should be debounced"),
206
'type': 'boolean',
207
'default': false,
208
'tags': ['accessibility']
209
},
210
'accessibility.signalOptions.experimental.delays.general': {
211
'type': 'object',
212
'description': 'Delays for all signals besides error and warning at position',
213
'additionalProperties': false,
214
'properties': {
215
'announcement': {
216
'description': localize('accessibility.signalOptions.delays.general.announcement', "The delay in milliseconds before an announcement is made."),
217
'type': 'number',
218
'minimum': 0,
219
'default': 3000
220
},
221
'sound': {
222
'description': localize('accessibility.signalOptions.delays.general.sound', "The delay in milliseconds before a sound is played."),
223
'type': 'number',
224
'minimum': 0,
225
'default': 400
226
}
227
},
228
'tags': ['accessibility']
229
},
230
'accessibility.signalOptions.experimental.delays.warningAtPosition': {
231
'type': 'object',
232
'additionalProperties': false,
233
'properties': {
234
'announcement': {
235
'description': localize('accessibility.signalOptions.delays.warningAtPosition.announcement', "The delay in milliseconds before an announcement is made when there's a warning at the position."),
236
'type': 'number',
237
'minimum': 0,
238
'default': 3000
239
},
240
'sound': {
241
'description': localize('accessibility.signalOptions.delays.warningAtPosition.sound', "The delay in milliseconds before a sound is played when there's a warning at the position."),
242
'type': 'number',
243
'minimum': 0,
244
'default': 1000
245
}
246
},
247
'tags': ['accessibility']
248
},
249
'accessibility.signalOptions.experimental.delays.errorAtPosition': {
250
'type': 'object',
251
'additionalProperties': false,
252
'properties': {
253
'announcement': {
254
'description': localize('accessibility.signalOptions.delays.errorAtPosition.announcement', "The delay in milliseconds before an announcement is made when there's an error at the position."),
255
'type': 'number',
256
'minimum': 0,
257
'default': 3000
258
},
259
'sound': {
260
'description': localize('accessibility.signalOptions.delays.errorAtPosition.sound', "The delay in milliseconds before a sound is played when there's an error at the position."),
261
'type': 'number',
262
'minimum': 0,
263
'default': 1000
264
}
265
},
266
'tags': ['accessibility']
267
},
268
'accessibility.signals.lineHasBreakpoint': {
269
...signalFeatureBase,
270
'description': localize('accessibility.signals.lineHasBreakpoint', "Plays a signal - sound (audio cue) and/or announcement (alert) - when the active line has a breakpoint."),
271
'properties': {
272
'sound': {
273
'description': localize('accessibility.signals.lineHasBreakpoint.sound', "Plays a sound when the active line has a breakpoint."),
274
...soundFeatureBase
275
},
276
'announcement': {
277
'description': localize('accessibility.signals.lineHasBreakpoint.announcement', "Announces when the active line has a breakpoint."),
278
...announcementFeatureBase
279
},
280
},
281
},
282
'accessibility.signals.lineHasInlineSuggestion': {
283
...defaultNoAnnouncement,
284
'description': localize('accessibility.signals.lineHasInlineSuggestion', "Plays a sound / audio cue when the active line has an inline suggestion."),
285
'properties': {
286
'sound': {
287
'description': localize('accessibility.signals.lineHasInlineSuggestion.sound', "Plays a sound when the active line has an inline suggestion."),
288
...soundFeatureBase,
289
'default': 'off'
290
}
291
}
292
},
293
'accessibility.signals.nextEditSuggestion': {
294
...signalFeatureBase,
295
'description': localize('accessibility.signals.nextEditSuggestion', "Plays a signal - sound / audio cue and/or announcement (alert) when there is a next edit suggestion."),
296
'properties': {
297
'sound': {
298
'description': localize('accessibility.signals.nextEditSuggestion.sound', "Plays a sound when there is a next edit suggestion."),
299
...soundFeatureBase,
300
},
301
'announcement': {
302
'description': localize('accessibility.signals.nextEditSuggestion.announcement', "Announces when there is a next edit suggestion."),
303
...announcementFeatureBase,
304
},
305
}
306
},
307
'accessibility.signals.lineHasError': {
308
...signalFeatureBase,
309
'description': localize('accessibility.signals.lineHasError', "Plays a signal - sound (audio cue) and/or announcement (alert) - when the active line has an error."),
310
'properties': {
311
'sound': {
312
'description': localize('accessibility.signals.lineHasError.sound', "Plays a sound when the active line has an error."),
313
...soundFeatureBase
314
},
315
'announcement': {
316
'description': localize('accessibility.signals.lineHasError.announcement', "Announces when the active line has an error."),
317
...announcementFeatureBase,
318
default: 'off'
319
},
320
},
321
},
322
'accessibility.signals.lineHasFoldedArea': {
323
...signalFeatureBase,
324
'description': localize('accessibility.signals.lineHasFoldedArea', "Plays a signal - sound (audio cue) and/or announcement (alert) - the active line has a folded area that can be unfolded."),
325
'properties': {
326
'sound': {
327
'description': localize('accessibility.signals.lineHasFoldedArea.sound', "Plays a sound when the active line has a folded area that can be unfolded."),
328
...soundFeatureBase,
329
default: 'off'
330
},
331
'announcement': {
332
'description': localize('accessibility.signals.lineHasFoldedArea.announcement', "Announces when the active line has a folded area that can be unfolded."),
333
...announcementFeatureBase
334
},
335
}
336
},
337
'accessibility.signals.lineHasWarning': {
338
...signalFeatureBase,
339
'description': localize('accessibility.signals.lineHasWarning', "Plays a signal - sound (audio cue) and/or announcement (alert) - when the active line has a warning."),
340
'properties': {
341
'sound': {
342
'description': localize('accessibility.signals.lineHasWarning.sound', "Plays a sound when the active line has a warning."),
343
...soundFeatureBase
344
},
345
'announcement': {
346
'description': localize('accessibility.signals.lineHasWarning.announcement', "Announces when the active line has a warning."),
347
...announcementFeatureBase,
348
default: 'off'
349
},
350
},
351
},
352
'accessibility.signals.positionHasError': {
353
...signalFeatureBase,
354
'description': localize('accessibility.signals.positionHasError', "Plays a signal - sound (audio cue) and/or announcement (alert) - when the active line has a warning."),
355
'properties': {
356
'sound': {
357
'description': localize('accessibility.signals.positionHasError.sound', "Plays a sound when the active line has a warning."),
358
...soundFeatureBase
359
},
360
'announcement': {
361
'description': localize('accessibility.signals.positionHasError.announcement', "Announces when the active line has a warning."),
362
...announcementFeatureBase,
363
default: 'on'
364
},
365
},
366
},
367
'accessibility.signals.positionHasWarning': {
368
...signalFeatureBase,
369
'description': localize('accessibility.signals.positionHasWarning', "Plays a signal - sound (audio cue) and/or announcement (alert) - when the active line has a warning."),
370
'properties': {
371
'sound': {
372
'description': localize('accessibility.signals.positionHasWarning.sound', "Plays a sound when the active line has a warning."),
373
...soundFeatureBase
374
},
375
'announcement': {
376
'description': localize('accessibility.signals.positionHasWarning.announcement', "Announces when the active line has a warning."),
377
...announcementFeatureBase,
378
default: 'on'
379
},
380
},
381
},
382
'accessibility.signals.onDebugBreak': {
383
...signalFeatureBase,
384
'description': localize('accessibility.signals.onDebugBreak', "Plays a signal - sound (audio cue) and/or announcement (alert) - when the debugger stopped on a breakpoint."),
385
'properties': {
386
'sound': {
387
'description': localize('accessibility.signals.onDebugBreak.sound', "Plays a sound when the debugger stopped on a breakpoint."),
388
...soundFeatureBase
389
},
390
'announcement': {
391
'description': localize('accessibility.signals.onDebugBreak.announcement', "Announces when the debugger stopped on a breakpoint."),
392
...announcementFeatureBase
393
},
394
}
395
},
396
'accessibility.signals.noInlayHints': {
397
...signalFeatureBase,
398
'description': localize('accessibility.signals.noInlayHints', "Plays a signal - sound (audio cue) and/or announcement (alert) - when trying to read a line with inlay hints that has no inlay hints."),
399
'properties': {
400
'sound': {
401
'description': localize('accessibility.signals.noInlayHints.sound', "Plays a sound when trying to read a line with inlay hints that has no inlay hints."),
402
...soundFeatureBase
403
},
404
'announcement': {
405
'description': localize('accessibility.signals.noInlayHints.announcement', "Announces when trying to read a line with inlay hints that has no inlay hints."),
406
...announcementFeatureBase
407
},
408
}
409
},
410
'accessibility.signals.taskCompleted': {
411
...signalFeatureBase,
412
'description': localize('accessibility.signals.taskCompleted', "Plays a signal - sound (audio cue) and/or announcement (alert) - when a task is completed."),
413
'properties': {
414
'sound': {
415
'description': localize('accessibility.signals.taskCompleted.sound', "Plays a sound when a task is completed."),
416
...soundFeatureBase
417
},
418
'announcement': {
419
'description': localize('accessibility.signals.taskCompleted.announcement', "Announces when a task is completed."),
420
...announcementFeatureBase
421
},
422
}
423
},
424
'accessibility.signals.taskFailed': {
425
...signalFeatureBase,
426
'description': localize('accessibility.signals.taskFailed', "Plays a signal - sound (audio cue) and/or announcement (alert) - when a task fails (non-zero exit code)."),
427
'properties': {
428
'sound': {
429
'description': localize('accessibility.signals.taskFailed.sound', "Plays a sound when a task fails (non-zero exit code)."),
430
...soundFeatureBase
431
},
432
'announcement': {
433
'description': localize('accessibility.signals.taskFailed.announcement', "Announces when a task fails (non-zero exit code)."),
434
...announcementFeatureBase
435
},
436
}
437
},
438
'accessibility.signals.terminalCommandFailed': {
439
...signalFeatureBase,
440
'description': localize('accessibility.signals.terminalCommandFailed', "Plays a signal - sound (audio cue) and/or announcement (alert) - when a terminal command fails (non-zero exit code) or when a command with such an exit code is navigated to in the accessible view."),
441
'properties': {
442
'sound': {
443
'description': localize('accessibility.signals.terminalCommandFailed.sound', "Plays a sound when a terminal command fails (non-zero exit code) or when a command with such an exit code is navigated to in the accessible view."),
444
...soundFeatureBase
445
},
446
'announcement': {
447
'description': localize('accessibility.signals.terminalCommandFailed.announcement', "Announces when a terminal command fails (non-zero exit code) or when a command with such an exit code is navigated to in the accessible view."),
448
...announcementFeatureBase
449
},
450
}
451
},
452
'accessibility.signals.terminalCommandSucceeded': {
453
...signalFeatureBase,
454
'description': localize('accessibility.signals.terminalCommandSucceeded', "Plays a signal - sound (audio cue) and/or announcement (alert) - when a terminal command succeeds (zero exit code) or when a command with such an exit code is navigated to in the accessible view."),
455
'properties': {
456
'sound': {
457
'description': localize('accessibility.signals.terminalCommandSucceeded.sound', "Plays a sound when a terminal command succeeds (zero exit code) or when a command with such an exit code is navigated to in the accessible view."),
458
...soundFeatureBase
459
},
460
'announcement': {
461
'description': localize('accessibility.signals.terminalCommandSucceeded.announcement', "Announces when a terminal command succeeds (zero exit code) or when a command with such an exit code is navigated to in the accessible view."),
462
...announcementFeatureBase
463
},
464
}
465
},
466
'accessibility.signals.terminalQuickFix': {
467
...signalFeatureBase,
468
'description': localize('accessibility.signals.terminalQuickFix', "Plays a signal - sound (audio cue) and/or announcement (alert) - when terminal Quick Fixes are available."),
469
'properties': {
470
'sound': {
471
'description': localize('accessibility.signals.terminalQuickFix.sound', "Plays a sound when terminal Quick Fixes are available."),
472
...soundFeatureBase
473
},
474
'announcement': {
475
'description': localize('accessibility.signals.terminalQuickFix.announcement', "Announces when terminal Quick Fixes are available."),
476
...announcementFeatureBase
477
},
478
}
479
},
480
'accessibility.signals.terminalBell': {
481
...signalFeatureBase,
482
'description': localize('accessibility.signals.terminalBell', "Plays a signal - sound (audio cue) and/or announcement (alert) - when the terminal bell is ringing."),
483
'properties': {
484
'sound': {
485
'description': localize('accessibility.signals.terminalBell.sound', "Plays a sound when the terminal bell is ringing."),
486
...soundFeatureBase
487
},
488
'announcement': {
489
'description': localize('accessibility.signals.terminalBell.announcement', "Announces when the terminal bell is ringing."),
490
...announcementFeatureBase
491
},
492
}
493
},
494
'accessibility.signals.diffLineInserted': {
495
...defaultNoAnnouncement,
496
'description': localize('accessibility.signals.diffLineInserted', "Plays a sound / audio cue when the focus moves to an inserted line in Accessible Diff Viewer mode or to the next/previous change."),
497
'properties': {
498
'sound': {
499
'description': localize('accessibility.signals.sound', "Plays a sound when the focus moves to an inserted line in Accessible Diff Viewer mode or to the next/previous change."),
500
...soundFeatureBase
501
}
502
}
503
},
504
'accessibility.signals.diffLineModified': {
505
...defaultNoAnnouncement,
506
'description': localize('accessibility.signals.diffLineModified', "Plays a sound / audio cue when the focus moves to an modified line in Accessible Diff Viewer mode or to the next/previous change."),
507
'properties': {
508
'sound': {
509
'description': localize('accessibility.signals.diffLineModified.sound', "Plays a sound when the focus moves to a modified line in Accessible Diff Viewer mode or to the next/previous change."),
510
...soundFeatureBase
511
}
512
}
513
},
514
'accessibility.signals.diffLineDeleted': {
515
...defaultNoAnnouncement,
516
'description': localize('accessibility.signals.diffLineDeleted', "Plays a sound / audio cue when the focus moves to an deleted line in Accessible Diff Viewer mode or to the next/previous change."),
517
'properties': {
518
'sound': {
519
'description': localize('accessibility.signals.diffLineDeleted.sound', "Plays a sound when the focus moves to an deleted line in Accessible Diff Viewer mode or to the next/previous change."),
520
...soundFeatureBase
521
}
522
}
523
},
524
'accessibility.signals.chatEditModifiedFile': {
525
...defaultNoAnnouncement,
526
'description': localize('accessibility.signals.chatEditModifiedFile', "Plays a sound / audio cue when revealing a file with changes from chat edits"),
527
'properties': {
528
'sound': {
529
'description': localize('accessibility.signals.chatEditModifiedFile.sound', "Plays a sound when revealing a file with changes from chat edits"),
530
...soundFeatureBase
531
}
532
}
533
},
534
'accessibility.signals.notebookCellCompleted': {
535
...signalFeatureBase,
536
'description': localize('accessibility.signals.notebookCellCompleted', "Plays a signal - sound (audio cue) and/or announcement (alert) - when a notebook cell execution is successfully completed."),
537
'properties': {
538
'sound': {
539
'description': localize('accessibility.signals.notebookCellCompleted.sound', "Plays a sound when a notebook cell execution is successfully completed."),
540
...soundFeatureBase
541
},
542
'announcement': {
543
'description': localize('accessibility.signals.notebookCellCompleted.announcement', "Announces when a notebook cell execution is successfully completed."),
544
...announcementFeatureBase
545
},
546
}
547
},
548
'accessibility.signals.notebookCellFailed': {
549
...signalFeatureBase,
550
'description': localize('accessibility.signals.notebookCellFailed', "Plays a signal - sound (audio cue) and/or announcement (alert) - when a notebook cell execution fails."),
551
'properties': {
552
'sound': {
553
'description': localize('accessibility.signals.notebookCellFailed.sound', "Plays a sound when a notebook cell execution fails."),
554
...soundFeatureBase
555
},
556
'announcement': {
557
'description': localize('accessibility.signals.notebookCellFailed.announcement', "Announces when a notebook cell execution fails."),
558
...announcementFeatureBase
559
},
560
}
561
},
562
'accessibility.signals.progress': {
563
...signalFeatureBase,
564
'description': localize('accessibility.signals.progress', "Plays a signal - sound (audio cue) and/or announcement (alert) - on loop while progress is occurring."),
565
'properties': {
566
'sound': {
567
'description': localize('accessibility.signals.progress.sound', "Plays a sound on loop while progress is occurring."),
568
...soundFeatureBase
569
},
570
'announcement': {
571
'description': localize('accessibility.signals.progress.announcement', "Alerts on loop while progress is occurring."),
572
...announcementFeatureBase
573
},
574
},
575
},
576
'accessibility.signals.chatRequestSent': {
577
...signalFeatureBase,
578
'description': localize('accessibility.signals.chatRequestSent', "Plays a signal - sound (audio cue) and/or announcement (alert) - when a chat request is made."),
579
'properties': {
580
'sound': {
581
'description': localize('accessibility.signals.chatRequestSent.sound', "Plays a sound when a chat request is made."),
582
...soundFeatureBase
583
},
584
'announcement': {
585
'description': localize('accessibility.signals.chatRequestSent.announcement', "Announces when a chat request is made."),
586
...announcementFeatureBase
587
},
588
}
589
},
590
'accessibility.signals.chatResponseReceived': {
591
...defaultNoAnnouncement,
592
'description': localize('accessibility.signals.chatResponseReceived', "Plays a sound / audio cue when the response has been received."),
593
'properties': {
594
'sound': {
595
'description': localize('accessibility.signals.chatResponseReceived.sound', "Plays a sound on when the response has been received."),
596
...soundFeatureBase
597
},
598
}
599
},
600
'accessibility.signals.codeActionTriggered': {
601
...defaultNoAnnouncement,
602
'description': localize('accessibility.signals.codeActionTriggered', "Plays a sound / audio cue - when a code action has been triggered."),
603
'properties': {
604
'sound': {
605
'description': localize('accessibility.signals.codeActionTriggered.sound', "Plays a sound when a code action has been triggered."),
606
...soundFeatureBase
607
}
608
}
609
},
610
'accessibility.signals.codeActionApplied': {
611
...defaultNoAnnouncement,
612
'description': localize('accessibility.signals.codeActionApplied', "Plays a sound / audio cue when the code action has been applied."),
613
'properties': {
614
'sound': {
615
'description': localize('accessibility.signals.codeActionApplied.sound', "Plays a sound when the code action has been applied."),
616
...soundFeatureBase
617
},
618
}
619
},
620
'accessibility.signals.voiceRecordingStarted': {
621
...defaultNoAnnouncement,
622
'description': localize('accessibility.signals.voiceRecordingStarted', "Plays a sound / audio cue when the voice recording has started."),
623
'properties': {
624
'sound': {
625
'description': localize('accessibility.signals.voiceRecordingStarted.sound', "Plays a sound when the voice recording has started."),
626
...soundFeatureBase,
627
},
628
},
629
'default': {
630
'sound': 'on'
631
}
632
},
633
'accessibility.signals.voiceRecordingStopped': {
634
...defaultNoAnnouncement,
635
'description': localize('accessibility.signals.voiceRecordingStopped', "Plays a sound / audio cue when the voice recording has stopped."),
636
'properties': {
637
'sound': {
638
'description': localize('accessibility.signals.voiceRecordingStopped.sound', "Plays a sound when the voice recording has stopped."),
639
...soundFeatureBase,
640
default: 'off'
641
},
642
}
643
},
644
'accessibility.signals.clear': {
645
...signalFeatureBase,
646
'description': localize('accessibility.signals.clear', "Plays a signal - sound (audio cue) and/or announcement (alert) - when a feature is cleared (for example, the terminal, Debug Console, or Output channel)."),
647
'properties': {
648
'sound': {
649
'description': localize('accessibility.signals.clear.sound', "Plays a sound when a feature is cleared."),
650
...soundFeatureBase
651
},
652
'announcement': {
653
'description': localize('accessibility.signals.clear.announcement', "Announces when a feature is cleared."),
654
...announcementFeatureBase
655
},
656
},
657
},
658
'accessibility.signals.editsUndone': {
659
...signalFeatureBase,
660
'description': localize('accessibility.signals.editsUndone', "Plays a signal - sound (audio cue) and/or announcement (alert) - when edits have been undone."),
661
'properties': {
662
'sound': {
663
'description': localize('accessibility.signals.editsUndone.sound', "Plays a sound when edits have been undone."),
664
...soundFeatureBase
665
},
666
'announcement': {
667
'description': localize('accessibility.signals.editsUndone.announcement', "Announces when edits have been undone."),
668
...announcementFeatureBase
669
},
670
},
671
},
672
'accessibility.signals.editsKept': {
673
...signalFeatureBase,
674
'description': localize('accessibility.signals.editsKept', "Plays a signal - sound (audio cue) and/or announcement (alert) - when edits are kept."),
675
'properties': {
676
'sound': {
677
'description': localize('accessibility.signals.editsKept.sound', "Plays a sound when edits are kept."),
678
...soundFeatureBase
679
},
680
'announcement': {
681
'description': localize('accessibility.signals.editsKept.announcement', "Announces when edits are kept."),
682
...announcementFeatureBase
683
},
684
},
685
},
686
'accessibility.signals.save': {
687
'type': 'object',
688
'tags': ['accessibility'],
689
additionalProperties: false,
690
'markdownDescription': localize('accessibility.signals.save', "Plays a signal - sound (audio cue) and/or announcement (alert) - when a file is saved."),
691
'properties': {
692
'sound': {
693
'description': localize('accessibility.signals.save.sound', "Plays a sound when a file is saved."),
694
'type': 'string',
695
'enum': ['userGesture', 'always', 'never'],
696
'default': 'never',
697
'enumDescriptions': [
698
localize('accessibility.signals.save.sound.userGesture', "Plays the sound when a user explicitly saves a file."),
699
localize('accessibility.signals.save.sound.always', "Plays the sound whenever a file is saved, including auto save."),
700
localize('accessibility.signals.save.sound.never', "Never plays the sound.")
701
],
702
},
703
'announcement': {
704
'description': localize('accessibility.signals.save.announcement', "Announces when a file is saved."),
705
'type': 'string',
706
'enum': ['userGesture', 'always', 'never'],
707
'default': 'never',
708
'enumDescriptions': [
709
localize('accessibility.signals.save.announcement.userGesture', "Announces when a user explicitly saves a file."),
710
localize('accessibility.signals.save.announcement.always', "Announces whenever a file is saved, including auto save."),
711
localize('accessibility.signals.save.announcement.never', "Never plays the announcement.")
712
],
713
},
714
},
715
default: {
716
'sound': 'never',
717
'announcement': 'never'
718
}
719
},
720
'accessibility.signals.format': {
721
'type': 'object',
722
'tags': ['accessibility'],
723
additionalProperties: false,
724
'markdownDescription': localize('accessibility.signals.format', "Plays a signal - sound (audio cue) and/or announcement (alert) - when a file or notebook is formatted."),
725
'properties': {
726
'sound': {
727
'description': localize('accessibility.signals.format.sound', "Plays a sound when a file or notebook is formatted."),
728
'type': 'string',
729
'enum': ['userGesture', 'always', 'never'],
730
'default': 'never',
731
'enumDescriptions': [
732
localize('accessibility.signals.format.userGesture', "Plays the sound when a user explicitly formats a file."),
733
localize('accessibility.signals.format.always', "Plays the sound whenever a file is formatted, including if it is set to format on save, type, or, paste, or run of a cell."),
734
localize('accessibility.signals.format.never', "Never plays the sound.")
735
],
736
},
737
'announcement': {
738
'description': localize('accessibility.signals.format.announcement', "Announces when a file or notebook is formatted."),
739
'type': 'string',
740
'enum': ['userGesture', 'always', 'never'],
741
'default': 'never',
742
'enumDescriptions': [
743
localize('accessibility.signals.format.announcement.userGesture', "Announces when a user explicitly formats a file."),
744
localize('accessibility.signals.format.announcement.always', "Announces whenever a file is formatted, including if it is set to format on save, type, or, paste, or run of a cell."),
745
localize('accessibility.signals.format.announcement.never', "Never announces.")
746
],
747
},
748
},
749
default: {
750
'sound': 'never',
751
'announcement': 'never'
752
}
753
},
754
'accessibility.signals.chatUserActionRequired': {
755
...signalFeatureBase,
756
'markdownDescription': localize('accessibility.signals.chatUserActionRequired', "Plays a signal - sound (audio cue) and/or announcement (alert) - when user action is required in the chat."),
757
'properties': {
758
'sound': {
759
'description': localize('accessibility.signals.chatUserActionRequired.sound', "Plays a sound when user action is required in the chat."),
760
'type': 'string',
761
'enum': ['auto', 'on', 'off'],
762
'enumDescriptions': [
763
localize('sound.enabled.autoWindow', "Enable sound when a screen reader is attached."),
764
localize('sound.enabled.on', "Enable sound."),
765
localize('sound.enabled.off', "Disable sound.")
766
],
767
},
768
'announcement': {
769
'description': localize('accessibility.signals.chatUserActionRequired.announcement', "Announces when a user action is required in the chat - including information about the action and how to take it."),
770
...announcementFeatureBase
771
},
772
},
773
default: {
774
'sound': 'auto',
775
'announcement': 'auto'
776
},
777
tags: ['accessibility']
778
},
779
'accessibility.underlineLinks': {
780
'type': 'boolean',
781
'description': localize('accessibility.underlineLinks', "Controls whether links should be underlined in the workbench."),
782
'default': false,
783
},
784
'accessibility.debugWatchVariableAnnouncements': {
785
'type': 'boolean',
786
'description': localize('accessibility.debugWatchVariableAnnouncements', "Controls whether variable changes should be announced in the debug watch view."),
787
'default': true,
788
},
789
'accessibility.replEditor.readLastExecutionOutput': {
790
'type': 'boolean',
791
'description': localize('accessibility.replEditor.readLastExecutedOutput', "Controls whether the output from an execution in the native REPL will be announced."),
792
'default': true,
793
},
794
'accessibility.replEditor.autoFocusReplExecution': {
795
type: 'string',
796
enum: ['none', 'input', 'lastExecution'],
797
default: 'input',
798
description: localize('replEditor.autoFocusAppendedCell', "Control whether focus should automatically be sent to the REPL when code is executed."),
799
},
800
'accessibility.windowTitleOptimized': {
801
'type': 'boolean',
802
'default': true,
803
'markdownDescription': localize('accessibility.windowTitleOptimized', "Controls whether the {0} should be optimized for screen readers when in screen reader mode. When enabled, the window title will have {1} appended to the end.", '`#window.title#`', '`activeEditorState`')
804
},
805
'accessibility.openChatEditedFiles': {
806
'type': 'boolean',
807
'default': true,
808
'markdownDescription': localize('accessibility.openChatEditedFiles', "Controls whether files should be opened when the chat agent has applied edits to them.")
809
},
810
}
811
};
812
813
export function registerAccessibilityConfiguration() {
814
const registry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
815
registry.registerConfiguration(configuration);
816
817
registry.registerConfiguration({
818
...workbenchConfigurationNodeBase,
819
properties: {
820
[AccessibilityWorkbenchSettingId.DimUnfocusedEnabled]: {
821
description: localize('dimUnfocusedEnabled', 'Whether to dim unfocused editors and terminals, which makes it more clear where typed input will go to. This works with the majority of editors with the notable exceptions of those that utilize iframes like notebooks and extension webview editors.'),
822
type: 'boolean',
823
default: false,
824
tags: ['accessibility'],
825
scope: ConfigurationScope.APPLICATION,
826
},
827
[AccessibilityWorkbenchSettingId.DimUnfocusedOpacity]: {
828
markdownDescription: localize('dimUnfocusedOpacity', 'The opacity fraction (0.2 to 1.0) to use for unfocused editors and terminals. This will only take effect when {0} is enabled.', `\`#${AccessibilityWorkbenchSettingId.DimUnfocusedEnabled}#\``),
829
type: 'number',
830
minimum: ViewDimUnfocusedOpacityProperties.Minimum,
831
maximum: ViewDimUnfocusedOpacityProperties.Maximum,
832
default: ViewDimUnfocusedOpacityProperties.Default,
833
tags: ['accessibility'],
834
scope: ConfigurationScope.APPLICATION,
835
},
836
[AccessibilityWorkbenchSettingId.HideAccessibleView]: {
837
description: localize('accessibility.hideAccessibleView', "Controls whether the Accessible View is hidden."),
838
type: 'boolean',
839
default: false,
840
tags: ['accessibility']
841
}
842
}
843
});
844
}
845
846
export { AccessibilityVoiceSettingId };
847
848
export const SpeechTimeoutDefault = 1200;
849
850
export class DynamicSpeechAccessibilityConfiguration extends Disposable implements IWorkbenchContribution {
851
852
static readonly ID = 'workbench.contrib.dynamicSpeechAccessibilityConfiguration';
853
854
constructor(
855
@ISpeechService private readonly speechService: ISpeechService
856
) {
857
super();
858
859
this._register(Event.runAndSubscribe(speechService.onDidChangeHasSpeechProvider, () => this.updateConfiguration()));
860
}
861
862
private updateConfiguration(): void {
863
if (!this.speechService.hasSpeechProvider) {
864
return; // these settings require a speech provider
865
}
866
867
const languages = this.getLanguages();
868
const languagesSorted = Object.keys(languages).sort((langA, langB) => {
869
return languages[langA].name.localeCompare(languages[langB].name);
870
});
871
872
const registry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
873
registry.registerConfiguration({
874
...accessibilityConfigurationNodeBase,
875
properties: {
876
[AccessibilityVoiceSettingId.SpeechTimeout]: {
877
'markdownDescription': localize('voice.speechTimeout', "The duration in milliseconds that voice speech recognition remains active after you stop speaking. For example in a chat session, the transcribed text is submitted automatically after the timeout is met. Set to `0` to disable this feature."),
878
'type': 'number',
879
'default': SpeechTimeoutDefault,
880
'minimum': 0,
881
'tags': ['accessibility']
882
},
883
[AccessibilityVoiceSettingId.IgnoreCodeBlocks]: {
884
'markdownDescription': localize('voice.ignoreCodeBlocks', "Whether to ignore code snippets in text-to-speech synthesis."),
885
'type': 'boolean',
886
'default': false,
887
'tags': ['accessibility']
888
},
889
[AccessibilityVoiceSettingId.SpeechLanguage]: {
890
'markdownDescription': localize('voice.speechLanguage', "The language that text-to-speech and speech-to-text should use. Select `auto` to use the configured display language if possible. Note that not all display languages maybe supported by speech recognition and synthesizers."),
891
'type': 'string',
892
'enum': languagesSorted,
893
'default': 'auto',
894
'tags': ['accessibility'],
895
'enumDescriptions': languagesSorted.map(key => languages[key].name),
896
'enumItemLabels': languagesSorted.map(key => languages[key].name)
897
},
898
[AccessibilityVoiceSettingId.AutoSynthesize]: {
899
'type': 'string',
900
'enum': ['on', 'off'],
901
'enumDescriptions': [
902
localize('accessibility.voice.autoSynthesize.on', "Enable the feature. When a screen reader is enabled, note that this will disable aria updates."),
903
localize('accessibility.voice.autoSynthesize.off', "Disable the feature."),
904
],
905
'markdownDescription': localize('autoSynthesize', "Whether a textual response should automatically be read out aloud when speech was used as input. For example in a chat session, a response is automatically synthesized when voice was used as chat request."),
906
'default': 'off',
907
'tags': ['accessibility']
908
}
909
}
910
});
911
}
912
913
private getLanguages(): { [locale: string]: { name: string } } {
914
return {
915
['auto']: {
916
name: localize('speechLanguage.auto', "Auto (Use Display Language)")
917
},
918
...SPEECH_LANGUAGES
919
};
920
}
921
}
922
923
Registry.as<IConfigurationMigrationRegistry>(WorkbenchExtensions.ConfigurationMigration)
924
.registerConfigurationMigrations([{
925
key: 'audioCues.volume',
926
migrateFn: (value, accessor) => {
927
return [
928
['accessibility.signalOptions.volume', { value }],
929
['audioCues.volume', { value: undefined }]
930
];
931
}
932
}]);
933
934
Registry.as<IConfigurationMigrationRegistry>(WorkbenchExtensions.ConfigurationMigration)
935
.registerConfigurationMigrations([{
936
key: 'audioCues.debouncePositionChanges',
937
migrateFn: (value) => {
938
return [
939
['accessibility.signalOptions.debouncePositionChanges', { value }],
940
['audioCues.debouncePositionChanges', { value: undefined }]
941
];
942
}
943
}]);
944
945
Registry.as<IConfigurationMigrationRegistry>(WorkbenchExtensions.ConfigurationMigration)
946
.registerConfigurationMigrations([{
947
key: 'accessibility.signalOptions',
948
migrateFn: (value, accessor) => {
949
const delayGeneral = getDelaysFromConfig(accessor, 'general');
950
const delayError = getDelaysFromConfig(accessor, 'errorAtPosition');
951
const delayWarning = getDelaysFromConfig(accessor, 'warningAtPosition');
952
const volume = getVolumeFromConfig(accessor);
953
const debouncePositionChanges = getDebouncePositionChangesFromConfig(accessor);
954
const result: [key: string, { value: any }][] = [];
955
if (!!volume) {
956
result.push(['accessibility.signalOptions.volume', { value: volume }]);
957
}
958
if (!!delayGeneral) {
959
result.push(['accessibility.signalOptions.experimental.delays.general', { value: delayGeneral }]);
960
}
961
if (!!delayError) {
962
result.push(['accessibility.signalOptions.experimental.delays.errorAtPosition', { value: delayError }]);
963
}
964
if (!!delayWarning) {
965
result.push(['accessibility.signalOptions.experimental.delays.warningAtPosition', { value: delayWarning }]);
966
}
967
if (!!debouncePositionChanges) {
968
result.push(['accessibility.signalOptions.debouncePositionChanges', { value: debouncePositionChanges }]);
969
}
970
result.push(['accessibility.signalOptions', { value: undefined }]);
971
return result;
972
}
973
}]);
974
975
976
Registry.as<IConfigurationMigrationRegistry>(WorkbenchExtensions.ConfigurationMigration)
977
.registerConfigurationMigrations([{
978
key: 'accessibility.signals.sounds.volume',
979
migrateFn: (value) => {
980
return [
981
['accessibility.signalOptions.volume', { value }],
982
['accessibility.signals.sounds.volume', { value: undefined }]
983
];
984
}
985
}]);
986
987
Registry.as<IConfigurationMigrationRegistry>(WorkbenchExtensions.ConfigurationMigration)
988
.registerConfigurationMigrations([{
989
key: 'accessibility.signals.debouncePositionChanges',
990
migrateFn: (value) => {
991
return [
992
['accessibility.signalOptions.debouncePositionChanges', { value }],
993
['accessibility.signals.debouncePositionChanges', { value: undefined }]
994
];
995
}
996
}]);
997
998
function getDelaysFromConfig(accessor: (key: string) => any, type: 'general' | 'errorAtPosition' | 'warningAtPosition'): { announcement: number; sound: number } | undefined {
999
return accessor(`accessibility.signalOptions.experimental.delays.${type}`) || accessor('accessibility.signalOptions')?.['experimental.delays']?.[`${type}`] || accessor('accessibility.signalOptions')?.['delays']?.[`${type}`];
1000
}
1001
1002
function getVolumeFromConfig(accessor: (key: string) => any): string | undefined {
1003
return accessor('accessibility.signalOptions.volume') || accessor('accessibility.signalOptions')?.volume || accessor('accessibility.signals.sounds.volume') || accessor('audioCues.volume');
1004
}
1005
1006
function getDebouncePositionChangesFromConfig(accessor: (key: string) => any): number | undefined {
1007
return accessor('accessibility.signalOptions.debouncePositionChanges') || accessor('accessibility.signalOptions')?.debouncePositionChanges || accessor('accessibility.signals.debouncePositionChanges') || accessor('audioCues.debouncePositionChanges');
1008
}
1009
1010
Registry.as<IConfigurationMigrationRegistry>(WorkbenchExtensions.ConfigurationMigration)
1011
.registerConfigurationMigrations([{
1012
key: AccessibilityVoiceSettingId.AutoSynthesize,
1013
migrateFn: (value: boolean) => {
1014
let newValue: string | undefined;
1015
if (value === true) {
1016
newValue = 'on';
1017
} else if (value === false) {
1018
newValue = 'off';
1019
} else {
1020
return [];
1021
}
1022
return [
1023
[AccessibilityVoiceSettingId.AutoSynthesize, { value: newValue }],
1024
];
1025
}
1026
}]);
1027
1028
Registry.as<IConfigurationMigrationRegistry>(WorkbenchExtensions.ConfigurationMigration)
1029
.registerConfigurationMigrations([{
1030
key: 'accessibility.signals.chatResponsePending',
1031
migrateFn: (value, accessor) => {
1032
return [
1033
['accessibility.signals.progress', { value }],
1034
['accessibility.signals.chatResponsePending', { value: undefined }],
1035
];
1036
}
1037
}]);
1038
1039
Registry.as<IConfigurationMigrationRegistry>(WorkbenchExtensions.ConfigurationMigration)
1040
.registerConfigurationMigrations(AccessibilitySignal.allAccessibilitySignals.map<ConfigurationMigration | undefined>(item => item.legacySoundSettingsKey ? ({
1041
key: item.legacySoundSettingsKey,
1042
migrateFn: (sound, accessor) => {
1043
const configurationKeyValuePairs: ConfigurationKeyValuePairs = [];
1044
const legacyAnnouncementSettingsKey = item.legacyAnnouncementSettingsKey;
1045
let announcement: string | undefined;
1046
if (legacyAnnouncementSettingsKey) {
1047
announcement = accessor(legacyAnnouncementSettingsKey) ?? undefined;
1048
if (announcement !== undefined && typeof announcement !== 'string') {
1049
announcement = announcement ? 'auto' : 'off';
1050
}
1051
}
1052
configurationKeyValuePairs.push([`${item.legacySoundSettingsKey}`, { value: undefined }]);
1053
configurationKeyValuePairs.push([`${item.settingsKey}`, { value: announcement !== undefined ? { announcement, sound } : { sound } }]);
1054
return configurationKeyValuePairs;
1055
}
1056
}) : undefined).filter(isDefined));
1057
1058
Registry.as<IConfigurationMigrationRegistry>(WorkbenchExtensions.ConfigurationMigration)
1059
.registerConfigurationMigrations(AccessibilitySignal.allAccessibilitySignals.filter(i => !!i.legacyAnnouncementSettingsKey && !!i.legacySoundSettingsKey).map(item => ({
1060
key: item.legacyAnnouncementSettingsKey!,
1061
migrateFn: (announcement, accessor) => {
1062
const configurationKeyValuePairs: ConfigurationKeyValuePairs = [];
1063
const sound = accessor(item.settingsKey)?.sound || accessor(item.legacySoundSettingsKey!);
1064
if (announcement !== undefined && typeof announcement !== 'string') {
1065
announcement = announcement ? 'auto' : 'off';
1066
}
1067
configurationKeyValuePairs.push([`${item.settingsKey}`, { value: announcement !== undefined ? { announcement, sound } : { sound } }]);
1068
configurationKeyValuePairs.push([`${item.legacyAnnouncementSettingsKey}`, { value: undefined }]);
1069
configurationKeyValuePairs.push([`${item.legacySoundSettingsKey}`, { value: undefined }]);
1070
return configurationKeyValuePairs;
1071
}
1072
})));
1073
1074