Make terminal rendering work in popout windows
Add support for the parent element (what is passed to Terminal.open) being in a different (same origin) window. Accesses to DOM APIs such as requestAnimationFrame and devicePixelRatio thus need to be scoped to the corrent window, instead of assuming that it's the same as the window/global scope where the code is running. This is done by inferring a parent window at the creation time, and then storing it in CoreBrowserService, which is already passed to most places that need it. To catch future regressions, an ESLint rule that checks for global accesses is added (it uses AST selectors via the no-restricted-syntax rule). This should also be applicable when the parent element is an iframe. Fixes #3758
This commit is contained in:
@@ -38,10 +38,10 @@ export class CursorRenderLayer extends BaseRenderLayer {
|
||||
zIndex: number,
|
||||
colors: IColorSet,
|
||||
private _onRequestRefreshRowsEvent: IEventEmitter<IRequestRedrawEvent>,
|
||||
private readonly _coreBrowserService: ICoreBrowserService,
|
||||
coreBrowserService: ICoreBrowserService,
|
||||
private readonly _coreService: ICoreService
|
||||
) {
|
||||
super(container, 'cursor', zIndex, true, colors);
|
||||
super(container, 'cursor', zIndex, true, colors, coreBrowserService);
|
||||
this._state = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -195,7 +195,7 @@ export class CursorRenderLayer extends BaseRenderLayer {
|
||||
private _clearCursor(): void {
|
||||
if (this._state) {
|
||||
// Avoid potential rounding errors when device pixel ratio is less than 1
|
||||
if (window.devicePixelRatio < 1) {
|
||||
if (this._coreBrowserService.dpr < 1) {
|
||||
this._clearAll();
|
||||
} else {
|
||||
this._clearCells(this._state.x, this._state.y, this._state.width, 1);
|
||||
@@ -257,10 +257,10 @@ class CursorBlinkStateManager {
|
||||
|
||||
constructor(
|
||||
private _renderCallback: () => void,
|
||||
coreBrowserService: ICoreBrowserService
|
||||
private _coreBrowserService: ICoreBrowserService
|
||||
) {
|
||||
this.isCursorVisible = true;
|
||||
if (coreBrowserService.isFocused) {
|
||||
if (this._coreBrowserService.isFocused) {
|
||||
this._restartInterval();
|
||||
}
|
||||
}
|
||||
@@ -269,15 +269,15 @@ class CursorBlinkStateManager {
|
||||
|
||||
public dispose(): void {
|
||||
if (this._blinkInterval) {
|
||||
window.clearInterval(this._blinkInterval);
|
||||
this._coreBrowserService.window.clearInterval(this._blinkInterval);
|
||||
this._blinkInterval = undefined;
|
||||
}
|
||||
if (this._blinkStartTimeout) {
|
||||
window.clearTimeout(this._blinkStartTimeout);
|
||||
this._coreBrowserService.window.clearTimeout(this._blinkStartTimeout);
|
||||
this._blinkStartTimeout = undefined;
|
||||
}
|
||||
if (this._animationFrame) {
|
||||
window.cancelAnimationFrame(this._animationFrame);
|
||||
this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);
|
||||
this._animationFrame = undefined;
|
||||
}
|
||||
}
|
||||
@@ -291,7 +291,7 @@ class CursorBlinkStateManager {
|
||||
// Force a cursor render to ensure it's visible and in the correct position
|
||||
this.isCursorVisible = true;
|
||||
if (!this._animationFrame) {
|
||||
this._animationFrame = window.requestAnimationFrame(() => {
|
||||
this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => {
|
||||
this._renderCallback();
|
||||
this._animationFrame = undefined;
|
||||
});
|
||||
@@ -301,7 +301,7 @@ class CursorBlinkStateManager {
|
||||
private _restartInterval(timeToStart: number = BLINK_INTERVAL): void {
|
||||
// Clear any existing interval
|
||||
if (this._blinkInterval) {
|
||||
window.clearInterval(this._blinkInterval);
|
||||
this._coreBrowserService.window.clearInterval(this._blinkInterval);
|
||||
this._blinkInterval = undefined;
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ class CursorBlinkStateManager {
|
||||
// the regular interval is setup in order to support restarting the blink
|
||||
// animation in a lightweight way (without thrashing clearInterval and
|
||||
// setInterval).
|
||||
this._blinkStartTimeout = window.setTimeout(() => {
|
||||
this._blinkStartTimeout = this._coreBrowserService.window.setTimeout(() => {
|
||||
// Check if another animation restart was requested while this was being
|
||||
// started
|
||||
if (this._animationTimeRestarted) {
|
||||
@@ -323,13 +323,13 @@ class CursorBlinkStateManager {
|
||||
|
||||
// Hide the cursor
|
||||
this.isCursorVisible = false;
|
||||
this._animationFrame = window.requestAnimationFrame(() => {
|
||||
this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => {
|
||||
this._renderCallback();
|
||||
this._animationFrame = undefined;
|
||||
});
|
||||
|
||||
// Setup the blink interval
|
||||
this._blinkInterval = window.setInterval(() => {
|
||||
this._blinkInterval = this._coreBrowserService.window.setInterval(() => {
|
||||
// Adjust the animation time if it was restarted
|
||||
if (this._animationTimeRestarted) {
|
||||
// calc time diff
|
||||
@@ -342,7 +342,7 @@ class CursorBlinkStateManager {
|
||||
|
||||
// Invert visibility and render
|
||||
this.isCursorVisible = !this.isCursorVisible;
|
||||
this._animationFrame = window.requestAnimationFrame(() => {
|
||||
this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => {
|
||||
this._renderCallback();
|
||||
this._animationFrame = undefined;
|
||||
});
|
||||
@@ -353,15 +353,15 @@ class CursorBlinkStateManager {
|
||||
public pause(): void {
|
||||
this.isCursorVisible = true;
|
||||
if (this._blinkInterval) {
|
||||
window.clearInterval(this._blinkInterval);
|
||||
this._coreBrowserService.window.clearInterval(this._blinkInterval);
|
||||
this._blinkInterval = undefined;
|
||||
}
|
||||
if (this._blinkStartTimeout) {
|
||||
window.clearTimeout(this._blinkStartTimeout);
|
||||
this._coreBrowserService.window.clearTimeout(this._blinkStartTimeout);
|
||||
this._blinkStartTimeout = undefined;
|
||||
}
|
||||
if (this._animationFrame) {
|
||||
window.cancelAnimationFrame(this._animationFrame);
|
||||
this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);
|
||||
this._animationFrame = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user