Scroll by exact line amount in alt buffer, unify scroll logic

Fixes #1304
This commit is contained in:
Daniel Imms
2018-03-05 14:22:20 -08:00
parent be7788dda6
commit e137530581
4 changed files with 66 additions and 17 deletions
+14 -7
View File
@@ -1056,15 +1056,22 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
on(el, 'wheel', (ev: WheelEvent) => {
if (!this.mouseEvents) {
// Convert wheel events into up/down events when the buffer does not have scrollback, this
// enables scrolling in apps hosted in the alt buffer such as vim or tmux.
// enables scrolling in apps hosted in the alt buffer such as vim or tmux.
if (!this.buffer.hasScrollback) {
let sequence = C0.ESC + (this.applicationCursor ? 'O' : '[');
if (ev.wheelDeltaY > 0) {
sequence += 'A';
} else {
sequence += 'B';
const amount = this.viewport.getLinesScrolled(ev);
// Do nothing if there's no vertical scroll
if (amount === 0) {
return;
}
this.send(sequence);
// Construct and send sequences
const sequence = C0.ESC + (this.applicationCursor ? 'O' : '[') + ( ev.deltaY < 0 ? 'A' : 'B');
let data = '';
for (let i = 0; i < Math.abs(amount); i++) {
data += sequence;
}
this.send(data);
}
return;
}
+1
View File
@@ -89,6 +89,7 @@ export interface IInputHandlingTerminal extends IEventEmitter {
export interface IViewport {
scrollBarWidth: number;
syncScrollArea(): void;
getLinesScrolled(ev: WheelEvent): number;
onWheel(ev: WheelEvent): void;
onTouchStart(ev: TouchEvent): void;
onTouchMove(ev: TouchEvent): void;
+48 -10
View File
@@ -21,6 +21,11 @@ export class Viewport implements IViewport {
private lastRecordedBufferHeight: number = 0;
private lastTouchY: number;
// Stores a partial line amount when scrolling, this is used to keep track of how much of a line
// is scrolled so we can "scroll" over partial lines and feel natural on touchpads. This is a
// quick fix and could have a more robust solution in place that reset the value when needed.
private _wheelPartialScroll: number;
/**
* Creates a new Viewport.
* @param terminal The terminal this viewport belongs to.
@@ -113,22 +118,55 @@ export class Viewport implements IViewport {
* @param ev The mouse wheel event.
*/
public onWheel(ev: WheelEvent): void {
if (ev.deltaY === 0) {
// Do nothing if it's not a vertical scroll event
const amount = this._getPixelsScrolled(ev);
if (amount === 0) {
return;
}
// Fallback to WheelEvent.DOM_DELTA_PIXEL
let multiplier = 1;
if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {
multiplier = this.currentRowHeight;
} else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
multiplier = this.currentRowHeight * this.terminal.rows;
}
this.viewportElement.scrollTop += ev.deltaY * multiplier;
this.viewportElement.scrollTop += amount;
// Prevent the page from scrolling when the terminal scrolls
ev.preventDefault();
}
private _getPixelsScrolled(ev: WheelEvent): number {
// Do nothing if it's not a vertical scroll event
if (ev.deltaY === 0) {
return 0;
}
// Fallback to WheelEvent.DOM_DELTA_PIXEL
let amount = ev.deltaY;
if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {
amount *= this.currentRowHeight;
} else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
amount *= this.currentRowHeight * this.terminal.rows;
}
return amount;
}
/**
* Gets the number of pixels scrolled by the mouse event taking into account what type of delta
* is being used.
* @param ev The mouse wheel event.
*/
public getLinesScrolled(ev: WheelEvent): number {
// Do nothing if it's not a vertical scroll event
if (ev.deltaY === 0) {
return 0;
}
// Fallback to WheelEvent.DOM_DELTA_LINE
let amount = ev.deltaY;
if (ev.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {
amount /= this.currentRowHeight + 0.0; // Prevent integer division
this._wheelPartialScroll += amount;
amount = Math.floor(Math.abs(this._wheelPartialScroll)) * (this._wheelPartialScroll > 0 ? 1 : -1);
this._wheelPartialScroll %= 1;
} else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
amount *= this.terminal.rows;
}
return amount;
}
/**
* Handles the touchstart event, recording the touch occurred.
* @param ev The touch event.
+3
View File
@@ -337,6 +337,9 @@ export class MockViewport implements IViewport {
throw new Error('Method not implemented.');
}
syncScrollArea(): void { }
getLinesScrolled(ev: WheelEvent): number {
throw new Error('Method not implemented.');
}
}
export class MockCompositionHelper implements ICompositionHelper {