allow customizing accessibility signal delays (#212834)

This commit is contained in:
Megan Rogge 2024-05-22 07:58:35 -07:00 committed by GitHub
parent dc11635b73
commit e68a0836fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 87 additions and 21 deletions

View file

@ -1083,6 +1083,10 @@ class StandaloneAccessbilitySignalService implements IAccessibilitySignalService
return ValueWithChangeEvent.const(false);
}
getDelayMs(signal: AccessibilitySignal, modality: AccessibilityModality): number {
return 0;
}
isSoundEnabled(cue: AccessibilitySignal): boolean {
return false;
}

View file

@ -26,7 +26,7 @@ export interface IAccessibilitySignalService {
playSignalLoop(signal: AccessibilitySignal, milliseconds: number): IDisposable;
getEnabledState(signal: AccessibilitySignal, userGesture: boolean, modality?: AccessibilityModality | undefined): IValueWithChangeEvent<boolean>;
getDelayMs(signal: AccessibilitySignal, modality: AccessibilityModality): number;
/**
* Avoid this method and prefer `.playSignal`!
* Only use it when you want to play the sound regardless of enablement, e.g. in the settings quick pick.
@ -240,6 +240,12 @@ export class AccessibilitySignalService extends Disposable implements IAccessibi
public onSoundEnabledChanged(signal: AccessibilitySignal): Event<void> {
return this.getEnabledState(signal, false).onDidChange;
}
public getDelayMs(signal: AccessibilitySignal, modality: AccessibilityModality): number {
const delaySettingsKey = signal.delaySettingsKey ?? 'accessibility.signalOptions.delays.general';
const delaySettingsValue: { sound: number; announcement: number } = this.configurationService.getValue(delaySettingsKey);
return modality === 'sound' ? delaySettingsValue.sound : delaySettingsValue.announcement;
}
}
type EnabledState = 'on' | 'off' | 'auto' | 'userGesture' | 'always' | 'never';
@ -328,6 +334,7 @@ export class AccessibilitySignal {
public readonly settingsKey: string,
public readonly legacyAnnouncementSettingsKey: string | undefined,
public readonly announcementMessage: string | undefined,
public readonly delaySettingsKey: string | undefined
) { }
private static _signals = new Set<AccessibilitySignal>();
@ -344,6 +351,7 @@ export class AccessibilitySignal {
settingsKey: string;
legacyAnnouncementSettingsKey?: string;
announcementMessage?: string;
delaySettingsKey?: string;
}): AccessibilitySignal {
const soundSource = new SoundSource('randomOneOf' in options.sound ? options.sound.randomOneOf : [options.sound]);
const signal = new AccessibilitySignal(
@ -353,6 +361,7 @@ export class AccessibilitySignal {
options.settingsKey,
options.legacyAnnouncementSettingsKey,
options.announcementMessage,
options.delaySettingsKey
);
AccessibilitySignal._signals.add(signal);
return signal;
@ -367,12 +376,14 @@ export class AccessibilitySignal {
sound: Sound.error,
announcementMessage: localize('accessibility.signals.positionHasError', 'Error'),
settingsKey: 'accessibility.signals.positionHasError',
delaySettingsKey: 'accessibility.signalOptions.delays.errorAtPosition'
});
public static readonly warningAtPosition = AccessibilitySignal.register({
name: localize('accessibilitySignals.positionHasWarning.name', 'Warning at Position'),
sound: Sound.warning,
announcementMessage: localize('accessibility.signals.positionHasWarning', 'Warning'),
settingsKey: 'accessibility.signals.positionHasWarning',
delaySettingsKey: 'accessibility.signalOptions.delays.warningAtPosition'
});
public static readonly errorOnLine = AccessibilitySignal.register({

View file

@ -187,10 +187,78 @@ const configuration: IConfigurationNode = {
'type': 'boolean',
'default': false,
},
'delays': {
'type': 'object',
'additionalProperties': false,
'properties': {
'general': {
'type': 'object',
'additionalProperties': false,
'properties': {
'announcement': {
'description': localize('accessibility.signalOptions.delays.general.announcement', "The delay in milliseconds before an announcement is made."),
'type': 'number',
'minimum': 0,
},
'sound': {
'description': localize('accessibility.signalOptions.delays.general.sound', "The delay in milliseconds before a sound is played."),
'type': 'number',
'minimum': 0,
}
},
},
'warningAtPosition': {
'type': 'object',
'additionalProperties': false,
'properties': {
'announcement': {
'description': localize('accessibility.signalOptions.delays.warningAtPosition.announcement', "The delay in milliseconds before an announcement is made when there's a warning at the position."),
'type': 'number',
'minimum': 0,
},
'sound': {
'description': localize('accessibility.signalOptions.delays.warningAtPosition.sound', "The delay in milliseconds before a sound is played when there's a warning at the position."),
'type': 'number',
'minimum': 0,
}
},
},
'errorAtPosition': {
'type': 'object',
'additionalProperties': false,
'properties': {
'announcement': {
'description': localize('accessibility.signalOptions.delays.errorAtPosition.announcement', "The delay in milliseconds before an announcement is made when there's an error at the position."),
'type': 'number',
'minimum': 0,
},
'sound': {
'description': localize('accessibility.signalOptions.delays.errorAtPosition.sound', "The delay in milliseconds before a sound is played when there's an error at the position."),
'type': 'number',
'minimum': 0,
}
},
},
}
}
},
default: {
'volume': 70,
'debouncePositionChanges': false
'debouncePositionChanges': false,
'delays': {
'general': {
'announcement': 3000,
'sound': 400
},
'warningAtPosition': {
'announcement': 3000,
'sound': 1000
},
'errorAtPosition': {
'announcement': 3000,
'sound': 1000
}
}
},
tags: ['accessibility']
},

View file

@ -53,7 +53,7 @@ export class EditorTextPropertySignalsContribution extends Disposable implements
constructor(
@IEditorService private readonly _editorService: IEditorService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@IAccessibilitySignalService private readonly _accessibilitySignalService: IAccessibilitySignalService,
@IAccessibilitySignalService private readonly _accessibilitySignalService: IAccessibilitySignalService
) {
super();
@ -104,7 +104,7 @@ export class EditorTextPropertySignalsContribution extends Disposable implements
for (const modality of ['sound', 'announcement'] as AccessibilityModality[]) {
if (this._accessibilitySignalService.getEnabledState(signal, false, modality).value) {
const delay = this._getDelay(signal, modality) + (didType.get() ? 1000 : 0);
const delay = this._accessibilitySignalService.getDelayMs(signal, modality) + (didType.get() ? 1000 : 0);
timeouts.add(disposableTimeout(() => {
if (source.isPresent(position, mode, undefined)) {
@ -162,23 +162,6 @@ export class EditorTextPropertySignalsContribution extends Disposable implements
}
}));
}
private _getDelay(signal: AccessibilitySignal, modality: AccessibilityModality): number {
// TODO make these delays configurable!
if (signal === AccessibilitySignal.errorAtPosition || signal === AccessibilitySignal.warningAtPosition) {
if (modality === 'sound') {
return 100;
} else {
return 1000;
}
}
if (modality === 'sound') {
return 400;
} else {
return 3000;
}
}
}
interface TextProperty {