Skip to content

Commit

Permalink
Merge pull request microsoft#195517 from microsoft/merogge/clear-cue
Browse files Browse the repository at this point in the history
add clear audio cue, accessible notification service
  • Loading branch information
meganrogge authored Oct 13, 2023
2 parents 4efeb37 + 9085a2c commit d3c9c2c
Show file tree
Hide file tree
Showing 14 changed files with 82 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { addDisposableListener } from 'vs/base/browser/dom';
import { alert } from 'vs/base/browser/ui/aria/aria';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { localize } from 'vs/nls';
import { AccessibilitySupport, CONTEXT_ACCESSIBILITY_MODE_ENABLED, IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
Expand All @@ -27,7 +26,7 @@ export class AccessibilityService extends Disposable implements IAccessibilitySe
constructor(
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
@ILayoutService private readonly _layoutService: ILayoutService,
@IConfigurationService protected readonly _configurationService: IConfigurationService,
@IConfigurationService protected readonly _configurationService: IConfigurationService
) {
super();
this._accessibilityModeEnabledContext = CONTEXT_ACCESSIBILITY_MODE_ENABLED.bindTo(this._contextKeyService);
Expand Down Expand Up @@ -116,9 +115,4 @@ export class AccessibilityService extends Disposable implements IAccessibilitySe
alert(message: string): void {
alert(message);
}
alertCleared(): void {
if (this.isScreenReaderOptimized()) {
alert(localize('cleared', "Cleared"));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { Disposable } from 'vs/base/common/lifecycle';
import { localize } from 'vs/nls';
import { IAccessibilityService, IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';

export class AccessibleNotificationService extends Disposable implements IAccessibleNotificationService {
declare readonly _serviceBrand: undefined;

constructor(
@IAudioCueService private readonly _audioCueService: IAudioCueService,
@IConfigurationService private readonly _configurationService: IConfigurationService,
@IAccessibilityService private readonly _accessibilityService: IAccessibilityService) {
super();
}

notifyCleared(): void {
const audioCueValue = this._configurationService.getValue(AudioCue.clear.settingsKey);
if (audioCueValue === 'on' || audioCueValue === 'auto' && this._accessibilityService.isScreenReaderOptimized()) {
this._audioCueService.playAudioCue(AudioCue.clear);
} else {
alert(localize('cleared', "Cleared"));
}
}
}

export class TestAccessibleNotificationService extends Disposable implements IAccessibleNotificationService {

declare readonly _serviceBrand: undefined;

notifyCleared(): void { }
}
13 changes: 12 additions & 1 deletion src/vs/platform/accessibility/common/accessibility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export interface IAccessibilityService {
getAccessibilitySupport(): AccessibilitySupport;
setAccessibilitySupport(accessibilitySupport: AccessibilitySupport): void;
alert(message: string): void;
alertCleared(): void;
}

export const enum AccessibilitySupport {
Expand All @@ -47,3 +46,15 @@ export function isAccessibilityInformation(obj: any): obj is IAccessibilityInfor
&& typeof obj.label === 'string'
&& (typeof obj.role === 'undefined' || typeof obj.role === 'string');
}

export const IAccessibleNotificationService = createDecorator<IAccessibleNotificationService>('accessibleNotificationService');
/**
* Manages whether an audio cue or an aria alert will be used
* in response to actions taken around the workbench.
* Targets screen reader and braille users.
*/
export interface IAccessibleNotificationService {
readonly _serviceBrand: undefined;
notifyCleared(): void;
}

Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,4 @@ export class TestAccessibilityService implements IAccessibilityService {
setAccessibilitySupport(accessibilitySupport: AccessibilitySupport): void { }
getAccessibilitySupport(): AccessibilitySupport { return AccessibilitySupport.Unknown; }
alert(message: string): void { }
alertCleared(): void { }
}
7 changes: 7 additions & 0 deletions src/vs/platform/audioCues/browser/audioCueService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ export class Sound {
public static readonly chatResponseReceived2 = Sound.register({ fileName: 'chatResponseReceived2.mp3' });
public static readonly chatResponseReceived3 = Sound.register({ fileName: 'chatResponseReceived3.mp3' });
public static readonly chatResponseReceived4 = Sound.register({ fileName: 'chatResponseReceived4.mp3' });
public static readonly clear = Sound.register({ fileName: 'clear.mp3' });

private constructor(public readonly fileName: string) { }
}
Expand Down Expand Up @@ -419,6 +420,12 @@ export class AudioCue {
settingsKey: 'audioCues.chatResponsePending'
});

public static readonly clear = AudioCue.register({
name: localize('audioCues.clear', 'Clear'),
sound: Sound.clear,
settingsKey: 'audioCues.clear'
});

private constructor(
public readonly sound: SoundSource,
public readonly name: string,
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ import { UnfocusedViewDimmingContribution } from 'vs/workbench/contrib/accessibi
import { EditorAccessibilityHelpContribution, HoverAccessibleViewContribution, InlineCompletionsAccessibleViewContribution, NotificationAccessibleViewContribution } from 'vs/workbench/contrib/accessibility/browser/accessibilityContributions';
import { AccessibilityStatus } from 'vs/workbench/contrib/accessibility/browser/accessibilityStatus';
import { CommentsAccessibilityHelpContribution } from 'vs/workbench/contrib/comments/browser/comments.contribution';
import { IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
import { AccessibleNotificationService } from 'vs/platform/accessibility/browser/accessibleNotificationService';

registerAccessibilityConfiguration();
registerSingleton(IAccessibleViewService, AccessibleViewService, InstantiationType.Delayed);
registerSingleton(IAccessibleNotificationService, AccessibleNotificationService, InstantiationType.Delayed);

const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
workbenchRegistry.registerWorkbenchContribution(EditorAccessibilityHelpContribution, LifecyclePhase.Eventually);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,13 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).regis
'description': localize('audioCues.chatResponseReceived', "Plays a sound on loop while the response has been received."),
...audioCueFeatureBase,
default: 'off'
}
}
},
'audioCues.clear': {
'description': localize('audioCues.clear', "Plays a sound when a feature is cleared (for example, the terminal, debug console, or output channel). When this is disabled, an aria alert will announce 'Cleared'."),
...audioCueFeatureBase,
default: 'off'
},
},
});

registerAction2(ShowAudioCueHelp);
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Codicon } from 'vs/base/common/codicons';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { ServicesAccessor } from 'vs/editor/browser/editorExtensions';
import { localize } from 'vs/nls';
import { IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
import { Action2, IAction2Options, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
Expand All @@ -18,7 +19,6 @@ import { IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat';
import { ChatEditorInput } from 'vs/workbench/contrib/chat/browser/chatEditorInput';
import { ChatViewPane } from 'vs/workbench/contrib/chat/browser/chatViewPane';
import { CONTEXT_IN_CHAT_SESSION, CONTEXT_PROVIDER_EXISTS } from 'vs/workbench/contrib/chat/common/chatContextKeys';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';

export const ACTION_ID_CLEAR_CHAT = `workbench.action.chat.clear`;

Expand Down Expand Up @@ -118,5 +118,5 @@ export function getClearAction(viewId: string, providerId: string) {
}

function announceChatCleared(accessor: ServicesAccessor): void {
accessor.get(IAccessibilityService).alertCleared();
accessor.get(IAccessibleNotificationService).notifyCleared();
}
6 changes: 3 additions & 3 deletions src/vs/workbench/contrib/debug/browser/repl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ import { Variable } from 'vs/workbench/contrib/debug/common/debugModel';
import { ReplEvaluationResult, ReplGroup } from 'vs/workbench/contrib/debug/common/replModel';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { registerNavigableContainer } from 'vs/workbench/browser/actions/widgetNavigationCommands';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';

const $ = dom.$;

Expand Down Expand Up @@ -976,9 +976,9 @@ registerAction2(class extends ViewAction<Repl> {
}

runInView(_accessor: ServicesAccessor, view: Repl): void {
const accessibilityService = _accessor.get(IAccessibilityService);
const accessibleNotificationService = _accessor.get(IAccessibleNotificationService);
view.clearRepl();
accessibilityService.alertCleared();
accessibleNotificationService.notifyCleared();
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
import { Categories } from 'vs/platform/action/common/actionCommonCategories';
import { Disposable, dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';

// Register Service
registerSingleton(IOutputService, OutputService, InstantiationType.Delayed);
Expand Down Expand Up @@ -221,11 +221,11 @@ class OutputContribution extends Disposable implements IWorkbenchContribution {
}
async run(accessor: ServicesAccessor): Promise<void> {
const outputService = accessor.get(IOutputService);
const accesibilityService = accessor.get(IAccessibilityService);
const accessibleNotificationService = accessor.get(IAccessibleNotificationService);
const activeChannel = outputService.getActiveChannel();
if (activeChannel) {
activeChannel.clear();
accesibilityService.alertCleared();
accessibleNotificationService.notifyCleared();
}
}
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
@IOpenerService private readonly _openerService: IOpenerService,
@ICommandService private readonly _commandService: ICommandService,
@IAudioCueService private readonly _audioCueService: IAudioCueService,
@IViewDescriptorService private readonly _viewDescriptorService: IViewDescriptorService,
@IViewDescriptorService private readonly _viewDescriptorService: IViewDescriptorService
) {
super();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService
import { debounce } from 'vs/base/common/decorators';
import { MouseWheelClassifier } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { IMouseWheelEvent, StandardWheelEvent } from 'vs/base/browser/mouseEvent';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';

const enum RenderConstants {
/**
Expand Down Expand Up @@ -204,7 +204,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach
@ITelemetryService private readonly _telemetryService: ITelemetryService,
@IClipboardService private readonly _clipboardService: IClipboardService,
@IContextKeyService contextKeyService: IContextKeyService,
@IAccessibilityService private readonly _accessibilityService: IAccessibilityService
@IAccessibleNotificationService private readonly _accessibleNotificationService: IAccessibleNotificationService
) {
super();
const font = this._configHelper.getFont(undefined, true);
Expand Down Expand Up @@ -590,7 +590,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach
// the prompt being written
this._capabilities.get(TerminalCapability.CommandDetection)?.handlePromptStart();
this._capabilities.get(TerminalCapability.CommandDetection)?.handleCommandStart();
this._accessibilityService.alertCleared();
this._accessibleNotificationService.notifyCleared();
}

hasSelection(): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import * as assert from 'assert';
import { importAMDNodeModule } from 'vs/amdX';
import { isWindows } from 'vs/base/common/platform';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { TestAccessibilityService } from 'vs/platform/accessibility/test/common/testAccessibilityService';
import { TestAccessibleNotificationService } from 'vs/platform/accessibility/browser/accessibleNotificationService';
import { IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
Expand Down Expand Up @@ -67,7 +67,7 @@ suite('Buffer Content Tracker', () => {
instantiationService.stub(IContextMenuService, store.add(instantiationService.createInstance(ContextMenuService)));
instantiationService.stub(ILifecycleService, store.add(new TestLifecycleService()));
instantiationService.stub(IContextKeyService, store.add(new MockContextKeyService()));
instantiationService.stub(IAccessibilityService, new TestAccessibilityService());
instantiationService.stub(IAccessibleNotificationService, store.add(new TestAccessibleNotificationService()));
configHelper = store.add(instantiationService.createInstance(TerminalConfigHelper));
capabilities = store.add(new TerminalCapabilityStore());
if (!isWindows) {
Expand Down

0 comments on commit d3c9c2c

Please sign in to comment.