Merge branch 'master' into handle-delete-composition-helper

This commit is contained in:
Daniel Imms
2022-09-07 09:39:54 -07:00
committed by GitHub
59 changed files with 1340 additions and 547 deletions
+72
View File
@@ -0,0 +1,72 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '41 17 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
+1 -1
View File
@@ -140,7 +140,7 @@ Xterm.js is used in several world-class applications to provide great terminal e
- [**Fluent Terminal**](https://github.com/felixse/FluentTerminal): A terminal emulator based on UWP and web technologies.
- [**Hyper**](https://hyper.is): A terminal built on web technologies.
- [**Diag**](https://diag.ai): A better way to troubleshoot problems faster. Capture, share and reapply troubleshooting knowledge so you can focus on solving problems that matter.
- [**GoTTY**](https://github.com/yudai/gotty): A simple command line tool that shares your terminal as a web application based on xterm.js.
- [**GoTTY**](https://github.com/sorenisanerd/gotty): A simple command line tool that shares your terminal as a web application based on xterm.js.
- [**genact**](https://github.com/svenstaro/genact): A nonsense activity generator.
- [**cPanel & WHM**](https://cpanel.com): The hosting platform of choice.
- [**Nutanix**](https://github.com/nutanix): Nutanix Enterprise Cloud uses xterm in the webssh functionality within Nutanix Calm, and is also looking to move our old noserial (termjs) functionality to xterm.js.
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"dom",
"es2015"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"es2015"
],
@@ -3,12 +3,11 @@
* @license MIT
*/
import { IRenderDimensions, IRequestRedrawEvent } from 'browser/renderer/Types';
import { IRenderDimensions } from 'browser/renderer/Types';
import { BaseRenderLayer } from './BaseRenderLayer';
import { IColorSet } from 'browser/Types';
import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services';
import { ICoreBrowserService } from 'browser/services/Services';
import { IEventEmitter } from 'common/EventEmitter';
interface ISelectionState {
start?: [number, number];
@@ -8,7 +8,7 @@ import { BaseCharAtlas } from './BaseCharAtlas';
import { DynamicCharAtlas } from './DynamicCharAtlas';
import { ICharAtlasConfig } from './Types';
import { IColorSet } from 'browser/Types';
import { ITerminalOptions } from 'common/services/Services';
import { ITerminalOptions } from 'xterm';
interface ICharAtlasCacheEntry {
atlas: BaseCharAtlas;
@@ -25,7 +25,7 @@ const charAtlasCache: ICharAtlasCacheEntry[] = [];
* one that is in use by another terminal.
*/
export function acquireCharAtlas(
options: ITerminalOptions,
options: Required<ITerminalOptions>,
rendererId: number,
colors: IColorSet,
scaledCharWidth: number,
@@ -6,9 +6,9 @@
import { ICharAtlasConfig } from './Types';
import { DEFAULT_COLOR } from 'common/buffer/Constants';
import { IColorSet, IPartialColorSet } from 'browser/Types';
import { ITerminalOptions } from 'common/services/Services';
import { ITerminalOptions } from 'xterm';
export function generateConfig(scaledCharWidth: number, scaledCharHeight: number, options: ITerminalOptions, colors: IColorSet): ICharAtlasConfig {
export function generateConfig(scaledCharWidth: number, scaledCharHeight: number, options: Required<ITerminalOptions>, colors: IColorSet): ICharAtlasConfig {
// null out some fields that don't matter
const clonedColors: IPartialColorSet = {
foreground: colors.foreground,
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"dom",
"es6"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"dom",
"es2015"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"es2015"
],
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"dom",
"es6",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"es6",
],
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"dom",
"es2015"
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"es2015"
],
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"dom",
"es2015"
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"es2015"
],
+14 -14
View File
@@ -8,7 +8,7 @@ import { WebglCharAtlas } from './atlas/WebglCharAtlas';
import { IWebGL2RenderingContext, IWebGLVertexArrayObject, IRenderModel, IRasterizedGlyph } from './Types';
import { fill } from 'common/TypedArrayUtils';
import { NULL_CELL_CODE } from 'common/buffer/Constants';
import { Terminal, IBufferLine } from 'xterm';
import { Terminal } from 'xterm';
import { IColorSet } from 'browser/Types';
import { IRenderDimensions } from 'browser/renderer/Types';
import { Disposable, toDisposable } from 'common/Lifecycle';
@@ -238,21 +238,24 @@ export class GlyphRenderer extends Disposable {
// a_cellpos only changes on resize
}
public clear(force?: boolean): void {
public clear(): void {
const terminal = this._terminal;
const newCount = terminal.cols * terminal.rows * INDICES_PER_CELL;
// Don't clear if not forced and the array length is correct
if (!force && this._vertices.count === newCount) {
return;
}
// Clear vertices
this._vertices.count = newCount;
this._vertices.attributes = new Float32Array(newCount);
for (let i = 0; i < this._vertices.attributesBuffers.length; i++) {
this._vertices.attributesBuffers[i] = new Float32Array(newCount);
if (this._vertices.count !== newCount) {
this._vertices.attributes = new Float32Array(newCount);
} else {
this._vertices.attributes.fill(0);
}
for (let i = 0; i < this._vertices.attributesBuffers.length; i++) {
if (this._vertices.count !== newCount) {
this._vertices.attributesBuffers[i] = new Float32Array(newCount);
} else {
this._vertices.attributesBuffers[i].fill(0);
}
}
this._vertices.count = newCount;
let i = 0;
for (let y = 0; y < terminal.rows; y++) {
for (let x = 0; x < terminal.cols; x++) {
@@ -269,9 +272,6 @@ export class GlyphRenderer extends Disposable {
this.clear();
}
public setColors(): void {
}
public render(renderModel: IRenderModel): void {
if (!this._atlas) {
return;
-4
View File
@@ -3,10 +3,6 @@
* @license MIT
*/
export interface IRasterizedGlyphSet {
[bg: number]: { [fg: number]: { [ext: number]: IRasterizedGlyph } } | undefined;
}
/**
* Represents a rasterized glyph within a texture atlas. Some numbers are
* tracked in CSS pixels as well in order to reduce calculations during the
+64 -19
View File
@@ -46,13 +46,14 @@ export class WebglRenderer extends Disposable implements IRenderer {
private _canvas: HTMLCanvasElement;
private _gl: IWebGL2RenderingContext;
private _rectangleRenderer: RectangleRenderer;
private _glyphRenderer: GlyphRenderer;
private _rectangleRenderer!: RectangleRenderer;
private _glyphRenderer!: GlyphRenderer;
public dimensions: IRenderDimensions;
private _core: ITerminal;
private _isAttached: boolean;
private _contextRestorationTimeout: number | undefined;
private _onChangeTextureAtlas = new EventEmitter<HTMLCanvasElement>();
public get onChangeTextureAtlas(): IEvent<HTMLCanvasElement> { return this._onChangeTextureAtlas.event; }
@@ -108,16 +109,34 @@ export class WebglRenderer extends Disposable implements IRenderer {
throw new Error('WebGL2 not supported ' + this._gl);
}
this.register(addDisposableDomListener(this._canvas, 'webglcontextlost', (e) => { this._onContextLoss.fire(e); }));
this.register(addDisposableDomListener(this._canvas, 'webglcontextlost', (e) => {
console.log('webglcontextlost event received');
// Prevent the default behavior in order to enable WebGL context restoration.
e.preventDefault();
// Wait a few seconds to see if the 'webglcontextrestored' event is fired.
// If not, dispatch the onContextLoss notification to observers.
this._contextRestorationTimeout = setTimeout(() => {
this._contextRestorationTimeout = undefined;
console.warn('webgl context not restored; firing onContextLoss');
this._onContextLoss.fire(e);
}, 3000 /* ms */);
}));
this.register(addDisposableDomListener(this._canvas, 'webglcontextrestored', (e) => {
console.warn('webglcontextrestored event received');
clearTimeout(this._contextRestorationTimeout);
this._contextRestorationTimeout = undefined;
// The texture atlas and glyph renderer must be fully reinitialized
// because their contents have been lost.
removeTerminalFromCache(this._terminal);
this._initializeWebGLState();
this._requestRedrawViewport();
}));
this.register(observeDevicePixelDimensions(this._canvas, (w, h) => this._setCanvasDevicePixelDimensions(w, h)));
this._core.screenElement!.appendChild(this._canvas);
this._rectangleRenderer = this.register(new RectangleRenderer(this._terminal, this._colors, this._gl, this.dimensions));
this._glyphRenderer = this.register(new GlyphRenderer(this._terminal, this._colors, this._gl, this.dimensions));
// Update dimensions and acquire char atlas
this.onCharSizeChanged();
this._initializeWebGLState();
this._isAttached = document.body.contains(this._core.screenElement!);
}
@@ -144,12 +163,11 @@ export class WebglRenderer extends Disposable implements IRenderer {
}
this._rectangleRenderer.setColors();
this._glyphRenderer.setColors();
this._refreshCharAtlas();
// Force a full refresh
this._model.clear();
this._clearModel(true);
}
public onDevicePixelRatioChange(): void {
@@ -189,8 +207,9 @@ export class WebglRenderer extends Disposable implements IRenderer {
this._refreshCharAtlas();
// Force a full refresh
this._model.clear();
// Force a full refresh. Resizing `_glyphRenderer` should clear it already,
// so there is no need to clear it again here.
this._clearModel(false);
}
public onCharSizeChanged(): void {
@@ -235,6 +254,21 @@ export class WebglRenderer extends Disposable implements IRenderer {
this._refreshCharAtlas();
}
/**
* Initializes members dependent on WebGL context state.
*/
private _initializeWebGLState(): void {
// Dispose any previous rectangle and glyph renderers before creating new ones.
this._rectangleRenderer?.dispose();
this._glyphRenderer?.dispose();
this._rectangleRenderer = new RectangleRenderer(this._terminal, this._colors, this._gl, this.dimensions);
this._glyphRenderer = new GlyphRenderer(this._terminal, this._colors, this._gl, this.dimensions);
// Update dimensions and acquire char atlas
this.onCharSizeChanged();
}
/**
* Refreshes the char atlas, aquiring a new one if necessary.
* @param terminal The terminal.
@@ -259,16 +293,27 @@ export class WebglRenderer extends Disposable implements IRenderer {
this._glyphRenderer.setAtlas(this._charAtlas);
}
/**
* Clear the model.
* @param clearGlyphRenderer Whether to also clear the glyph renderer. This
* should be true generally to make sure it is in the same state as the model.
*/
private _clearModel(clearGlyphRenderer: boolean): void {
this._model.clear();
if (clearGlyphRenderer) {
this._glyphRenderer.clear();
}
}
public clearCharAtlas(): void {
this._charAtlas?.clearTexture();
this._model.clear();
this._clearModel(true);
this._updateModel(0, this._terminal.rows - 1);
this._requestRedrawViewport();
}
public clear(): void {
this._model.clear();
this._glyphRenderer.clear(true);
this._clearModel(true);
for (const l of this._renderLayers) {
l.reset(this._terminal);
}
@@ -300,7 +345,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
// Tell renderer the frame is beginning
if (this._glyphRenderer.beginFrame()) {
this._model.clear();
this._clearModel(true);
this._updateSelectionModel(undefined, undefined);
}
@@ -588,18 +633,18 @@ export class WebglRenderer extends Disposable implements IRenderer {
// Calculate the scaled cell height, if lineHeight is _not_ 1, the resulting value will be
// floored since lineHeight can never be lower then 1, this guarentees the scaled cell height
// will always be larger than scaled char height.
this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._terminal.options.lineHeight!);
this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._terminal.options.lineHeight);
// Calculate the y offset within a cell that glyph should draw at in order for it to be centered
// correctly within the cell.
this.dimensions.scaledCharTop = this._terminal.options.lineHeight === 1 ? 0 : Math.round((this.dimensions.scaledCellHeight - this.dimensions.scaledCharHeight) / 2);
// Calculate the scaled cell width, taking the letterSpacing into account.
this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._terminal.options.letterSpacing!);
this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._terminal.options.letterSpacing);
// Calculate the x offset with a cell that text should draw from in order for it to be centered
// correctly within the cell.
this.dimensions.scaledCharLeft = Math.floor(this._terminal.options.letterSpacing! / 2);
this.dimensions.scaledCharLeft = Math.floor(this._terminal.options.letterSpacing / 2);
// Recalculate the canvas dimensions, the scaled dimensions define the actual number of pixel in
// the canvas
@@ -32,21 +32,21 @@ export function generateConfig(scaledCellWidth: number, scaledCellHeight: number
contrastCache: colors.contrastCache
};
return {
customGlyphs: terminal.options.customGlyphs!,
customGlyphs: terminal.options.customGlyphs,
devicePixelRatio: window.devicePixelRatio,
letterSpacing: terminal.options.letterSpacing!,
lineHeight: terminal.options.lineHeight!,
letterSpacing: terminal.options.letterSpacing,
lineHeight: terminal.options.lineHeight,
scaledCellWidth,
scaledCellHeight,
scaledCharWidth,
scaledCharHeight,
fontFamily: terminal.options.fontFamily!,
fontSize: terminal.options.fontSize!,
fontWeight: terminal.options.fontWeight as FontWeight,
fontWeightBold: terminal.options.fontWeightBold as FontWeight,
allowTransparency: terminal.options.allowTransparency!,
drawBoldTextInBrightColors: terminal.options.drawBoldTextInBrightColors!,
minimumContrastRatio: terminal.options.minimumContrastRatio!,
fontFamily: terminal.options.fontFamily,
fontSize: terminal.options.fontSize,
fontWeight: terminal.options.fontWeight,
fontWeightBold: terminal.options.fontWeightBold,
allowTransparency: terminal.options.allowTransparency,
drawBoldTextInBrightColors: terminal.options.drawBoldTextInBrightColors,
minimumContrastRatio: terminal.options.minimumContrastRatio,
colors: clonedColors
};
}

Some files were not shown because too many files have changed in this diff Show More