From 776c6dffea382bdace43919faf8fc8707e4ec826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Tue, 23 Jul 2019 20:16:42 +0200 Subject: [PATCH] refactor buttons, wheel with left right --- src/Terminal.ts | 27 ++++++++++----- src/common/Types.d.ts | 20 ++++++++--- src/common/services/CoreMouseService.test.ts | 1 + src/common/services/CoreMouseService.ts | 36 +++++++++++++------- 4 files changed, 58 insertions(+), 26 deletions(-) diff --git a/src/Terminal.ts b/src/Terminal.ts index e19a4516..92d904e9 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -734,35 +734,44 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp // buttons is not supported on macOS, try to get a value from button instead but = CoreMouseButton.NONE; if (ev.button !== undefined) { - but = ev.button < 3 ? ev.button : CoreMouseButton.NONE; + but = ev.button < 3 ? ev.button : undefined; } } else { but = ev.buttons & 1 ? CoreMouseButton.LEFT : ev.buttons & 4 ? CoreMouseButton.MIDDLE : ev.buttons & 2 ? CoreMouseButton.RIGHT : - CoreMouseButton.NONE; + CoreMouseButton.NONE; // fallback to NONE } break; case 'mouseup': action = CoreMouseAction.UP; - but = ev.button < 3 ? ev.button : CoreMouseButton.NONE; + // AUX buttons are currently not supported + but = ev.button < 3 ? ev.button : undefined; break; case 'mousedown': action = CoreMouseAction.DOWN; - but = ev.button < 3 ? ev.button : CoreMouseButton.NONE; - break; - case 'DOMMouseScroll': - action = ev.detail < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN; - but = CoreMouseButton.WHEEL; + but = ev.button < 3 ? ev.button : undefined; break; case 'wheel': - action = (ev).deltaY < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN; + // precedence: up/down over left/right + // FIXME: Can we have both in one event? Need to send another wheel event? + if ((ev as WheelEvent).deltaY !== 0) { + action = (ev as WheelEvent).deltaY < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN; + } else if ((ev as WheelEvent).deltaX !== 0) { + action = (ev as WheelEvent).deltaX < 0 ? CoreMouseAction.LEFT : CoreMouseAction.RIGHT; + } but = CoreMouseButton.WHEEL; break; default: // dont handle other event types by accident return false; } + + // exit if we cannot determine button/action values + if (action === undefined || but === undefined) { + return false; + } + return self._coreMouseService.triggerMouseEvent({ col: pos.x - 33, // FIXME: why -33 here? row: pos.y - 33, diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index 7f86b7ec..2f742038 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -167,13 +167,25 @@ export const enum CoreMouseButton { MIDDLE = 1, RIGHT = 2, NONE = 3, - WHEEL = 64 + WHEEL = 4, + // additional buttons 1..8 + // untested! + AUX1 = 8, + AUX2 = 9, + AUX3 = 10, + AUX4 = 11, + AUX5 = 12, + AUX6 = 13, + AUX7 = 14, + AUX8 = 15 } export const enum CoreMouseAction { - UP = 0, - DOWN = 1, - MOVE = 32 + UP = 0, // buttons, wheel + DOWN = 1, // buttons, wheel + LEFT = 2, // wheel only + RIGHT = 3, // wheel only + MOVE = 32 // buttons only } export interface ICoreMouseEvent { diff --git a/src/common/services/CoreMouseService.test.ts b/src/common/services/CoreMouseService.test.ts index 63f39f5d..2063a496 100644 --- a/src/common/services/CoreMouseService.test.ts +++ b/src/common/services/CoreMouseService.test.ts @@ -177,6 +177,7 @@ describe('CoreMouseService', () => { }); }); it('eventCodes with modifiers (DEFAULT encoding)', () => { + // TODO: implement AUX button tests cms.activeProtocol = 'ANY'; cms.activeEncoding = 'DEFAULT'; // all buttons + down + no modifer diff --git a/src/common/services/CoreMouseService.ts b/src/common/services/CoreMouseService.ts index 659a80ff..957537e4 100644 --- a/src/common/services/CoreMouseService.ts +++ b/src/common/services/CoreMouseService.ts @@ -89,11 +89,18 @@ const enum Modifiers { // helper for default encoders to generate the event code. function eventCode(e: ICoreMouseEvent, isSGR: boolean): number { - const modifier = (e.ctrl ? Modifiers.CTRL : 0) | (e.shift ? Modifiers.SHIFT : 0) | (e.alt ? Modifiers.ALT : 0); - let code = e.button | modifier; + let code = (e.ctrl ? Modifiers.CTRL : 0) | (e.shift ? Modifiers.SHIFT : 0) | (e.alt ? Modifiers.ALT : 0); if (e.button === CoreMouseButton.WHEEL) { + code |= 64; code |= e.action; } else { + code |= e.button & 3; + if (e.button & 4) { + code |= 64; + } + if (e.button & 8) { + code |= 128; + } if (e.action === CoreMouseAction.MOVE) { code |= CoreMouseAction.MOVE; } else if (e.action === CoreMouseAction.UP && !isSGR) { @@ -244,40 +251,43 @@ export class CoreMouseService implements ICoreMouseService { * Note: The method will change values of the given event object * to fullfill protocol and encoding restrictions. */ - public triggerMouseEvent(event: ICoreMouseEvent): boolean { + public triggerMouseEvent(e: ICoreMouseEvent): boolean { // range check for col/row - if (event.col < 0 || event.col >= this._bufferService.cols - || event.row < 0 || event.row >= this._bufferService.rows) { + if (e.col < 0 || e.col >= this._bufferService.cols + || e.row < 0 || e.row >= this._bufferService.rows) { return false; } // filter nonsense combinations of button + action - if (event.button === CoreMouseButton.WHEEL && event.action === CoreMouseAction.MOVE) { + if (e.button === CoreMouseButton.WHEEL && e.action === CoreMouseAction.MOVE) { return false; } - if (event.button === CoreMouseButton.NONE && event.action !== CoreMouseAction.MOVE) { + if (e.button === CoreMouseButton.NONE && e.action !== CoreMouseAction.MOVE) { + return false; + } + if (e.button !== CoreMouseButton.WHEEL && (e.action === CoreMouseAction.LEFT || e.action === CoreMouseAction.RIGHT)) { return false; } // report 1-based coords - event.col++; - event.row++; + e.col++; + e.row++; // debounce move at grid level - if (event.action === CoreMouseAction.MOVE && this._lastEvent && this._compareEvents(this._lastEvent, event)) { + if (e.action === CoreMouseAction.MOVE && this._lastEvent && this._compareEvents(this._lastEvent, e)) { return false; } // apply protocol restrictions - if (!this._protocols[this._activeProtocol].restrict(event)) { + if (!this._protocols[this._activeProtocol].restrict(e)) { return false; } // encode report and send - const report = this._encodings[this._activeEncoding](event); + const report = this._encodings[this._activeEncoding](e); this._coreService.triggerDataEvent(report, true); - this._lastEvent = event; + this._lastEvent = e; return true; }