use enums instead

This commit is contained in:
Jörg Breitbart
2019-07-19 23:55:18 +02:00
parent b64ed4f540
commit f239e10ed6
8 changed files with 183 additions and 175 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ export class MockCoreMouseService implements ICoreMouseService {
addProtocol(name: string): void {}
reset(): void {}
triggerMouseEvent(event: ICoreMouseEvent): boolean { return false; }
onProtocolChange: IEvent<CoreMouseEventType[]> = new EventEmitter<CoreMouseEventType[]>().event;
onProtocolChange: IEvent<CoreMouseEventType> = new EventEmitter<CoreMouseEventType>().event;
}
export class MockCoreService implements ICoreService {
+30 -10
View File
@@ -162,6 +162,20 @@ export interface IRowRange {
/**
* Interface for mouse events in the core.
*/
export const enum CoreMouseButton {
LEFT = 0,
MIDDLE = 1,
RIGHT = 2,
NONE = 3,
WHEEL = 64
}
export const enum CoreMouseAction {
UP = 0,
DOWN = 1,
MOVE = 32
}
export interface ICoreMouseEvent {
/** column (zero based). */
col: number;
@@ -174,8 +188,8 @@ export interface ICoreMouseEvent {
* There are invalid combinations of buttons and actions possible
* (like move + wheel), those are silently ignored by the CoreMouseService.
*/
button: 'left' | 'middle' | 'right' | 'wheel' | 'none';
action: 'up' | 'down' | 'move';
button: CoreMouseButton;
action: CoreMouseAction;
/**
* Modifier states.
* Protocols will add/ignore those based on specific restrictions.
@@ -190,14 +204,20 @@ export interface ICoreMouseEvent {
* To be reported to the browser component which events a mouse
* protocol wants to be catched and forwarded as an ICoreMouseEvent
* to CoreMouseService.
* Known types:
* - mousedown: any mousedown event
* - mouseup: any mouseup event
* - wheel: any wheel event
* - mousedrag: any mousemove event while a button is pressed
* - mousemove: any mousemove event
*/
export type CoreMouseEventType = 'mousedown' | 'mouseup' | 'wheel' | 'mousemove' | 'mousedrag';
export const enum CoreMouseEventType {
NONE = 0,
/** any mousedown event */
DOWN = 1,
/** any mouseup event */
UP = 2,
/** any mousemove event while a button is held */
DRAG = 4,
/** any mousemove event without a button */
MOVE = 8,
/** any wheel event */
WHEEL = 16
}
/**
* Mouse protocol interface.
@@ -208,7 +228,7 @@ export type CoreMouseEventType = 'mousedown' | 'mouseup' | 'wheel' | 'mousemove'
* modifiers or filtering invalid event types.
*/
export interface ICoreMouseProtocol {
events: CoreMouseEventType[];
events: CoreMouseEventType;
restrict: (e: ICoreMouseEvent) => boolean;
}
+71 -68
View File
@@ -5,7 +5,7 @@
import { CoreMouseService } from 'common/services/CoreMouseService';
import { MockCoreService, MockBufferService } from 'common/TestUtils.test';
import { assert } from 'chai';
import { ICoreMouseEvent, CoreMouseEventType } from 'common/Types';
import { ICoreMouseEvent, CoreMouseEventType, CoreMouseButton, CoreMouseAction } from 'common/Types';
// needed mock services
const bufferService = new MockBufferService(300, 100);
@@ -56,18 +56,21 @@ describe('CoreMouseService', () => {
});
it('addProtocol', () => {
const cms = new CoreMouseService(bufferService, coreService);
cms.addProtocol('XYZ', { events: [], restrict: (e: ICoreMouseEvent) => false });
cms.addProtocol('XYZ', { events: CoreMouseEventType.NONE, restrict: (e: ICoreMouseEvent) => false });
cms.activeProtocol = 'XYZ';
assert.equal(cms.activeProtocol, 'XYZ');
});
it('onProtocolChange', () => {
const cms = new CoreMouseService(bufferService, coreService);
const wantedEvents: CoreMouseEventType[][] = [];
const wantedEvents: CoreMouseEventType[] = [];
cms.onProtocolChange(events => wantedEvents.push(events));
cms.activeProtocol = 'NONE';
assert.deepEqual(wantedEvents, [[]]);
assert.deepEqual(wantedEvents, [CoreMouseEventType.NONE]);
cms.activeProtocol = 'ANY';
assert.deepEqual(wantedEvents, [[], ['mousedown', 'mouseup', 'wheel', 'mousedrag', 'mousemove']]);
assert.deepEqual(wantedEvents, [
CoreMouseEventType.NONE,
CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL | CoreMouseEventType.DRAG | CoreMouseEventType.MOVE
]);
});
describe('triggerMouseEvent', () => {
let cms: CoreMouseService;
@@ -78,68 +81,68 @@ describe('CoreMouseService', () => {
coreService.triggerDataEvent = (data: string, userInput?: boolean) => reports.push(data);
});
it('NONE', () => {
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'down' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'up' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'move' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'middle', action: 'down' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'right', action: 'down' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'wheel', action: 'up' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'none', action: 'move' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.UP }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.MOVE }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.DOWN }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.DOWN }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.UP }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE }), false);
});
it('X10', () => {
cms.activeProtocol = 'X10';
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'up' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'move' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'middle', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'right', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'wheel', action: 'up' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'none', action: 'move' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.UP }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.MOVE }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.DOWN }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.DOWN }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.UP }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE }), false);
});
it('VT200', () => {
cms.activeProtocol = 'VT200';
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'up' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'move' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'middle', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'right', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'wheel', action: 'up' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'none', action: 'move' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.UP }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.MOVE }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.DOWN }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.DOWN }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.UP }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE }), false);
});
it('DRAG', () => {
cms.activeProtocol = 'DRAG';
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'up' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'move' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'middle', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'right', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'wheel', action: 'up' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.UP }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.MOVE }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.DOWN }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.DOWN }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.UP }), true);
});
it('ANY', () => {
cms.activeProtocol = 'ANY';
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'up' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'move' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'middle', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'right', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'wheel', action: 'up' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'none', action: 'move' }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.UP }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.MOVE }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.DOWN }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.DOWN }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.UP }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE }), true);
// should not report in any case
// invalid button + action combinations
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'wheel', action: 'move' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'none', action: 'down' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'none', action: 'up' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.MOVE }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.DOWN }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.UP }), false);
// invalid coords
assert.equal(cms.triggerMouseEvent({ col: -1, row: 0, button: 'left', action: 'down' }), false);
assert.equal(cms.triggerMouseEvent({ col: 500, row: 0, button: 'left', action: 'down' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: -1, button: 'left', action: 'down' }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 500, button: 'left', action: 'down' }), false);
assert.equal(cms.triggerMouseEvent({ col: -1, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), false);
assert.equal(cms.triggerMouseEvent({ col: 500, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: -1, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), false);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 500, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), false);
});
describe('coords', () => {
it('DEFAULT encoding', () => {
cms.activeProtocol = 'ANY';
for (let i = 0; i < bufferService.cols; ++i) {
assert.equal(cms.triggerMouseEvent({ col: i, row: 0, button: 'left', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: i, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
// capped at 95
if (i < 95) {
assert.deepEqual(toBytes(reports.pop()), [0x1b, 0x5b, 0x4d, 0x20, i + 33, 0x21]);
@@ -152,7 +155,7 @@ describe('CoreMouseService', () => {
cms.activeProtocol = 'ANY';
cms.activeEncoding = 'UTF8';
for (let i = 0; i < bufferService.cols; ++i) {
assert.equal(cms.triggerMouseEvent({ col: i, row: 0, button: 'left', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: i, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
assert.deepEqual(toBytes(reports.pop()), [0x1b, 0x5b, 0x4d, 0x20, i + 33, 0x21]);
}
});
@@ -160,7 +163,7 @@ describe('CoreMouseService', () => {
cms.activeProtocol = 'ANY';
cms.activeEncoding = 'SGR';
for (let i = 0; i < bufferService.cols; ++i) {
assert.equal(cms.triggerMouseEvent({ col: i, row: 0, button: 'left', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: i, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
assert.deepEqual(reports.pop(), `\x1b[<0;${i + 1};1M`);
}
});
@@ -168,7 +171,7 @@ describe('CoreMouseService', () => {
cms.activeProtocol = 'ANY';
cms.activeEncoding = 'URXVT';
for (let i = 0; i < bufferService.cols; ++i) {
assert.equal(cms.triggerMouseEvent({ col: i, row: 0, button: 'left', action: 'down' }), true);
assert.equal(cms.triggerMouseEvent({ col: i, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN }), true);
assert.deepEqual(reports.pop(), `\x1b[32;${i + 1};1M`);
}
});
@@ -177,36 +180,36 @@ describe('CoreMouseService', () => {
cms.activeProtocol = 'ANY';
cms.activeEncoding = 'DEFAULT';
// all buttons + down + no modifer
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'down', ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'middle', action: 'down', ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'right', action: 'down', ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'wheel', action: 'down', ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.DOWN, ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.DOWN, ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.DOWN, ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.DOWN, ctrl: false, alt: false, shift: false }), true);
assert.deepEqual(reports, ['\x1b[M !!', '\x1b[M!!!', '\x1b[M"!!', '\x1b[Ma!!']);
while (reports.pop()) { }
// all buttons + up + no modifier
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'up', ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'middle', action: 'up', ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'right', action: 'up', ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'wheel', action: 'up', ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.UP, ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.UP, ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.UP, ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.WHEEL, action: CoreMouseAction.UP, ctrl: false, alt: false, shift: false }), true);
assert.deepEqual(reports, ['\x1b[M#!!', '\x1b[M#!!', '\x1b[M#!!', '\x1b[M`!!']);
while (reports.pop()) { }
// all buttons + move + no modifier
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'left', action: 'move', ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'middle', action: 'move', ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'right', action: 'move', ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'none', action: 'move', ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.LEFT, action: CoreMouseAction.MOVE, ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.MIDDLE, action: CoreMouseAction.MOVE, ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.RIGHT, action: CoreMouseAction.MOVE, ctrl: false, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: false, alt: false, shift: false }), true);
assert.deepEqual(reports, ['\x1b[M@!!', '\x1b[MA!!', '\x1b[MB!!', '\x1b[MC!!']);
while (reports.pop()) { }
// button none + move + modifiers
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'none', action: 'move', ctrl: true, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'none', action: 'move', ctrl: false, alt: true, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'none', action: 'move', ctrl: false, alt: false, shift: true }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'none', action: 'move', ctrl: true, alt: true, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'none', action: 'move', ctrl: false, alt: true, shift: true }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: 'none', action: 'move', ctrl: true, alt: true, shift: true }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: true, alt: false, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: false, alt: true, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: false, alt: false, shift: true }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: true, alt: true, shift: false }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: false, alt: true, shift: true }), true);
assert.equal(cms.triggerMouseEvent({ col: 0, row: 0, button: CoreMouseButton.NONE, action: CoreMouseAction.MOVE, ctrl: true, alt: true, shift: true }), true);
assert.deepEqual(reports, ['\x1b[MS!!', '\x1b[MK!!', '\x1b[MG!!', '\x1b[M[!!', '\x1b[MO!!', '\x1b[M_!!']);
while (reports.pop()) { }
});
+31 -46
View File
@@ -4,19 +4,19 @@
*/
import { IBufferService, ICoreService, ICoreMouseService } from 'common/services/Services';
import { EventEmitter, IEvent } from 'common/EventEmitter';
import { ICoreMouseProtocol, ICoreMouseEvent, CoreMouseEncoding, CoreMouseEventType } from 'common/Types';
import { ICoreMouseProtocol, ICoreMouseEvent, CoreMouseEncoding, CoreMouseEventType, CoreMouseButton, CoreMouseAction } from 'common/Types';
/**
* Supported default protocols.
*/
const DEFAULT_PROCOTOLS: {[key: string]: ICoreMouseProtocol} = {
const DEFAULT_PROTOCOLS: {[key: string]: ICoreMouseProtocol} = {
/**
* NONE
* Events: none
* Modifiers: none
*/
NONE: {
events: [],
events: CoreMouseEventType.NONE,
restrict: () => false
},
/**
@@ -25,10 +25,10 @@ const DEFAULT_PROCOTOLS: {[key: string]: ICoreMouseProtocol} = {
* Modifiers: none (TBD)
*/
X10: {
events: ['mousedown'],
events: CoreMouseEventType.DOWN,
restrict: (e: ICoreMouseEvent) => {
// no wheel (TBD), no move, no up
if (e.button === 'wheel' || e.action !== 'down') {
if (e.button === CoreMouseButton.WHEEL || e.action !== CoreMouseAction.DOWN) {
return false;
}
// no modifiers (TDB)
@@ -44,10 +44,10 @@ const DEFAULT_PROCOTOLS: {[key: string]: ICoreMouseProtocol} = {
* Modifiers: CTRL (TBD)
*/
VT200: {
events: ['mousedown', 'mouseup', 'wheel'],
events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL,
restrict: (e: ICoreMouseEvent) => {
// no move
if (e.action === 'move') {
if (e.action === CoreMouseAction.MOVE) {
return false;
}
// modifiers - only ctrl?
@@ -62,10 +62,10 @@ const DEFAULT_PROCOTOLS: {[key: string]: ICoreMouseProtocol} = {
* Modifiers: CTRL | ALT | SHIFT
*/
DRAG: {
events: ['mousedown', 'mouseup', 'wheel', 'mousedrag'],
events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL | CoreMouseEventType.DRAG,
restrict: (e: ICoreMouseEvent) => {
// no move without button
if (e.action === 'move' && e.button === 'none') {
if (e.action === CoreMouseAction.MOVE && e.button === CoreMouseButton.NONE) {
return false;
}
// modifiers unclear - let all pass for now
@@ -78,47 +78,32 @@ const DEFAULT_PROCOTOLS: {[key: string]: ICoreMouseProtocol} = {
* Modifiers: CTRL | ALT | SHIFT
*/
ANY: {
events: ['mousedown', 'mouseup', 'wheel', 'mousedrag', 'mousemove'],
events:
CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL
| CoreMouseEventType.DRAG | CoreMouseEventType.MOVE,
restrict: (e: ICoreMouseEvent) => true
}
};
/**
* Mapping of buttons and actions to event codes. (taken from xterm spec)
* More than 3 buttons are not supported.
*/
enum CODEMAP {
// buttons
left = 0,
middle = 1,
right = 2,
none = 3,
wheel = 64,
// actions
up = 0,
down = 1,
move = 32,
// modifiers
shift = 4,
alt = 8,
ctrl = 16
const enum Modifiers {
SHIFT = 4,
ALT = 8,
CTRL = 16
}
// helper for default encoders to generate the event code.
function eventCode(e: ICoreMouseEvent, isSGR: boolean): number {
const button = CODEMAP[e.button];
const action = CODEMAP[e.action];
const modifier = (e.ctrl ? CODEMAP.ctrl : 0) | (e.shift ? CODEMAP.shift : 0) | (e.alt ? CODEMAP.alt : 0);
let code = button | modifier;
if (e.button === 'wheel') {
code |= action;
const modifier = (e.ctrl ? Modifiers.CTRL : 0) | (e.shift ? Modifiers.SHIFT : 0) | (e.alt ? Modifiers.ALT : 0);
let code = e.button | modifier;
if (e.button === CoreMouseButton.WHEEL) {
code |= e.action;
} else {
if (e.action === 'move') {
code |= CODEMAP.move;
} else if (e.action === 'up' && !isSGR) {
if (e.action === CoreMouseAction.MOVE) {
code |= CoreMouseAction.MOVE;
} else if (e.action === CoreMouseAction.UP && !isSGR) {
// special case - only SGR can report button on release
// all others have to go with NONE
code |= CODEMAP.none;
code |= CoreMouseButton.NONE;
}
}
return code;
@@ -161,7 +146,7 @@ const DEFAULT_ENCODINGS: {[key: string]: CoreMouseEncoding} = {
* Can report button on release and works with a well formed sequence.
*/
SGR: (e: ICoreMouseEvent) => {
const final = (e.action === 'up' && e.button !== 'wheel') ? 'm' : 'M';
const final = (e.action === CoreMouseAction.UP && e.button !== CoreMouseButton.WHEEL) ? 'm' : 'M';
return `\x1b[<${eventCode(e, true)};${e.col};${e.row}${final}`;
},
/**
@@ -195,7 +180,7 @@ export class CoreMouseService implements ICoreMouseService {
private _encodings: {[name: string]: CoreMouseEncoding} = {};
private _activeProtocol: string = '';
private _activeEncoding: string = '';
private _onProtocolChange = new EventEmitter<CoreMouseEventType[]>();
private _onProtocolChange = new EventEmitter<CoreMouseEventType>();
private _lastEvent: ICoreMouseEvent | null = null;
constructor(
@@ -203,7 +188,7 @@ export class CoreMouseService implements ICoreMouseService {
@ICoreService private readonly _coreService: ICoreService
) {
// register default protocols and encodings
Object.keys(DEFAULT_PROCOTOLS).forEach(name => this.addProtocol(name, DEFAULT_PROCOTOLS[name]));
Object.keys(DEFAULT_PROTOCOLS).forEach(name => this.addProtocol(name, DEFAULT_PROTOCOLS[name]));
Object.keys(DEFAULT_ENCODINGS).forEach(name => this.addEncoding(name, DEFAULT_ENCODINGS[name]));
// call reset to set defaults
this.reset();
@@ -249,7 +234,7 @@ export class CoreMouseService implements ICoreMouseService {
/**
* Event to announce changes in mouse tracking.
*/
public get onProtocolChange(): IEvent<CoreMouseEventType[]> {
public get onProtocolChange(): IEvent<CoreMouseEventType> {
return this._onProtocolChange.event;
}
@@ -271,10 +256,10 @@ export class CoreMouseService implements ICoreMouseService {
}
// filter nonsense combinations of button + action
if (event.button === 'wheel' && event.action === 'move') {
if (event.button === CoreMouseButton.WHEEL && event.action === CoreMouseAction.MOVE) {
return false;
}
if (event.button === 'none' && event.action !== 'move') {
if (event.button === CoreMouseButton.NONE && event.action !== CoreMouseAction.MOVE) {
return false;
}
@@ -283,7 +268,7 @@ export class CoreMouseService implements ICoreMouseService {
event.row++;
// debounce move at grid level
if (event.action === 'move' && this._lastEvent && this._compareEvents(this._lastEvent, event)) {
if (event.action === CoreMouseAction.MOVE && this._lastEvent && this._compareEvents(this._lastEvent, event)) {
return false;
}
+1 -1
View File
@@ -46,7 +46,7 @@ export interface ICoreMouseService {
/**
* Event to announce changes in mouse tracking.
*/
onProtocolChange: IEvent<CoreMouseEventType[]>;
onProtocolChange: IEvent<CoreMouseEventType>;
}
export const ICoreService = createDecorator<ICoreService>('CoreService');