mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge pull request #2310 from Tyriar/layering2
Move MouseZoneManager and Viewport into browser
This commit is contained in:
+13
-6
@@ -21,10 +21,10 @@
|
||||
* http://linux.die.net/man/7/urxvt
|
||||
*/
|
||||
|
||||
import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, CustomKeyEventHandler } from './Types';
|
||||
import { IInputHandlingTerminal, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, CustomKeyEventHandler } from './Types';
|
||||
import { IRenderer, CharacterJoinerHandler } from 'browser/renderer/Types';
|
||||
import { CompositionHelper } from 'browser/input/CompositionHelper';
|
||||
import { Viewport } from './Viewport';
|
||||
import { Viewport } from 'browser/Viewport';
|
||||
import { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from 'browser/Clipboard';
|
||||
import { C0 } from 'common/data/EscapeSequences';
|
||||
import { InputHandler } from './InputHandler';
|
||||
@@ -33,9 +33,9 @@ import { Linkifier } from 'browser/Linkifier';
|
||||
import { SelectionService } from './browser/services/SelectionService';
|
||||
import * as Browser from 'common/Platform';
|
||||
import { addDisposableDomListener } from 'browser/Lifecycle';
|
||||
import * as Strings from './browser/LocalizableStrings';
|
||||
import * as Strings from 'browser/LocalizableStrings';
|
||||
import { SoundService } from 'browser/services/SoundService';
|
||||
import { MouseZoneManager } from './MouseZoneManager';
|
||||
import { MouseZoneManager } from 'browser/MouseZoneManager';
|
||||
import { AccessibilityManager } from './AccessibilityManager';
|
||||
import { ITheme, IMarker, IDisposable, ISelectionPosition } from 'xterm';
|
||||
import { removeTerminalFromCache } from './renderer/atlas/CharAtlasCache';
|
||||
@@ -59,7 +59,7 @@ import { MouseService } from 'browser/services/MouseService';
|
||||
import { IParams } from 'common/parser/Types';
|
||||
import { CoreService } from 'common/services/CoreService';
|
||||
import { LogService } from 'common/services/LogService';
|
||||
import { ILinkifier, IMouseZoneManager, LinkMatcherHandler, ILinkMatcherOptions } from 'browser/Types';
|
||||
import { ILinkifier, IMouseZoneManager, LinkMatcherHandler, ILinkMatcherOptions, IViewport } from 'browser/Types';
|
||||
|
||||
// Let it work inside Node.js for automated testing purposes.
|
||||
const document = (typeof window !== 'undefined') ? window.document : null;
|
||||
@@ -599,7 +599,14 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
|
||||
this._soundService = new SoundService(this.optionsService);
|
||||
this._mouseService = new MouseService(this._renderService, this._charSizeService);
|
||||
|
||||
this.viewport = new Viewport(this, this._viewportElement, this._viewportScrollArea, this._renderService.dimensions, this._charSizeService);
|
||||
this.viewport = new Viewport(
|
||||
(amount: number, suppressEvent: boolean) => this.scrollLines(amount, suppressEvent),
|
||||
this._viewportElement,
|
||||
this._viewportScrollArea,
|
||||
this._bufferService,
|
||||
this._charSizeService,
|
||||
this._renderService
|
||||
);
|
||||
this.viewport.onThemeChange(this._colorManager.colors);
|
||||
this.register(this.viewport);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { IRenderer, IRenderDimensions, CharacterJoinerHandler } from 'browser/renderer/Types';
|
||||
import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBrowser, ITerminalOptions } from './Types';
|
||||
import { IInputHandlingTerminal, ICompositionHelper, ITerminal, IBrowser, ITerminalOptions } from './Types';
|
||||
import { IBuffer, IBufferStringIterator, IBufferSet } from 'common/buffer/Types';
|
||||
import { IBufferLine, ICellData, IAttributeData, ICircularList, XtermListener, ICharset } from 'common/Types';
|
||||
import { Buffer } from 'common/buffer/Buffer';
|
||||
@@ -12,7 +12,7 @@ import * as Browser from 'common/Platform';
|
||||
import { IDisposable, IMarker, IEvent, ISelectionPosition } from 'xterm';
|
||||
import { Terminal } from './Terminal';
|
||||
import { AttributeData } from 'common/buffer/AttributeData';
|
||||
import { IColorManager, IColorSet, ILinkMatcherOptions, ILinkifier } from 'browser/Types';
|
||||
import { IColorManager, IColorSet, ILinkMatcherOptions, ILinkifier, IViewport } from 'browser/Types';
|
||||
import { IOptionsService } from 'common/services/Services';
|
||||
import { EventEmitter } from 'common/EventEmitter';
|
||||
import { IParams } from 'common/parser/Types';
|
||||
|
||||
Vendored
+1
-11
@@ -6,7 +6,7 @@
|
||||
import { ITerminalOptions as IPublicTerminalOptions, IDisposable, IMarker, ISelectionPosition } from 'xterm';
|
||||
import { ICharset, IAttributeData, CharData } from 'common/Types';
|
||||
import { IEvent, IEventEmitter } from 'common/EventEmitter';
|
||||
import { IColorSet, ILinkifier, ILinkMatcherOptions } from 'browser/Types';
|
||||
import { IColorSet, ILinkifier, ILinkMatcherOptions, IViewport } from 'browser/Types';
|
||||
import { IOptionsService } from 'common/services/Services';
|
||||
import { IBuffer, IBufferSet } from 'common/buffer/Types';
|
||||
import { IParams } from 'common/parser/Types';
|
||||
@@ -68,16 +68,6 @@ export interface IInputHandlingTerminal {
|
||||
handleTitle(title: string): void;
|
||||
}
|
||||
|
||||
export interface IViewport extends IDisposable {
|
||||
scrollBarWidth: number;
|
||||
syncScrollArea(): void;
|
||||
getLinesScrolled(ev: WheelEvent): number;
|
||||
onWheel(ev: WheelEvent): void;
|
||||
onTouchStart(ev: TouchEvent): void;
|
||||
onTouchMove(ev: TouchEvent): void;
|
||||
onThemeChange(colors: IColorSet): void;
|
||||
}
|
||||
|
||||
export interface ICompositionHelper {
|
||||
compositionstart(): void;
|
||||
compositionupdate(ev: CompositionEvent): void;
|
||||
|
||||
@@ -27,10 +27,10 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
|
||||
private _mouseLeaveListener: (e: MouseEvent) => any;
|
||||
private _clickListener: (e: MouseEvent) => any;
|
||||
|
||||
private _tooltipTimeout: number = null;
|
||||
private _currentZone: IMouseZone = null;
|
||||
private _lastHoverCoords: [number, number] = [null, null];
|
||||
private _initialSelectionLength: number;
|
||||
private _tooltipTimeout: number | undefined;
|
||||
private _currentZone: IMouseZone | undefined;
|
||||
private _lastHoverCoords: [number | undefined, number | undefined] = [undefined, undefined];
|
||||
private _initialSelectionLength: number = 0;
|
||||
|
||||
constructor(
|
||||
private readonly _element: HTMLElement,
|
||||
@@ -68,7 +68,7 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
|
||||
}
|
||||
|
||||
// Clear all if start/end weren't set
|
||||
if (!end) {
|
||||
if (!start || !end) {
|
||||
start = 0;
|
||||
end = this._bufferService.rows - 1;
|
||||
}
|
||||
@@ -81,7 +81,7 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
|
||||
(zone.y1 < start && zone.y2 > end + 1)) {
|
||||
if (this._currentZone && this._currentZone === zone) {
|
||||
this._currentZone.leaveCallback();
|
||||
this._currentZone = null;
|
||||
this._currentZone = undefined;
|
||||
}
|
||||
this._zones.splice(i--, 1);
|
||||
}
|
||||
@@ -133,7 +133,7 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
|
||||
// is being hovered
|
||||
if (this._currentZone) {
|
||||
this._currentZone.leaveCallback();
|
||||
this._currentZone = null;
|
||||
this._currentZone = undefined;
|
||||
if (this._tooltipTimeout) {
|
||||
clearTimeout(this._tooltipTimeout);
|
||||
}
|
||||
@@ -155,7 +155,7 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
|
||||
}
|
||||
|
||||
private _onTooltip(e: MouseEvent): void {
|
||||
this._tooltipTimeout = null;
|
||||
this._tooltipTimeout = undefined;
|
||||
const zone = this._findZoneEventAt(e);
|
||||
if (zone && zone.tooltipCallback) {
|
||||
zone.tooltipCallback(e);
|
||||
@@ -188,7 +188,7 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
|
||||
// leaves the terminal element
|
||||
if (this._currentZone) {
|
||||
this._currentZone.leaveCallback();
|
||||
this._currentZone = null;
|
||||
this._currentZone = undefined;
|
||||
if (this._tooltipTimeout) {
|
||||
clearTimeout(this._tooltipTimeout);
|
||||
}
|
||||
@@ -213,10 +213,10 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
|
||||
return selectionText ? selectionText.length : 0;
|
||||
}
|
||||
|
||||
private _findZoneEventAt(e: MouseEvent): IMouseZone {
|
||||
private _findZoneEventAt(e: MouseEvent): IMouseZone | undefined {
|
||||
const coords = this._mouseService.getCoords(e, this._screenElement, this._bufferService.cols, this._bufferService.rows);
|
||||
if (!coords) {
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
const x = coords[0];
|
||||
const y = coords[1];
|
||||
@@ -236,6 +236,6 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
Vendored
+10
@@ -24,6 +24,16 @@ export interface IColorSet {
|
||||
ansi: IColor[];
|
||||
}
|
||||
|
||||
export interface IViewport extends IDisposable {
|
||||
scrollBarWidth: number;
|
||||
syncScrollArea(): void;
|
||||
getLinesScrolled(ev: WheelEvent): number;
|
||||
onWheel(ev: WheelEvent): void;
|
||||
onTouchStart(ev: TouchEvent): void;
|
||||
onTouchMove(ev: TouchEvent): void;
|
||||
onThemeChange(colors: IColorSet): void;
|
||||
}
|
||||
|
||||
export type LinkMatcherHandler = (event: MouseEvent, uri: string) => void;
|
||||
export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void;
|
||||
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ITerminal, IViewport } from './Types';
|
||||
import { Disposable } from 'common/Lifecycle';
|
||||
import { addDisposableDomListener } from 'browser/Lifecycle';
|
||||
import { IColorSet } from 'browser/Types';
|
||||
import { IRenderDimensions } from 'browser/renderer/Types';
|
||||
import { ICharSizeService } from 'browser/services/Services';
|
||||
import { IColorSet, IViewport } from 'browser/Types';
|
||||
import { ICharSizeService, IRenderService } from 'browser/services/Services';
|
||||
import { IBufferService } from 'common/services/Services';
|
||||
|
||||
const FALLBACK_SCROLL_BAR_WIDTH = 15;
|
||||
|
||||
@@ -22,7 +21,7 @@ export class Viewport extends Disposable implements IViewport {
|
||||
private _lastRecordedBufferLength: number = 0;
|
||||
private _lastRecordedViewportHeight: number = 0;
|
||||
private _lastRecordedBufferHeight: number = 0;
|
||||
private _lastTouchY: number;
|
||||
private _lastTouchY: number = 0;
|
||||
private _lastScrollTop: number = 0;
|
||||
|
||||
// Stores a partial line amount when scrolling, this is used to keep track of how much of a line
|
||||
@@ -34,11 +33,12 @@ export class Viewport extends Disposable implements IViewport {
|
||||
private _ignoreNextScrollEvent: boolean = false;
|
||||
|
||||
constructor(
|
||||
private _terminal: ITerminal,
|
||||
private _viewportElement: HTMLElement,
|
||||
private _scrollArea: HTMLElement,
|
||||
private _dimensions: IRenderDimensions,
|
||||
private _charSizeService: ICharSizeService
|
||||
private readonly _scrollLines: (amount: number, suppressEvent: boolean) => void,
|
||||
private readonly _viewportElement: HTMLElement,
|
||||
private readonly _scrollArea: HTMLElement,
|
||||
private readonly _bufferService: IBufferService,
|
||||
private readonly _charSizeService: ICharSizeService,
|
||||
private readonly _renderService: IRenderService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -52,10 +52,6 @@ export class Viewport extends Disposable implements IViewport {
|
||||
setTimeout(() => this.syncScrollArea(), 0);
|
||||
}
|
||||
|
||||
public onDimensionsChance(dimensions: IRenderDimensions): void {
|
||||
this._dimensions = dimensions;
|
||||
}
|
||||
|
||||
public onThemeChange(colors: IColorSet): void {
|
||||
this._viewportElement.style.backgroundColor = colors.background.css;
|
||||
}
|
||||
@@ -72,9 +68,9 @@ export class Viewport extends Disposable implements IViewport {
|
||||
|
||||
private _innerRefresh(): void {
|
||||
if (this._charSizeService.height > 0) {
|
||||
this._currentRowHeight = this._dimensions.scaledCellHeight / window.devicePixelRatio;
|
||||
this._currentRowHeight = this._renderService.dimensions.scaledCellHeight / window.devicePixelRatio;
|
||||
this._lastRecordedViewportHeight = this._viewportElement.offsetHeight;
|
||||
const newBufferHeight = Math.round(this._currentRowHeight * this._lastRecordedBufferLength) + (this._lastRecordedViewportHeight - this._dimensions.canvasHeight);
|
||||
const newBufferHeight = Math.round(this._currentRowHeight * this._lastRecordedBufferLength) + (this._lastRecordedViewportHeight - this._renderService.dimensions.canvasHeight);
|
||||
if (this._lastRecordedBufferHeight !== newBufferHeight) {
|
||||
this._lastRecordedBufferHeight = newBufferHeight;
|
||||
this._scrollArea.style.height = this._lastRecordedBufferHeight + 'px';
|
||||
@@ -82,7 +78,7 @@ export class Viewport extends Disposable implements IViewport {
|
||||
}
|
||||
|
||||
// Sync scrollTop
|
||||
const scrollTop = this._terminal.buffer.ydisp * this._currentRowHeight;
|
||||
const scrollTop = this._bufferService.buffer.ydisp * this._currentRowHeight;
|
||||
if (this._viewportElement.scrollTop !== scrollTop) {
|
||||
// Ignore the next scroll event which will be triggered by setting the scrollTop as we do not
|
||||
// want this event to scroll the terminal
|
||||
@@ -98,20 +94,20 @@ export class Viewport extends Disposable implements IViewport {
|
||||
*/
|
||||
public syncScrollArea(): void {
|
||||
// If buffer height changed
|
||||
if (this._lastRecordedBufferLength !== this._terminal.buffer.lines.length) {
|
||||
this._lastRecordedBufferLength = this._terminal.buffer.lines.length;
|
||||
if (this._lastRecordedBufferLength !== this._bufferService.buffer.lines.length) {
|
||||
this._lastRecordedBufferLength = this._bufferService.buffer.lines.length;
|
||||
this._refresh();
|
||||
return;
|
||||
}
|
||||
|
||||
// If viewport height changed
|
||||
if (this._lastRecordedViewportHeight !== this._dimensions.canvasHeight) {
|
||||
if (this._lastRecordedViewportHeight !== this._renderService.dimensions.canvasHeight) {
|
||||
this._refresh();
|
||||
return;
|
||||
}
|
||||
|
||||
// If the buffer position doesn't match last scroll top
|
||||
const newScrollTop = this._terminal.buffer.ydisp * this._currentRowHeight;
|
||||
const newScrollTop = this._bufferService.buffer.ydisp * this._currentRowHeight;
|
||||
if (this._lastScrollTop !== newScrollTop) {
|
||||
this._refresh();
|
||||
return;
|
||||
@@ -124,7 +120,7 @@ export class Viewport extends Disposable implements IViewport {
|
||||
}
|
||||
|
||||
// If row height changed
|
||||
if (this._dimensions.scaledCellHeight / window.devicePixelRatio !== this._currentRowHeight) {
|
||||
if (this._renderService.dimensions.scaledCellHeight / window.devicePixelRatio !== this._currentRowHeight) {
|
||||
this._refresh();
|
||||
return;
|
||||
}
|
||||
@@ -152,8 +148,8 @@ export class Viewport extends Disposable implements IViewport {
|
||||
}
|
||||
|
||||
const newRow = Math.round(this._lastScrollTop / this._currentRowHeight);
|
||||
const diff = newRow - this._terminal.buffer.ydisp;
|
||||
this._terminal.scrollLines(diff, true);
|
||||
const diff = newRow - this._bufferService.buffer.ydisp;
|
||||
this._scrollLines(diff, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,7 +179,7 @@ export class Viewport extends Disposable implements IViewport {
|
||||
if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {
|
||||
amount *= this._currentRowHeight;
|
||||
} else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
|
||||
amount *= this._currentRowHeight * this._terminal.rows;
|
||||
amount *= this._currentRowHeight * this._bufferService.rows;
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
@@ -207,7 +203,7 @@ export class Viewport extends Disposable implements IViewport {
|
||||
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;
|
||||
amount *= this._bufferService.rows;
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
Reference in New Issue
Block a user