From 9937d544101e958348690c8176e455c876fcbd40 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 21 Nov 2016 13:59:30 -0800 Subject: [PATCH] Prevent keyboard modifier events from scrolling down Fixes #363 --- package.json | 2 ++ src/test/test.js | 2 +- src/utils/Keyboard.test.ts | 21 +++++++++++++++++++++ src/utils/Keyboard.ts | 22 ++++++++++++++++++++++ src/xterm.js | 3 ++- 5 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 src/utils/Keyboard.test.ts create mode 100644 src/utils/Keyboard.ts diff --git a/package.json b/package.json index 93ed9a7..519b740 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,8 @@ "repository": "https://github.com/sourcelair/xterm.js", "license": "MIT", "devDependencies": { + "@types/chai": "^3.4.34", + "@types/mocha": "^2.2.33", "@types/node": "^6.0.41", "browserify": "^13.1.0", "chai": "3.5.0", diff --git a/src/test/test.js b/src/test/test.js index 08593e1..6f70000 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -194,7 +194,7 @@ describe('xterm.js', function() { terminal.ydisp = 0; terminal.ybase = 40; - terminal.keyDown(); + terminal.keyDown({ keyCode: 0 }); // Ensure that now the terminal is scrolled to bottom assert.equal(terminal.ydisp, terminal.ybase); diff --git a/src/utils/Keyboard.test.ts b/src/utils/Keyboard.test.ts new file mode 100644 index 0000000..618d333 --- /dev/null +++ b/src/utils/Keyboard.test.ts @@ -0,0 +1,21 @@ +import { assert } from 'chai'; +import * as Keyboard from './Keyboard'; + +describe('Keyboard', () => { + describe('isModifierOnlyKeyboardEvent', () => { + it('should return true when only modifier keys are used', () => { + // Note that KeyboardEvent.keyCode is deprecated but we're using it to improve browser + // compatibility. This helper returns the `any` type because KeyboardEvent doesn't exist under + // NodeJS. + function createEvent(keyCode: number): any { + return { keyCode }; + } + assert.isTrue(Keyboard.isModifierOnlyKeyboardEvent(createEvent(16))); + assert.isTrue(Keyboard.isModifierOnlyKeyboardEvent(createEvent(17))); + assert.isTrue(Keyboard.isModifierOnlyKeyboardEvent(createEvent(18))); + assert.isTrue(Keyboard.isModifierOnlyKeyboardEvent(createEvent(91))); + assert.isFalse(Keyboard.isModifierOnlyKeyboardEvent(createEvent(19))); + assert.isFalse(Keyboard.isModifierOnlyKeyboardEvent(createEvent(90))); + }); + }); +}); diff --git a/src/utils/Keyboard.ts b/src/utils/Keyboard.ts new file mode 100644 index 0000000..e43cba4 --- /dev/null +++ b/src/utils/Keyboard.ts @@ -0,0 +1,22 @@ +/** + * xterm.js: xterm, in the browser + * Copyright (c) 2016, SourceLair Private Company (MIT License) + */ + +/** + * Keyboard utilities module. This module contains utilities for dealing with keyboard interaction. + * @module xterm/utils/Keyboard + */ + +/** + * Gets whether a KeyboardEvent is made up entirely of modifier keys. + * + * @param event The event to check. + * @return Whether the KeyboardEvent is made up entirely of modifier keys. + */ +export function isModifierOnlyKeyboardEvent(event: KeyboardEvent): boolean { + return event.keyCode === 16 || // Shift + event.keyCode === 17 || // Control + event.keyCode === 18 || // Alt + event.keyCode === 91; // Meta +} diff --git a/src/xterm.js b/src/xterm.js index 85efc22..5924b79 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -36,6 +36,7 @@ import { EventEmitter } from './EventEmitter.js'; import { Viewport } from './Viewport.js'; import { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard.js'; import * as Browser from './utils/Browser'; +import * as Keyboard from './utils/Keyboard'; /** * Terminal Emulation References: @@ -2426,7 +2427,7 @@ Terminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) { */ Terminal.prototype.keyDown = function(ev) { // Scroll down to prompt, whenever the user presses a key. - if (this.ybase !== this.ydisp) { + if (!Keyboard.isModifierOnlyKeyboardEvent(ev) && this.ybase !== this.ydisp) { this.scrollToBottom(); } -- 2.39.5