Fix selection wrapping to end when not beyond viewport

This was happening as the devicePixelRatio wasn't being taken into account,
the fix was to rely on IRenderService to get the right canvas height.

Fixes #2833
This commit is contained in:
Daniel Imms
2020-04-11 06:31:58 -07:00
parent 1913e9512c
commit 714daba393
3 changed files with 85 additions and 9 deletions
+72 -1
View File
@@ -4,7 +4,9 @@
*/
import { IEvent, EventEmitter } from 'common/EventEmitter';
import { ICharSizeService, IMouseService } from 'browser/services/Services';
import { ICharSizeService, IMouseService, IRenderService } from 'browser/services/Services';
import { IRenderDimensions, IRenderer, CharacterJoinerHandler } from 'browser/renderer/Types';
import { IColorSet } from 'browser/Types';
export class MockCharSizeService implements ICharSizeService {
serviceBrand: any;
@@ -24,3 +26,72 @@ export class MockMouseService implements IMouseService {
throw new Error('Not implemented');
}
}
export class MockRenderService implements IRenderService {
serviceBrand: any;
onDimensionsChange: IEvent<IRenderDimensions> = new EventEmitter<IRenderDimensions>().event;
onRender: IEvent<{ start: number, end: number }, void> = new EventEmitter<{ start: number, end: number }>().event;
onRefreshRequest: IEvent<{ start: number, end: number}, void> = new EventEmitter<{ start: number, end: number }>().event;
dimensions: IRenderDimensions = {
scaledCharWidth: 0,
scaledCharHeight: 0,
scaledCellWidth: 0,
scaledCellHeight: 0,
scaledCharLeft: 0,
scaledCharTop: 0,
scaledCanvasWidth: 0,
scaledCanvasHeight: 0,
canvasWidth: 0,
canvasHeight: 0,
actualCellWidth: 0,
actualCellHeight: 0
};
refreshRows(start: number, end: number): void {
throw new Error('Method not implemented.');
}
resize(cols: number, rows: number): void {
throw new Error('Method not implemented.');
}
changeOptions(): void {
throw new Error('Method not implemented.');
}
setRenderer(renderer: IRenderer): void {
throw new Error('Method not implemented.');
}
setColors(colors: IColorSet): void {
throw new Error('Method not implemented.');
}
onDevicePixelRatioChange(): void {
throw new Error('Method not implemented.');
}
onResize(cols: number, rows: number): void {
throw new Error('Method not implemented.');
}
onCharSizeChanged(): void {
throw new Error('Method not implemented.');
}
onBlur(): void {
throw new Error('Method not implemented.');
}
onFocus(): void {
throw new Error('Method not implemented.');
}
onSelectionChanged(start: [number, number], end: [number, number], columnSelectMode: boolean): void {
throw new Error('Method not implemented.');
}
onCursorMove(): void {
throw new Error('Method not implemented.');
}
clear(): void {
throw new Error('Method not implemented.');
}
registerCharacterJoiner(handler: CharacterJoinerHandler): number {
throw new Error('Method not implemented.');
}
deregisterCharacterJoiner(joinerId: number): boolean {
throw new Error('Method not implemented.');
}
dispose(): void {
throw new Error('Method not implemented.');
}
}
@@ -10,16 +10,18 @@ import { IBufferLine } from 'common/Types';
import { MockBufferService, MockOptionsService, MockCoreService } from 'common/TestUtils.test';
import { BufferLine } from 'common/buffer/BufferLine';
import { IBufferService, IOptionsService } from 'common/services/Services';
import { MockCharSizeService, MockMouseService } from 'browser/TestUtils.test';
import { MockMouseService, MockRenderService } from 'browser/TestUtils.test';
import { CellData } from 'common/buffer/CellData';
import { IBuffer } from 'common/buffer/Types';
import { IRenderService } from 'browser/services/Services';
class TestSelectionService extends SelectionService {
constructor(
bufferService: IBufferService,
optionsService: IOptionsService
optionsService: IOptionsService,
renderService: IRenderService
) {
super(() => {}, null!, null!, new MockCharSizeService(10, 10), bufferService, new MockCoreService(), new MockMouseService(), optionsService);
super(() => {}, null!, null!, bufferService, new MockCoreService(), new MockMouseService(), optionsService, renderService);
}
public get model(): SelectionModel { return this._model; }
@@ -46,7 +48,10 @@ describe('SelectionService', () => {
optionsService = new MockOptionsService();
bufferService = new MockBufferService(20, 20, optionsService);
buffer = bufferService.buffer;
selectionService = new TestSelectionService(bufferService, optionsService);
const renderService = new MockRenderService();
renderService.dimensions.canvasHeight = 10 * 20;
renderService.dimensions.canvasWidth = 10 * 20;
selectionService = new TestSelectionService(bufferService, optionsService, renderService);
});
function stringToRow(text: string): IBufferLine {
+4 -4
View File
@@ -10,7 +10,7 @@ import * as Browser from 'common/Platform';
import { SelectionModel } from 'browser/selection/SelectionModel';
import { CellData } from 'common/buffer/CellData';
import { EventEmitter, IEvent } from 'common/EventEmitter';
import { ICharSizeService, IMouseService, ISelectionService } from 'browser/services/Services';
import { ICharSizeService, IMouseService, ISelectionService, IRenderService } from 'browser/services/Services';
import { IBufferService, IOptionsService, ICoreService } from 'common/services/Services';
import { getCoordsRelativeToElement } from 'browser/input/Mouse';
import { moveToCellSequence } from 'browser/input/MoveToCell';
@@ -116,11 +116,11 @@ export class SelectionService implements ISelectionService {
private readonly _scrollLines: (amount: number, suppressEvent: boolean) => void,
private readonly _element: HTMLElement,
private readonly _screenElement: HTMLElement,
@ICharSizeService private readonly _charSizeService: ICharSizeService,
@IBufferService private readonly _bufferService: IBufferService,
@ICoreService private readonly _coreService: ICoreService,
@IMouseService private readonly _mouseService: IMouseService,
@IOptionsService private readonly _optionsService: IOptionsService
@IOptionsService private readonly _optionsService: IOptionsService,
@IRenderService private readonly _renderService: IRenderService
) {
// Init listeners
this._mouseMoveListener = event => this._onMouseMove(<MouseEvent>event);
@@ -374,7 +374,7 @@ export class SelectionService implements ISelectionService {
*/
private _getMouseEventScrollAmount(event: MouseEvent): number {
let offset = getCoordsRelativeToElement(event, this._screenElement)[1];
const terminalHeight = this._bufferService.rows * Math.ceil(this._charSizeService.height * this._optionsService.options.lineHeight);
const terminalHeight = this._renderService.dimensions.canvasHeight;
if (offset >= 0 && offset <= terminalHeight) {
return 0;
}