diff --git a/src/Terminal.ts b/src/Terminal.ts index 7a068c84..952adb01 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -179,6 +179,13 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp // Store if user went browsing history in scrollback private _userScrolling: boolean; + /** + * Records whether the keydown event has already been handled and triggered a data event, if so + * the keypress event should not trigger a data event but should still print to the textarea so + * screen readers will announce it. + */ + private _keyDownHandled: boolean = false; + private _inputHandler: InputHandler; public linkifier: ILinkifier; public viewport: IViewport; @@ -246,13 +253,13 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp this._instantiationService.setService(IOptionsService, this.optionsService); this._bufferService = this._instantiationService.createInstance(BufferService); this._instantiationService.setService(IBufferService, this._bufferService); + this._logService = this._instantiationService.createInstance(LogService); + this._instantiationService.setService(ILogService, this._logService); this._coreService = this._instantiationService.createInstance(CoreService, () => this.scrollToBottom()); this._instantiationService.setService(ICoreService, this._coreService); this._coreService.onData(e => this._onData.fire(e)); this._dirtyRowService = this._instantiationService.createInstance(DirtyRowService); this._instantiationService.setService(IDirtyRowService, this._dirtyRowService); - this._logService = this._instantiationService.createInstance(LogService); - this._instantiationService.setService(ILogService, this._logService); this._setupOptionsListeners(); this._setup(); @@ -1515,6 +1522,8 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp * @param ev The keydown event to be handled. */ protected _keyDown(event: KeyboardEvent): boolean { + this._keyDownHandled = false; + if (this._customKeyEventHandler && this._customKeyEventHandler(event) === false) { return false; } @@ -1530,12 +1539,6 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp this.updateCursorStyle(event); - // if (result.key === C0.DC3) { // XOFF - // this._writeStopped = true; - // } else if (result.key === C0.DC1) { // XON - // this._writeStopped = false; - // } - if (result.type === KeyboardResultType.PAGE_DOWN || result.type === KeyboardResultType.PAGE_UP) { const scrollCount = this.rows - 1; this.scrollLines(result.type === KeyboardResultType.PAGE_UP ? -scrollCount : scrollCount); @@ -1559,11 +1562,17 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp return true; } + // If ctrl+c or enter is being sent, clear out the textarea. This is done so that screen readers + // will announce deleted characters. This will not work 100% of the time but it should cover + // most scenarios. + if (result.key === C0.ETX || result.key === C0.CR) { + this.textarea.value = ''; + } + + this._keyDownHandled = true; this._onKey.fire({ key: result.key, domEvent: event }); this.showCursor(); this._coreService.triggerDataEvent(result.key, true); - - return this.cancel(event, true); } private _isThirdLevelShift(browser: IBrowser, ev: IKeyboardEvent): boolean { @@ -1621,6 +1630,10 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp protected _keyPress(ev: KeyboardEvent): boolean { let key; + if (this._keyDownHandled) { + return false; + } + if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) { return false; } diff --git a/src/common/services/CoreService.ts b/src/common/services/CoreService.ts index 674cfedb..d17b0c93 100644 --- a/src/common/services/CoreService.ts +++ b/src/common/services/CoreService.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { ICoreService, IOptionsService, IBufferService } from 'common/services/Services'; +import { ICoreService, ILogService, IOptionsService, IBufferService } from 'common/services/Services'; import { EventEmitter, IEvent } from 'common/EventEmitter'; import { IDecPrivateModes } from 'common/Types'; import { clone } from 'common/Clone'; @@ -26,6 +26,7 @@ export class CoreService implements ICoreService { // TODO: Move this into a service private readonly _scrollToBottom: () => void, @IBufferService private readonly _bufferService: IBufferService, + @ILogService private readonly _logService: ILogService, @IOptionsService private readonly _optionsService: IOptionsService ) { this.decPrivateModes = clone(DEFAULT_DEC_PRIVATE_MODES); @@ -53,6 +54,7 @@ export class CoreService implements ICoreService { } // Fire onData API + this._logService.debug('sending data', data); this._onData.fire(data); } }