mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Sync textarea with cursor. Fixes #2598
This commit is contained in:
+4
-4
@@ -59,10 +59,10 @@
|
||||
}
|
||||
|
||||
.xterm .xterm-helper-textarea {
|
||||
/*
|
||||
* HACK: to fix IE's blinking cursor
|
||||
* Move textarea out of the screen to the far left, so that the cursor is not visible.
|
||||
*/
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
/* Move textarea out of the screen to the far left, so that the cursor is not visible */
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
left: -9999em;
|
||||
|
||||
@@ -78,17 +78,6 @@ export function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextA
|
||||
textarea.style.zIndex = '1000';
|
||||
|
||||
textarea.focus();
|
||||
|
||||
// Reset the terminal textarea's styling
|
||||
// Timeout needs to be long enough for click event to be handled.
|
||||
setTimeout(() => {
|
||||
textarea.style.position = '';
|
||||
textarea.style.width = '';
|
||||
textarea.style.height = '';
|
||||
textarea.style.left = '';
|
||||
textarea.style.top = '';
|
||||
textarea.style.zIndex = '';
|
||||
}, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+25
-1
@@ -281,6 +281,26 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
||||
this._onBlur.fire();
|
||||
}
|
||||
|
||||
private _syncTextArea(): void {
|
||||
if (!this.buffer.isCursorInViewport || this._compositionHelper!.isComposing) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cellHeight = Math.ceil(this._charSizeService!.height * this.optionsService.options.lineHeight);
|
||||
const cursorTop = this._bufferService.buffer.y * cellHeight;
|
||||
const cursorLeft = this._bufferService.buffer.x * this._charSizeService!.width;
|
||||
|
||||
// Sync the textarea to the exact position of the composition view so the IME knows where the
|
||||
// text is.
|
||||
this.textarea!.style.position = 'absolute';
|
||||
this.textarea!.style.left = cursorLeft + 'px';
|
||||
this.textarea!.style.top = cursorTop + 'px';
|
||||
this.textarea!.style.width = this._charSizeService!.width + 'px';
|
||||
this.textarea!.style.height = cellHeight + 'px';
|
||||
this.textarea!.style.lineHeight = cellHeight + 'px';
|
||||
this.textarea!.style.zIndex = '-5';
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize default behavior
|
||||
*/
|
||||
@@ -436,7 +456,11 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
||||
this.register(this._inputHandler.onRequestSyncScrollBar(() => this.viewport!.syncScrollArea()));
|
||||
this.register(this.viewport);
|
||||
|
||||
this.register(this.onCursorMove(() => this._renderService!.onCursorMove()));
|
||||
this.register(this.onCursorMove(() => {
|
||||
this._renderService!.onCursorMove();
|
||||
this._syncTextArea();
|
||||
|
||||
}));
|
||||
this.register(this.onResize(() => this._renderService!.onResize(this.cols, this.rows)));
|
||||
this.register(this.onBlur(() => this._renderService!.onBlur()));
|
||||
this.register(this.onFocus(() => this._renderService!.onFocus()));
|
||||
|
||||
@@ -309,6 +309,9 @@ export class MockViewport implements IViewport {
|
||||
}
|
||||
|
||||
export class MockCompositionHelper implements ICompositionHelper {
|
||||
public get isComposing(): boolean {
|
||||
return false;
|
||||
}
|
||||
public compositionstart(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -87,6 +87,7 @@ export type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;
|
||||
export type LineData = CharData[];
|
||||
|
||||
export interface ICompositionHelper {
|
||||
readonly isComposing: boolean;
|
||||
compositionstart(): void;
|
||||
compositionupdate(ev: CompositionEvent): void;
|
||||
compositionend(): void;
|
||||
|
||||
@@ -22,6 +22,7 @@ export class CompositionHelper {
|
||||
* IME. This variable determines whether the compositionText should be displayed on the UI.
|
||||
*/
|
||||
private _isComposing: boolean;
|
||||
public get isComposing(): boolean { return this._isComposing; }
|
||||
|
||||
/**
|
||||
* The position within the input textarea's value of the current composition.
|
||||
@@ -118,7 +119,6 @@ export class CompositionHelper {
|
||||
private _finalizeComposition(waitForPropagation: boolean): void {
|
||||
this._compositionView.classList.remove('active');
|
||||
this._isComposing = false;
|
||||
this._clearTextareaPosition();
|
||||
|
||||
if (!waitForPropagation) {
|
||||
// Cancel any delayed composition send requests and send the input immediately.
|
||||
@@ -207,6 +207,7 @@ export class CompositionHelper {
|
||||
// Sync the textarea to the exact position of the composition view so the IME knows where the
|
||||
// text is.
|
||||
const compositionViewBounds = this._compositionView.getBoundingClientRect();
|
||||
this._textarea.style.position = 'absolute';
|
||||
this._textarea.style.left = cursorLeft + 'px';
|
||||
this._textarea.style.top = cursorTop + 'px';
|
||||
this._textarea.style.width = compositionViewBounds.width + 'px';
|
||||
@@ -218,13 +219,4 @@ export class CompositionHelper {
|
||||
setTimeout(() => this.updateCompositionElements(true), 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the textarea's position so that the cursor does not blink on IE.
|
||||
* @private
|
||||
*/
|
||||
private _clearTextareaPosition(): void {
|
||||
this._textarea.style.left = '';
|
||||
this._textarea.style.top = '';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user