mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
fix pixel to cell offsets
This commit is contained in:
+27
-26
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Script to test different mouse modes in terminal emulators.
|
||||
* Tests for protocols DECSET 9, 1000, 1002, 1003 with different
|
||||
* report encodings (default, UTF8, SGR, URXVT).
|
||||
* report encodings (default, UTF8, SGR, URXVT, SGR-pixels).
|
||||
*
|
||||
* VT200 Highlight mode (DECSET 1001) is not implemented.
|
||||
*
|
||||
@@ -123,19 +123,19 @@ const ENC = {
|
||||
row: report[5] - 32
|
||||
})
|
||||
],
|
||||
// 'UTF8' : [
|
||||
// '\x1b[?1005h',
|
||||
// // format: CSI M <button + 32> <row + 32> <col + 32>
|
||||
// // + utf8 encoding on row/col
|
||||
// report => {
|
||||
// const sReport = report.toString(); // decode with utf8
|
||||
// return {
|
||||
// state: evalButtonCode(sReport.charCodeAt(3) - 32),
|
||||
// col: sReport.charCodeAt(4) - 32,
|
||||
// row: sReport.charCodeAt(5) - 32
|
||||
// };
|
||||
// }
|
||||
// ],
|
||||
'UTF8' : [
|
||||
'\x1b[?1005h',
|
||||
// format: CSI M <button + 32> <row + 32> <col + 32>
|
||||
// + utf8 encoding on row/col
|
||||
report => {
|
||||
const sReport = report.toString(); // decode with utf8
|
||||
return {
|
||||
state: evalButtonCode(sReport.charCodeAt(3) - 32),
|
||||
col: sReport.charCodeAt(4) - 32,
|
||||
row: sReport.charCodeAt(5) - 32
|
||||
};
|
||||
}
|
||||
],
|
||||
'SGR' : [
|
||||
'\x1b[?1006h',
|
||||
// format: CSI < Pbutton ; Prow ; Pcol M
|
||||
@@ -150,16 +150,16 @@ const ENC = {
|
||||
return {state, row, col};
|
||||
}
|
||||
],
|
||||
// 'URXVT': [
|
||||
// '\x1b[?1015h',
|
||||
// // format: CSI <button + 32> ; Prow ; Pcol M
|
||||
// report => {
|
||||
// // strip off introducer + M
|
||||
// const sReport = report.toString().slice(2, -1);
|
||||
// const [button, col, row] = sReport.split(';');
|
||||
// return {state: evalButtonCode(button - 32), row, col};
|
||||
// }
|
||||
// ],
|
||||
'URXVT': [
|
||||
'\x1b[?1015h',
|
||||
// format: CSI <button + 32> ; Prow ; Pcol M
|
||||
report => {
|
||||
// strip off introducer + M
|
||||
const sReport = report.toString().slice(2, -1);
|
||||
const [button, col, row] = sReport.split(';');
|
||||
return {state: evalButtonCode(button - 32), row, col};
|
||||
}
|
||||
],
|
||||
'SGR_PIXELS' : [
|
||||
'\x1b[?1016h',
|
||||
// format: CSI < Pbutton ; Prow ; Pcol M
|
||||
@@ -217,10 +217,11 @@ function activate() {
|
||||
|
||||
function applyReportData(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);
|
||||
// apply to cursor position
|
||||
if (Object.keys(ENC)[activeEnc] !== 'SGR_PIXELS') {
|
||||
console.log('\x1b[2KButton:', state.button, 'Action:', state.action, 'Modifier:', state.modifier, 'row:', row, 'col:', col);
|
||||
process.stdout.write(`\x1b[${row};${col}H`);
|
||||
} else {
|
||||
console.log('\x1b[2KButton:', state.button, 'Action:', state.action, 'Modifier:', state.modifier, 'x:', row, 'y:', col);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -645,7 +645,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
||||
// send event to CoreMouseService
|
||||
function sendEvent(ev: MouseEvent | WheelEvent): boolean {
|
||||
// get mouse coordinates
|
||||
const pos = self._mouseService!.getMouseReportCoords(ev, self.screenElement!, self.cols, self.rows);
|
||||
const pos = self._mouseService!.getMouseReportCoords(ev, self.screenElement!);
|
||||
if (!pos) {
|
||||
return false;
|
||||
}
|
||||
@@ -1322,13 +1322,13 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
||||
|
||||
switch (type) {
|
||||
case WindowsOptionsReportType.GET_WIN_SIZE_PIXELS:
|
||||
const canvasWidth = this._renderService.dimensions.scaledCanvasWidth.toFixed(0);
|
||||
const canvasHeight = this._renderService.dimensions.scaledCanvasHeight.toFixed(0);
|
||||
const canvasWidth = this._renderService.dimensions.canvasWidth.toFixed(0);
|
||||
const canvasHeight = this._renderService.dimensions.canvasHeight.toFixed(0);
|
||||
this.coreService.triggerDataEvent(`${C0.ESC}[4;${canvasHeight};${canvasWidth}t`);
|
||||
break;
|
||||
case WindowsOptionsReportType.GET_CELL_SIZE_PIXELS:
|
||||
const cellWidth = this._renderService.dimensions.scaledCellWidth.toFixed(0);
|
||||
const cellHeight = this._renderService.dimensions.scaledCellHeight.toFixed(0);
|
||||
const cellWidth = this._renderService.dimensions.actualCellWidth.toFixed(0);
|
||||
const cellHeight = this._renderService.dimensions.actualCellHeight.toFixed(0);
|
||||
this.coreService.triggerDataEvent(`${C0.ESC}[6;${cellHeight};${cellWidth}t`);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -359,7 +359,7 @@ export class MockMouseService implements IMouseService {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
public getMouseReportCoords(event: MouseEvent, element: HTMLElement, colCount: number, rowCount: number): { col: number, row: number, x: number, y: number } | undefined {
|
||||
public getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,31 +29,24 @@ export class MouseService implements IMouseService {
|
||||
);
|
||||
}
|
||||
|
||||
public getMouseReportCoords(event: MouseEvent, element: HTMLElement, colCount: number, rowCount: number): { col: number, row: number, x: number, y: number } | undefined {
|
||||
const pixelCoords = getCoordsRelativeToElement(window, event, element);
|
||||
public getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined {
|
||||
const coords = getCoordsRelativeToElement(window, event, element);
|
||||
|
||||
// due to rounding issue in zoom state pixel values might be negative at the edges
|
||||
// simply ignore the event effectively narrowing the active mouse area
|
||||
if (pixelCoords[0] < 0 || pixelCoords[1] < 0) {
|
||||
return undefined;
|
||||
}
|
||||
// also ignore if we exceed real pixel area
|
||||
if (pixelCoords[0] >= this._renderService.dimensions.canvasWidth || pixelCoords[1] >= this._renderService.dimensions.canvasHeight) {
|
||||
// due to rounding issues in zoom states pixel values might be negative or overflow actual canvas
|
||||
// ignore those events effectively narrowing mouse area a tiny bit at the edges
|
||||
if (!this._charSizeService.hasValidSize
|
||||
|| coords[0] < 0
|
||||
|| coords[1] < 0
|
||||
|| coords[0] >= this._renderService.dimensions.canvasWidth
|
||||
|| coords[1] >= this._renderService.dimensions.canvasHeight) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
pixelCoords[0] = Math.round(pixelCoords[0]);
|
||||
pixelCoords[1] = Math.round(pixelCoords[1]);
|
||||
|
||||
const cellCoords = this.getCoords(event, element, colCount, rowCount);
|
||||
if (!cellCoords) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
col: cellCoords[0] - 1,
|
||||
row: cellCoords[1] - 1,
|
||||
x: pixelCoords[0],
|
||||
y: pixelCoords[1]
|
||||
col: Math.floor(coords[0] / this._renderService.dimensions.actualCellWidth),
|
||||
row: Math.floor(coords[1] / this._renderService.dimensions.actualCellHeight),
|
||||
x: Math.floor(coords[0]),
|
||||
y: Math.floor(coords[1])
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ export interface IMouseService {
|
||||
serviceBrand: undefined;
|
||||
|
||||
getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined;
|
||||
getMouseReportCoords(event: MouseEvent, element: HTMLElement, colCount: number, rowCount: number): { col: number, row: number, x: number, y: number } | undefined;
|
||||
getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined;
|
||||
}
|
||||
|
||||
export const IRenderService = createDecorator<IRenderService>('RenderService');
|
||||
|
||||
Reference in New Issue
Block a user