From 4d32826891548d5c8f18b07bdb6d821b327e87f0 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 21 May 2017 11:50:01 -0700 Subject: [PATCH 1/3] Pull getCoords into a Mouse util module This is part of the work to prepare for the upcoing selection changes Related #207 --- src/utils/Mouse.ts | 49 ++++++++++++++++++++++++++++++++++++++++++++++ src/xterm.js | 49 +++------------------------------------------- 2 files changed, 52 insertions(+), 46 deletions(-) create mode 100644 src/utils/Mouse.ts diff --git a/src/utils/Mouse.ts b/src/utils/Mouse.ts new file mode 100644 index 0000000000..b5faa167f2 --- /dev/null +++ b/src/utils/Mouse.ts @@ -0,0 +1,49 @@ +/** + * @license MIT + */ + +import { CharMeasure } from './CharMeasure'; + +export function getCoords(event: MouseEvent, rowContainer: HTMLElement, charMeasure: CharMeasure): [number, number] { + // ignore browsers without pageX for now + if (event.pageX == null) { + return null; + } + + let x = event.pageX; + let y = event.pageY; + let el = 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.parentElement; + } + + // convert to cols/rows + x = Math.ceil(x / charMeasure.width); + y = Math.ceil(y / charMeasure.height); + + return [x, y]; +} + +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]; + + // be sure to avoid sending bad positions to the program + if (x < 0) x = 0; + if (x > colCount) x = colCount; + if (y < 0) y = 0; + if (y > rowCount) y = 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 c632eb705f..f92a25f7b6 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -24,6 +24,7 @@ import { CharMeasure } from './utils/CharMeasure'; import * as Browser from './utils/Browser'; import * as Keyboard from './utils/Keyboard'; import { CHARSETS } from './Charsets'; +import { getRawByteCoords } from './utils/Mouse'; /** * Terminal Emulation References: @@ -789,7 +790,7 @@ Terminal.prototype.bindMouse = function() { button = getButton(ev); // get mouse coordinates - pos = getCoords(ev); + pos = getRawByteCoords(ev, self.rowContainer, self.charMeasure, self.cols, self.rows); if (!pos) return; sendEvent(button, pos); @@ -817,7 +818,7 @@ Terminal.prototype.bindMouse = function() { var button = pressed , pos; - pos = getCoords(ev); + pos = getRawByteCoords(ev, self.rowContainer, self.charMeasure, self.cols, self.rows); if (!pos) return; // buttons marked as motions @@ -992,50 +993,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.element; - - // 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; From c323e0ad4a4bf5b83c27cf3270ab4a65def99b83 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 21 May 2017 11:57:24 -0700 Subject: [PATCH 2/3] jsdoc --- src/utils/Mouse.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/utils/Mouse.ts b/src/utils/Mouse.ts index b5faa167f2..ce852ace4f 100644 --- a/src/utils/Mouse.ts +++ b/src/utils/Mouse.ts @@ -4,6 +4,14 @@ 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 if (event.pageX == null) { @@ -29,6 +37,16 @@ export function getCoords(event: MouseEvent, rowContainer: HTMLElement, charMeas 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]; From 70e35de56b6bd7256ff9982e3fd6cb79d0063c1e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 21 May 2017 12:03:44 -0700 Subject: [PATCH 3/3] Polish comments and cap code --- src/utils/Mouse.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/utils/Mouse.ts b/src/utils/Mouse.ts index ce852ace4f..a9efdf9342 100644 --- a/src/utils/Mouse.ts +++ b/src/utils/Mouse.ts @@ -13,7 +13,7 @@ import { CharMeasure } from './CharMeasure'; * @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; } @@ -22,15 +22,15 @@ 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); @@ -52,14 +52,11 @@ export function getRawByteCoords(event: MouseEvent, rowContainer: HTMLElement, c let x = coords[0]; let y = coords[1]; - // be sure to avoid sending bad positions to the program - if (x < 0) x = 0; - if (x > colCount) x = colCount; - if (y < 0) y = 0; - if (y > rowCount) y = rowCount; + // 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. + // xterm sends raw bytes and starts at 32 (SP) for each. x += 32; y += 32;