deactivate wheel left/right, docs

This commit is contained in:
Jörg Breitbart
2019-07-24 15:14:37 +02:00
parent f68769e5f3
commit 4fba080d34
2 changed files with 80 additions and 45 deletions
+57 -34
View File
@@ -48,43 +48,66 @@ stdin.addListener('data', function(data) {
} }
}); });
// basic button codes (modifier keys are added on top) // button definitions
const BUTTONS = { const buttons = {
0: ['left', 'press'], '<none>': -1,
1: ['middle', 'press'], left: 0,
2: ['right', 'press'], middle: 1,
3: ['', 'release'], right: 2,
32: ['left', 'move'], released: 3,
33: ['middle', 'move'], wheelUp: 4,
34: ['right', 'move'], wheelDown: 5,
35: ['', 'move'], wheelLeft: 6,
64: ['wheel', 'up'], wheelRight: 7,
65: ['wheel', 'down'] aux1: 8,
aux2: 9,
aux3: 10,
aux4: 11,
aux5: 12,
aux6: 13,
aux7: 14,
aux8: 15
}; };
const reverseButtons = {};
for (const el in buttons) {
reverseButtons[buttons[el]] = el;
}
// extract button data from buttonCode
function evalButtonCode(code) { function evalButtonCode(code) {
// 2 bits: 0 - left, 1 - middle, 2 - right, 3 - release // more than 15 buttons are not supported
// higher bits: 4 - shift, 8 - meta, 16 - control if (code > 255) {
const modifier = {shift: !!(code & 4), meta: !!(code & 8), control: !!(code & 16)}; return {button: 'invalid', action: 'invalid', modifier: {}};
const wheel = code & 64;
let action;
let button;
if (wheel) {
action = (code & 1) ? 'down' : 'up';
button = 'wheel';
} else {
action = code & 32 ? 'move' : code === 3 ? 'release' : 'press';
code &= 3; // TODO: more than 3 buttons + wheel
button = code === 0 ? 'left' : code === 1 ? 'middle' : code === 2 ? 'right' : '<none>';
} }
return {button, action, modifier}; const modifier = {shift: !!(code & 4), meta: !!(code & 8), control: !!(code & 16)};
const move = code & 32;
let button = code & 3;
if (code & 128) {
button |= 8;
}
if (code & 64) {
button |= 4
}
let actionS = 'press';
let buttonS = reverseButtons[button];
if (button === 3) {
buttonS = '<none>';
actionS = 'release';
}
if (move) {
actionS = 'move';
} else if (4 <= button && button <= 7) {
buttonS = 'wheel';
actionS = button === 4 ? 'up' : button === 5 ? 'down' : button === 6 ? 'left' : 'right';
}
return {button: buttonS, action: actionS, modifier};
} }
// protocols // protocols
const PROTOCOLS = { const PROTOCOLS = {
'9 (X10: press only)': '\x1b[?9h', '9 (X10: press only)': '\x1b[?9h',
'1000 (VT200: press, release, wheel)': '\x1b[?1000h', '1000 (VT200: press, release, wheel)': '\x1b[?1000h',
// '1001 (VT200 highlight)': '\x1b[?1001h', // handle of backreport not implemented // '1001 (VT200 highlight)': '\x1b[?1001h', // handle of backreport - not implemented
'1002 (press, release, move on pressed, wheel)': '\x1b[?1002h', '1002 (press, release, move on pressed, wheel)': '\x1b[?1002h',
'1003 (press, relase, move, wheel)': '\x1b[?1003h' '1003 (press, relase, move, wheel)': '\x1b[?1003h'
} }
@@ -96,8 +119,8 @@ const ENC = {
// format: CSI M <button + 32> <row + 32> <col + 32> // format: CSI M <button + 32> <row + 32> <col + 32>
report => ({ report => ({
state: evalButtonCode(report[3] - 32), state: evalButtonCode(report[3] - 32),
row: report[4] - 32, col: report[4] - 32,
col: report[5] - 32 row: report[5] - 32
}) })
], ],
'UTF8' : [ 'UTF8' : [
@@ -108,8 +131,8 @@ const ENC = {
const sReport = report.toString(); // decode with utf8 const sReport = report.toString(); // decode with utf8
return { return {
state: evalButtonCode(sReport.charCodeAt(3) - 32), state: evalButtonCode(sReport.charCodeAt(3) - 32),
row: sReport.charCodeAt(4) - 32, col: sReport.charCodeAt(4) - 32,
col: sReport.charCodeAt(5) - 32 row: sReport.charCodeAt(5) - 32
}; };
} }
], ],
@@ -119,7 +142,7 @@ const ENC = {
report => { report => {
// strip off introducer + M // strip off introducer + M
const sReport = report.toString().slice(3, -1); const sReport = report.toString().slice(3, -1);
const [buttonCode, row, col] = sReport.split(';'); const [buttonCode, col, row] = sReport.split(';');
const state = evalButtonCode(buttonCode); const state = evalButtonCode(buttonCode);
if (report[report.length - 1] === 'm'.charCodeAt(0)) { if (report[report.length - 1] === 'm'.charCodeAt(0)) {
state.action = 'release'; state.action = 'release';
@@ -133,7 +156,7 @@ const ENC = {
report => { report => {
// strip off introducer + M // strip off introducer + M
const sReport = report.toString().slice(2, -1); const sReport = report.toString().slice(2, -1);
const [button, row, col] = sReport.split(';'); const [button, col, row] = sReport.split(';');
return {state: evalButtonCode(button - 32), row, col}; return {state: evalButtonCode(button - 32), row, col};
} }
] ]
@@ -182,7 +205,7 @@ function applyReportData(data) {
let {state, row, col} = ENC[Object.keys(ENC)[activeEnc]][1](data); let {state, row, col} = ENC[Object.keys(ENC)[activeEnc]][1](data);
console.log('\x1b[2KButton:', state.button, 'Action:', state.action, 'Modifier:', state.modifier, 'row:', row, 'col:', col); console.log('\x1b[2KButton:', state.button, 'Action:', state.action, 'Modifier:', state.modifier, 'row:', row, 'col:', col);
// apply to cursor position // apply to cursor position
process.stdout.write(`\x1b[${col};${row}H`); process.stdout.write(`\x1b[${row};${col}H`);
} }
printMenu(); printMenu();
+23 -11
View File
@@ -710,7 +710,21 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
} }
} }
// TODO: Move mouse event code into its own file. /**
* Bind certain mouse events to the terminal.
* By default only 3 button + wheel up/down is ativated. For higher buttons
* no mouse report will be created. Typically the standard actions will be active.
*
* There are several reasons not to enable support for higher buttons/wheel:
* - Button 4 and 5 are typically used for history back and forward navigation,
* there is no straight forward way to supress/intercept those standard actions.
* - Support for higher buttons does not work in some platform/browser combinations.
* - Left/right wheel was not tested.
* - Emulators vary in mouse button support, typically only 3 buttons and
* wheel up/down work reliable.
*
* TODO: Move mouse event code into its own file.
*/
public bindMouse(): void { public bindMouse(): void {
const self = this; const self = this;
const el = this.element; const el = this.element;
@@ -734,9 +748,10 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
// buttons is not supported on macOS, try to get a value from button instead // buttons is not supported on macOS, try to get a value from button instead
but = CoreMouseButton.NONE; but = CoreMouseButton.NONE;
if (ev.button !== undefined) { if (ev.button !== undefined) {
but = ev.button < 3 ? ev.button : undefined; but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;
} }
} else { } else {
// according to MDN buttons only reports up to button 5 (AUX2)
but = ev.buttons & 1 ? CoreMouseButton.LEFT : but = ev.buttons & 1 ? CoreMouseButton.LEFT :
ev.buttons & 4 ? CoreMouseButton.MIDDLE : ev.buttons & 4 ? CoreMouseButton.MIDDLE :
ev.buttons & 2 ? CoreMouseButton.RIGHT : ev.buttons & 2 ? CoreMouseButton.RIGHT :
@@ -745,20 +760,16 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
break; break;
case 'mouseup': case 'mouseup':
action = CoreMouseAction.UP; action = CoreMouseAction.UP;
// AUX buttons are currently not supported but = ev.button < 3 ? ev.button : ev.button + 5;
but = ev.button < 3 ? ev.button : undefined;
break; break;
case 'mousedown': case 'mousedown':
action = CoreMouseAction.DOWN; action = CoreMouseAction.DOWN;
but = ev.button < 3 ? ev.button : undefined; but = ev.button < 3 ? ev.button : ev.button + 5;
break; break;
case 'wheel': case 'wheel':
// precedence: up/down over left/right // only UP/DOWN wheel events are respected
// FIXME: Can we have both in one event? Need to send another wheel event?
if ((ev as WheelEvent).deltaY !== 0) { if ((ev as WheelEvent).deltaY !== 0) {
action = (ev as WheelEvent).deltaY < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN; 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; but = CoreMouseButton.WHEEL;
break; break;
@@ -767,8 +778,9 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
return false; return false;
} }
// exit if we cannot determine button/action values // exit if we cannot determine valid button/action values
if (action === undefined || but === undefined) { // do nothing for higher buttons than wheel
if (action === undefined || but === undefined || but > CoreMouseButton.WHEEL) {
return false; return false;
} }