diff --git a/src/Parser.ts b/src/Parser.ts index 92ff1595..5938e2ea 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -472,7 +472,7 @@ export class Parser { if (ch === C0.ESC || ch === C0.BEL) { if (ch === C0.ESC) this._position++; let pt; - let valid; + let valid: boolean; switch (this._terminal.prefix) { // User-Defined Keys (DECUDK). diff --git a/src/utils/Mouse.ts b/src/utils/Mouse.ts index 7b18d41e..a9efdf93 100644 --- a/src/utils/Mouse.ts +++ b/src/utils/Mouse.ts @@ -4,8 +4,16 @@ import { CharMeasure } from './CharMeasure'; +/** + * Gets coordinates within the terminal for a particular mouse event. The result + * is returned as an array in the form [x, y] instead of an object as it's a + * little faster and this function is used in some low level code. + * @param event The mouse event. + * @param rowContainer The terminal's row container. + * @param charMeasure The char measure object used to determine character sizes. + */ export function getCoords(event: MouseEvent, rowContainer: HTMLElement, charMeasure: CharMeasure): [number, number] { - // ignore browsers without pageX for now + // Ignore browsers that don't support MouseEvent.pageX if (event.pageX == null) { return null; } @@ -14,17 +22,43 @@ export function getCoords(event: MouseEvent, rowContainer: HTMLElement, charMeas let y = event.pageY; let el = rowContainer; - // should probably check offsetParent - // but this is more portable + // Converts the coordinates from being relative to the document to being + // relative to the terminal. while (el && el !== self.document.documentElement) { x -= el.offsetLeft; y -= el.offsetTop; el = 'offsetParent' in el ? el.offsetParent : el.parentElement; } - // convert to cols/rows + // Convert to cols/rows x = Math.ceil(x / charMeasure.width); y = Math.ceil(y / charMeasure.height); return [x, y]; } + +/** + * Gets coordinates within the terminal for a particular mouse event, wrapping + * them to the bounds of the terminal and adding 32 to both the x and y values + * as expected by xterm. + * @param event The mouse event. + * @param rowContainer The terminal's row container. + * @param charMeasure The char measure object used to determine character sizes. + * @param colCount The number of columns in the terminal. + * @param rowCount The number of rows in the terminal. + */ +export function getRawByteCoords(event: MouseEvent, rowContainer: HTMLElement, charMeasure: CharMeasure, colCount: number, rowCount: number): { x: number, y: number } { + const coords = getCoords(event, rowContainer, charMeasure); + let x = coords[0]; + let y = coords[1]; + + // Ensure coordinates are within the terminal viewport. + x = Math.min(Math.max(x, 0), colCount); + y = Math.min(Math.max(y, 0), rowCount); + + // xterm sends raw bytes and starts at 32 (SP) for each. + x += 32; + y += 32; + + return { x, y }; +} diff --git a/src/xterm.js b/src/xterm.js index 8d8bffb8..f16c7ea0 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -25,6 +25,7 @@ import { CharMeasure } from './utils/CharMeasure'; import * as Browser from './utils/Browser'; import * as Mouse from './utils/Mouse'; import { CHARSETS } from './Charsets'; +import { getRawByteCoords } from './utils/Mouse'; /** * Terminal Emulation References: @@ -801,19 +802,9 @@ Terminal.prototype.bindMouse = function() { button = getButton(ev); // get mouse coordinates - pos = Mouse.getCoords(ev, self.rowContainer, self.charMeasure); + pos = getRawByteCoords(ev, self.rowContainer, self.charMeasure, self.cols, self.rows); if (!pos) return; - // Temp fix until getcoords PR is pushed - pos.x = pos[0]; - pos.y = pos[1]; - if (pos.x < 0) pos.x = 0; - if (pos.x > self.cols) pos.x = self.cols; - if (pos.y < 0) pos.y = 0; - if (pos.y > self.rows) pos.y = self.rows; - pos.x += 32; - pos.y += 32; - sendEvent(button, pos); switch (ev.overrideType || ev.type) { @@ -839,19 +830,9 @@ Terminal.prototype.bindMouse = function() { var button = pressed , pos; - pos = Mouse.getCoords(ev, self.rowContainer, self.charMeasure); + pos = getRawByteCoords(ev, self.rowContainer, self.charMeasure, self.cols, self.rows); if (!pos) return; - // Temp fix until getcoords PR is pushed - pos.x = pos[0]; - pos.y = pos[1]; - if (pos.x < 0) pos.x = 0; - if (pos.x > self.cols) pos.x = self.cols; - if (pos.y < 0) pos.y = 0; - if (pos.y > self.rows) pos.y = self.rows; - pos.x += 32; - pos.y += 32; - // buttons marked as motions // are incremented by 32 button += 32; @@ -1024,50 +1005,6 @@ Terminal.prototype.bindMouse = function() { return button; } - // mouse coordinates measured in cols/rows - // function getCoords(ev) { - // var x, y, w, h, el; - - // // ignore browsers without pageX for now - // if (ev.pageX == null) return; - - // x = ev.pageX; - // y = ev.pageY; - // el = self.rowContainer; - - // // should probably check offsetParent - // // but this is more portable - // while (el && el !== self.document.documentElement) { - // x -= el.offsetLeft; - // y -= el.offsetTop; - // el = 'offsetParent' in el - // ? el.offsetParent - // : el.parentNode; - // } - - // // convert to cols/rows - // x = Math.ceil(x / self.charMeasure.width); - // y = Math.ceil(y / self.charMeasure.height); - - // // be sure to avoid sending - // // bad positions to the program - // if (x < 0) x = 0; - // if (x > self.cols) x = self.cols; - // if (y < 0) y = 0; - // if (y > self.rows) y = self.rows; - - // // xterm sends raw bytes and - // // starts at 32 (SP) for each. - // x += 32; - // y += 32; - - // return { - // x: x, - // y: y, - // type: 'wheel' - // }; - // } - on(el, 'mousedown', function(ev) { if (!self.mouseEvents) return;