From 8b53b8c2559ce976726152c8a7d043f024935529 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 23 May 2022 06:49:52 -0700 Subject: [PATCH 1/2] Take padding into account when converting mouse coord to cell Part of microsoft/vscode#148061 --- src/browser/input/Mouse.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/browser/input/Mouse.ts b/src/browser/input/Mouse.ts index 2986fb3c..31a6af0a 100644 --- a/src/browser/input/Mouse.ts +++ b/src/browser/input/Mouse.ts @@ -5,7 +5,13 @@ export function getCoordsRelativeToElement(event: {clientX: number, clientY: number}, element: HTMLElement): [number, number] { const rect = element.getBoundingClientRect(); - return [event.clientX - rect.left, event.clientY - rect.top]; + const elementStyle = window.getComputedStyle(element); + const leftPadding = parseInt(elementStyle.getPropertyValue('padding-left')); + const topPadding = parseInt(elementStyle.getPropertyValue('padding-top')); + return [ + event.clientX - rect.left - leftPadding, + event.clientY - rect.top - topPadding + ]; } /** From ca083f257cd1136746c382996dbc77280b48c5e8 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 23 May 2022 07:15:18 -0700 Subject: [PATCH 2/2] Pass window in to fix tests --- src/browser/input/Mouse.test.ts | 20 ++++++++++++++------ src/browser/input/Mouse.ts | 6 +++--- src/browser/services/MouseService.ts | 1 + src/browser/services/SelectionService.ts | 2 +- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/browser/input/Mouse.test.ts b/src/browser/input/Mouse.test.ts index 6a908499..00260361 100644 --- a/src/browser/input/Mouse.test.ts +++ b/src/browser/input/Mouse.test.ts @@ -11,30 +11,38 @@ const CHAR_WIDTH = 10; const CHAR_HEIGHT = 20; describe('Mouse getCoords', () => { + let windowOverride: Pick; let document: Document; beforeEach(() => { + windowOverride = { + getComputedStyle(): any { + return { + getPropertyValue: () => '0px' + } as Pick; + } + }; document = new jsdom.JSDOM('').window.document; }); it('should return the cell that was clicked', () => { let coords: [number, number] | undefined; - coords = getCoords({ clientX: CHAR_WIDTH / 2, clientY: CHAR_HEIGHT / 2 }, document.createElement('div'), 10, 10, true, CHAR_WIDTH, CHAR_HEIGHT); + coords = getCoords(windowOverride, { clientX: CHAR_WIDTH / 2, clientY: CHAR_HEIGHT / 2 }, document.createElement('div'), 10, 10, true, CHAR_WIDTH, CHAR_HEIGHT); assert.deepEqual(coords, [1, 1]); - coords = getCoords({ clientX: CHAR_WIDTH, clientY: CHAR_HEIGHT }, document.createElement('div'), 10, 10, true, CHAR_WIDTH, CHAR_HEIGHT); + coords = getCoords(windowOverride, { clientX: CHAR_WIDTH, clientY: CHAR_HEIGHT }, document.createElement('div'), 10, 10, true, CHAR_WIDTH, CHAR_HEIGHT); assert.deepEqual(coords, [1, 1]); - coords = getCoords({ clientX: CHAR_WIDTH, clientY: CHAR_HEIGHT + 1 }, document.createElement('div'), 10, 10, true, CHAR_WIDTH, CHAR_HEIGHT); + coords = getCoords(windowOverride, { clientX: CHAR_WIDTH, clientY: CHAR_HEIGHT + 1 }, document.createElement('div'), 10, 10, true, CHAR_WIDTH, CHAR_HEIGHT); assert.deepEqual(coords, [1, 2]); - coords = getCoords({ clientX: CHAR_WIDTH + 1, clientY: CHAR_HEIGHT }, document.createElement('div'), 10, 10, true, CHAR_WIDTH, CHAR_HEIGHT); + coords = getCoords(windowOverride, { clientX: CHAR_WIDTH + 1, clientY: CHAR_HEIGHT }, document.createElement('div'), 10, 10, true, CHAR_WIDTH, CHAR_HEIGHT); assert.deepEqual(coords, [2, 1]); }); it('should ensure the coordinates are returned within the terminal bounds', () => { let coords: [number, number] | undefined; - coords = getCoords({ clientX: -1, clientY: -1 }, document.createElement('div'), 10, 10, true, CHAR_WIDTH, CHAR_HEIGHT); + coords = getCoords(windowOverride, { clientX: -1, clientY: -1 }, document.createElement('div'), 10, 10, true, CHAR_WIDTH, CHAR_HEIGHT); assert.deepEqual(coords, [1, 1]); // Event are double the cols/rows - coords = getCoords({ clientX: CHAR_WIDTH * 20, clientY: CHAR_HEIGHT * 20 }, document.createElement('div'), 10, 10, true, CHAR_WIDTH, CHAR_HEIGHT); + coords = getCoords(windowOverride, { clientX: CHAR_WIDTH * 20, clientY: CHAR_HEIGHT * 20 }, document.createElement('div'), 10, 10, true, CHAR_WIDTH, CHAR_HEIGHT); assert.deepEqual(coords, [10, 10], 'coordinates should never come back as larger than the terminal'); }); }); diff --git a/src/browser/input/Mouse.ts b/src/browser/input/Mouse.ts index 31a6af0a..6c377edb 100644 --- a/src/browser/input/Mouse.ts +++ b/src/browser/input/Mouse.ts @@ -3,7 +3,7 @@ * @license MIT */ -export function getCoordsRelativeToElement(event: {clientX: number, clientY: number}, element: HTMLElement): [number, number] { +export function getCoordsRelativeToElement(window: Pick, event: {clientX: number, clientY: number}, element: HTMLElement): [number, number] { const rect = element.getBoundingClientRect(); const elementStyle = window.getComputedStyle(element); const leftPadding = parseInt(elementStyle.getPropertyValue('padding-left')); @@ -26,13 +26,13 @@ export function getCoordsRelativeToElement(event: {clientX: number, clientY: num * apply an offset to the x value such that the left half of the cell will * select that cell and the right half will select the next cell. */ -export function getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, hasValidCharSize: boolean, actualCellWidth: number, actualCellHeight: number, isSelection?: boolean): [number, number] | undefined { +export function getCoords(window: Pick, event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, hasValidCharSize: boolean, actualCellWidth: number, actualCellHeight: number, isSelection?: boolean): [number, number] | undefined { // Coordinates cannot be measured if there are no valid if (!hasValidCharSize) { return undefined; } - const coords = getCoordsRelativeToElement(event, element); + const coords = getCoordsRelativeToElement(window, event, element); if (!coords) { return undefined; } diff --git a/src/browser/services/MouseService.ts b/src/browser/services/MouseService.ts index 348ba64e..69123ba3 100644 --- a/src/browser/services/MouseService.ts +++ b/src/browser/services/MouseService.ts @@ -17,6 +17,7 @@ export class MouseService implements IMouseService { public getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined { return getCoords( + window, event, element, colCount, diff --git a/src/browser/services/SelectionService.ts b/src/browser/services/SelectionService.ts index c7b7707a..57ba048f 100644 --- a/src/browser/services/SelectionService.ts +++ b/src/browser/services/SelectionService.ts @@ -402,7 +402,7 @@ export class SelectionService extends Disposable implements ISelectionService { * @param event The mouse event. */ private _getMouseEventScrollAmount(event: MouseEvent): number { - let offset = getCoordsRelativeToElement(event, this._screenElement)[1]; + let offset = getCoordsRelativeToElement(window, event, this._screenElement)[1]; const terminalHeight = this._renderService.dimensions.canvasHeight; if (offset >= 0 && offset <= terminalHeight) { return 0;