@xterm/xterm 6.1.0-beta.186 → 6.1.0-beta.187

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xterm/xterm",
3
3
  "description": "Full xterm terminal, in your browser",
4
- "version": "6.1.0-beta.186",
4
+ "version": "6.1.0-beta.187",
5
5
  "main": "lib/xterm.js",
6
6
  "module": "lib/xterm.mjs",
7
7
  "style": "css/xterm.css",
@@ -119,5 +119,5 @@
119
119
  "ws": "^8.2.3",
120
120
  "xterm-benchmark": "^0.3.1"
121
121
  },
122
- "commit": "b0118dfd3a3e07c6e48336b7af4ca209d51488ab"
122
+ "commit": "af6731b5337e33724a2c6f4dff47015362138b09"
123
123
  }
@@ -653,7 +653,8 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
653
653
  this._mouseService.bindMouse({
654
654
  element: this.element!,
655
655
  screenElement: this.screenElement!,
656
- document: this._document!
656
+ document: this._document!,
657
+ handleTouchScroll: amount => this._viewport?.handleTouchScroll(amount)
657
658
  }, disposable => this._register(disposable), () => this.focus());
658
659
  }
659
660
 
@@ -8,12 +8,11 @@ import { ViewportConstants } from 'browser/shared/Constants';
8
8
  import { Disposable, toDisposable } from 'common/Lifecycle';
9
9
  import { IBufferService, IMouseStateService, IOptionsService } from 'common/services/Services';
10
10
  import { CoreMouseEventType } from 'common/Types';
11
- import { addDisposableListener, scheduleAtNextAnimationFrame } from 'browser/Dom';
11
+ import { scheduleAtNextAnimationFrame } from 'browser/Dom';
12
12
  import { SmoothScrollableElement } from 'browser/scrollable/scrollableElement';
13
13
  import type { IScrollableElementChangeOptions } from 'browser/scrollable/scrollableElementOptions';
14
14
  import { Emitter, EventUtils } from 'common/Event';
15
15
  import { Scrollable, ScrollbarVisibility, type IScrollEvent } from 'browser/scrollable/scrollable';
16
- import { Gesture, EventType as GestureEventType, type IGestureEvent } from 'browser/scrollable/touch';
17
16
 
18
17
  export class Viewport extends Disposable {
19
18
 
@@ -107,9 +106,6 @@ export class Viewport extends Disposable {
107
106
 
108
107
  this._register(this._scrollableElement.onScroll(e => this._handleScroll(e)));
109
108
 
110
- // Touch/gesture scrolling support
111
- this._register(Gesture.addTarget(screenElement));
112
- this._register(addDisposableListener(screenElement, GestureEventType.CHANGE, (e: IGestureEvent) => this._handleGestureChange(e)));
113
109
  }
114
110
 
115
111
  public scrollLines(disp: number): void {
@@ -204,12 +200,10 @@ export class Viewport extends Disposable {
204
200
  this._isHandlingScroll = false;
205
201
  }
206
202
 
207
- private _handleGestureChange(e: IGestureEvent): void {
208
- e.preventDefault();
209
- e.stopPropagation();
203
+ public handleTouchScroll(translationY: number): void {
210
204
  const pos = this._scrollableElement.getScrollPosition();
211
205
  this._scrollableElement.setScrollPosition({
212
- scrollTop: pos.scrollTop - e.translationY
206
+ scrollTop: pos.scrollTop - translationY
213
207
  });
214
208
  }
215
209
  }
@@ -153,6 +153,8 @@ export interface IGestureEvent extends MouseEvent {
153
153
  translationY: number;
154
154
  pageX: number;
155
155
  pageY: number;
156
+ clientX: number;
157
+ clientY: number;
156
158
  tapCount: number;
157
159
  }
158
160
 
@@ -459,6 +461,8 @@ export class Gesture extends Disposable {
459
461
  evt.translationY = touch.pageY - tail(data.rollingPageY)!;
460
462
  evt.pageX = touch.pageX;
461
463
  evt.pageY = touch.pageY;
464
+ evt.clientX = touch.clientX;
465
+ evt.clientY = touch.clientY;
462
466
  this._dispatchEvent(evt);
463
467
 
464
468
  if (data.rollingPageX.length > 3) {
@@ -9,6 +9,7 @@ import { CoreMouseAction, CoreMouseButton, CoreMouseEventType, ICoreMouseEvent,
9
9
  import { C0 } from 'common/data/EscapeSequences';
10
10
  import { toDisposable } from 'common/Lifecycle';
11
11
  import { ICoreBrowserService, IMouseCoordsService, IMouseService, IMouseServiceTarget, IRenderService, ISelectionService } from './Services';
12
+ import { Gesture, EventType as GestureEventType, IGestureEvent } from 'browser/scrollable/touch';
12
13
 
13
14
  type RequestedMouseEvents = Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener | null>;
14
15
 
@@ -23,6 +24,7 @@ export class MouseService implements IMouseService {
23
24
 
24
25
  private _lastEvent: ICoreMouseEvent | null = null;
25
26
  private _wheelPartialScroll: number = 0;
27
+ private _touchScrollAccumulator: number = 0;
26
28
 
27
29
  constructor(
28
30
  @IRenderService private readonly _renderService: IRenderService,
@@ -82,6 +84,9 @@ export class MouseService implements IMouseService {
82
84
  */
83
85
  register(addDisposableListener(element, 'mousedown', (ev: MouseEvent) => this._handleMouseDown(ctx, ev)));
84
86
  register(addDisposableListener(element, 'wheel', (ev: WheelEvent) => this._handlePassiveWheel(ctx, ev), { passive: false }));
87
+ register(Gesture.addTarget(target.screenElement));
88
+ register(addDisposableListener(target.screenElement, GestureEventType.START, () => this._handleTouchStart()));
89
+ register(addDisposableListener(target.screenElement, GestureEventType.CHANGE, (e: IGestureEvent) => this._handleTouchChange(ctx, e)));
85
90
  }
86
91
 
87
92
  private _sendEvent(ctx: IMouseBindContext, ev: MouseEvent | WheelEvent): boolean {
@@ -264,9 +269,88 @@ export class MouseService implements IMouseService {
264
269
  }
265
270
  }
266
271
 
272
+ private _handleTouchStart(): void {
273
+ this._touchScrollAccumulator = 0;
274
+ }
275
+
276
+ private _handleTouchChange(ctx: IMouseBindContext, e: IGestureEvent): void {
277
+ e.preventDefault();
278
+ e.stopPropagation();
279
+
280
+ // When mouse protocol has wheel events active, send as mouse wheel events.
281
+ if (ctx.requestedEvents.wheel) {
282
+ this._handleTouchScrollAsWheel(ctx, e);
283
+ return;
284
+ }
285
+
286
+ // When in alt buffer (no scrollback), send up/down key sequences.
287
+ if (!this._bufferService.buffer.hasScrollback) {
288
+ this._handleTouchScrollAsKeys(e);
289
+ return;
290
+ }
291
+
292
+ // Normal scrollback: delegate to viewport scrolling when available.
293
+ ctx.target.handleTouchScroll?.(e.translationY);
294
+ }
295
+
296
+ private _handleTouchScrollAsKeys(e: IGestureEvent): void {
297
+ const cellHeight = this._renderService?.dimensions.css.cell.height;
298
+ if (!cellHeight) {
299
+ return;
300
+ }
301
+
302
+ this._touchScrollAccumulator -= e.translationY;
303
+ const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);
304
+ if (lines === 0) {
305
+ return;
306
+ }
307
+
308
+ this._touchScrollAccumulator -= lines * cellHeight;
309
+ const sequence = C0.ESC
310
+ + (this._coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[')
311
+ + (lines < 0 ? 'A' : 'B');
312
+ for (let i = 0; i < Math.abs(lines); i++) {
313
+ this._coreService.triggerDataEvent(sequence, true);
314
+ }
315
+ }
316
+
317
+ private _handleTouchScrollAsWheel(ctx: IMouseBindContext, e: IGestureEvent): void {
318
+ const cellHeight = this._renderService?.dimensions.css.cell.height;
319
+ if (!cellHeight) {
320
+ return;
321
+ }
322
+
323
+ this._touchScrollAccumulator -= e.translationY;
324
+ const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);
325
+ if (lines === 0) {
326
+ return;
327
+ }
328
+
329
+ this._touchScrollAccumulator -= lines * cellHeight;
330
+ const pos = this._mouseCoordsService.getMouseReportCoords(e, ctx.target.screenElement);
331
+ if (!pos) {
332
+ return;
333
+ }
334
+
335
+ for (let i = 0; i < Math.abs(lines); i++) {
336
+ this._triggerMouseEvent({
337
+ col: pos.col,
338
+ row: pos.row,
339
+ x: pos.x,
340
+ y: pos.y,
341
+ button: CoreMouseButton.WHEEL,
342
+ action: lines < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN,
343
+ ctrl: false,
344
+ alt: false,
345
+ shift: false
346
+ });
347
+ }
348
+ }
349
+
267
350
  public reset(): void {
268
351
  this._lastEvent = null;
269
352
  this._wheelPartialScroll = 0;
353
+ this._touchScrollAccumulator = 0;
270
354
  }
271
355
 
272
356
  private _handleProtocolChange(ctx: IMouseBindContext, eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener>, events: CoreMouseEventType): void {
@@ -68,6 +68,7 @@ export interface IMouseServiceTarget {
68
68
  element: HTMLElement;
69
69
  screenElement: HTMLElement;
70
70
  document: Document;
71
+ handleTouchScroll?(amount: number): void;
71
72
  }
72
73
 
73
74
  export const IRenderService = createDecorator<IRenderService>('RenderService');
@@ -6,4 +6,4 @@
6
6
  /**
7
7
  * The xterm.js version. This is updated by the publish script from package.json.
8
8
  */
9
- export const XTERM_VERSION = '6.1.0-beta.186';
9
+ export const XTERM_VERSION = '6.1.0-beta.187';