terminal: fall back to canvas renderer if webgl is not supported
All offical chromebook devices should support webgl, but some flex
devices using old chipset do not.
Including the xterm.js canvas addon increase ~20KB of the distribution
size.
Bug: b/276755418
Change-Id: I0157f050cb1c189daeb6ea8c084cd2070e42fcac
Reviewed-on: https://chromium-review.googlesource.com/c/apps/libapps/+/4438769
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Joel Hockey <joelhockey@chromium.org>
diff --git a/libdot/bin/node b/libdot/bin/node
index 6a95a8a..3d47525 100755
--- a/libdot/bin/node
+++ b/libdot/bin/node
@@ -17,7 +17,7 @@
# Allow a long line for easy automated updating.
# pylint: disable=line-too-long
NODE_MODULES_HASH = (
- "7ba7922c19bbf9df60d316121cf314ebaea046c8ddcf9ba3a41f92a8607738a7"
+ "a98c76bf5c11b1fa8caadcdda9c4945d5436b619e3b41868adf91f739b7ec06f"
)
# pylint: enable=line-too-long
diff --git a/nassh/js/deps_xterm.shim.js b/nassh/js/deps_xterm.shim.js
index f28baab..e07e2af 100644
--- a/nassh/js/deps_xterm.shim.js
+++ b/nassh/js/deps_xterm.shim.js
@@ -7,8 +7,9 @@
*/
import {Terminal} from 'xterm';
+import {CanvasAddon} from 'xterm-addon-canvas';
import {Unicode11Addon} from 'xterm-addon-unicode11';
import {WebglAddon} from 'xterm-addon-webgl';
import {WebLinksAddon} from 'xterm-addon-web-links';
-export const xterm = {Terminal, Unicode11Addon, WebLinksAddon,
+export const xterm = {Terminal, CanvasAddon, Unicode11Addon, WebLinksAddon,
WebglAddon};
diff --git a/package.json b/package.json
index c3d56c6..d1dccaf 100644
--- a/package.json
+++ b/package.json
@@ -56,6 +56,7 @@
"webpack": "~5",
"webpack-cli": "~4",
"xterm": "^5.1.0",
+ "xterm-addon-canvas": "^0.3.0",
"xterm-addon-unicode11": "^0.5.0",
"xterm-addon-web-links": "^0.8.0",
"xterm-addon-webgl": "^0.14.0"
diff --git a/terminal/js/terminal_common.js b/terminal/js/terminal_common.js
index 733959c..8fb4565 100644
--- a/terminal/js/terminal_common.js
+++ b/terminal/js/terminal_common.js
@@ -55,12 +55,6 @@
export const SUPPORTED_LINE_HEIGHT = [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8,
1.9, 2];
-export const TERMINAL_EMULATORS = new Map([
- ['xterm.js', {lib: 'xterm.js', webgl: true}],
- ['xterm.js (disable WebGl)', {lib: 'xterm.js', webgl: false}],
- ['hterm', {lib: 'hterm', webgl: false}],
-]);
-
// Numeric chrome version (e.g. 78). `null` if fail to detect.
export const CHROME_VERSION = (function() {
const matches = navigator.userAgent.match(/Chrome\/(\d+)/);
diff --git a/terminal/js/terminal_emulator.js b/terminal/js/terminal_emulator.js
index 0d32bbf..0b74c72 100644
--- a/terminal/js/terminal_emulator.js
+++ b/terminal/js/terminal_emulator.js
@@ -14,14 +14,12 @@
import {hterm, lib} from './deps_local.concat.js';
import {LitElement, css, html} from './lit.js';
-import {FontManager, ORIGINAL_URL, TERMINAL_EMULATORS,
- backgroundImageLocalStorageKey, definePrefs, delayedScheduler, fontManager,
- getOSInfo, sleep}
- from './terminal_common.js';
+import {FontManager, ORIGINAL_URL, backgroundImageLocalStorageKey, definePrefs,
+ delayedScheduler, fontManager, getOSInfo, sleep} from './terminal_common.js';
import {TerminalContextMenu} from './terminal_context_menu.js';
import {ICON_COPY} from './terminal_icons.js';
import {TerminalTooltip} from './terminal_tooltip.js';
-import {Terminal, Unicode11Addon, WebLinksAddon, WebglAddon}
+import {Terminal, CanvasAddon, Unicode11Addon, WebLinksAddon, WebglAddon}
from './xterm.js';
import {XtermInternal} from './terminal_xterm_internal.js';
@@ -429,11 +427,10 @@
* @param {{
* storage: !lib.Storage,
* profileId: string,
- * enableWebGL: boolean,
* testParams: (!XtermTerminalTestParams|undefined),
* }} args
*/
- constructor({storage, profileId, enableWebGL, testParams}) {
+ constructor({storage, profileId, testParams}) {
this.ctrlCKeyDownHandler_ = this.ctrlCKeyDownHandler_.bind(this);
this.ctrlVKeyDownHandler_ = this.ctrlVKeyDownHandler_.bind(this);
this.zoomKeyDownHandler_ = this.zoomKeyDownHandler_.bind(this);
@@ -443,7 +440,6 @@
/** @type {!hterm.PreferenceManager} */
this.prefs_ = new hterm.PreferenceManager(storage, profileId);
definePrefs(this.prefs_);
- this.enableWebGL_ = enableWebGL;
// TODO: we should probably pass the initial prefs to the ctor.
this.term = testParams?.term || new Terminal({allowProposedApi: true});
@@ -451,6 +447,12 @@
new XtermInternal(this.term);
this.fontManager_ = testParams?.fontManager || fontManager;
+ this.renderAddonType_ = WebglAddon;
+ if (!document.createElement('canvas').getContext('webgl')) {
+ console.warn('Webgl is not supported. Fall back to canvas renderer');
+ this.renderAddonType_ = CanvasAddon;
+ }
+
/** @type {?Element} */
this.container_;
this.bell_ = new Bell();
@@ -517,7 +519,7 @@
this.scrollOnOutputListener_ = null;
this.backgroundImageWatcher_ = new BackgroundImageWatcher(this.prefs_,
this.setBackgroundImage.bind(this));
- this.webglAddon_ = null;
+ this.renderAddon_ = null;
this.userCSSElement_ = null;
this.userCSSTextElement_ = null;
@@ -745,9 +747,7 @@
this.term.open(elem);
this.xtermInternal_.addDimensionsObserver(() => this.scheduleFit_());
- if (this.enableWebGL_) {
- this.reloadWebglAddon_();
- }
+ this.reloadRenderAddon_();
this.term.focus();
(new ResizeObserver(() => this.scheduleFit_())).observe(elem);
this.htermA11yReader_ = new hterm.AccessibilityReader(elem);
@@ -952,12 +952,12 @@
}
}
- reloadWebglAddon_() {
- if (this.webglAddon_) {
- this.webglAddon_.dispose();
+ reloadRenderAddon_() {
+ if (this.renderAddon_) {
+ this.renderAddon_.dispose();
}
- this.webglAddon_ = new WebglAddon();
- this.term.loadAddon(this.webglAddon_);
+ this.renderAddon_ = new this.renderAddonType_();
+ this.term.loadAddon(this.renderAddon_);
}
/**
@@ -975,10 +975,10 @@
// This could be a bug with xterm.js.
if (!!this.term.options.allowTransparency !== hasBackgroundImage) {
this.term.options.allowTransparency = hasBackgroundImage;
- if (this.enableWebGL_ && this.inited_) {
- // Setting allowTransparency in the middle messes up webgl rendering,
- // so we need to reload it here.
- this.reloadWebglAddon_();
+ if (this.inited_) {
+ // Setting allowTransparency in the middle messes up rendering, so we
+ // need to reload it here.
+ this.reloadRenderAddon_();
}
}
@@ -1480,34 +1480,25 @@
* @return {!Promise<!hterm.Terminal>}
*/
export async function createEmulator({storage, profileId}) {
- let config = TERMINAL_EMULATORS.get('hterm');
+ let emulator_type = 'hterm';
if (getOSInfo().alternative_emulator) {
// TODO: remove the url param logic. This is temporary to make manual
- // testing a bit easier, which is also why this is not in
- // './js/terminal_info.js'.
- const emulator = ORIGINAL_URL.searchParams.get('emulator');
- // Use the default (i.e. first) one if the pref is not set or invalid.
- config = TERMINAL_EMULATORS.get(emulator) ||
- TERMINAL_EMULATORS.values().next().value;
- console.log('Terminal emulator config: ', config);
+ // testing a bit easier.
+ if (ORIGINAL_URL.searchParams.get('emulator') !== 'hterm') {
+ emulator_type = 'xterm.js';
+ }
+ console.log('Terminal emulator type: ', emulator_type);
}
- switch (config.lib) {
- case 'xterm.js':
- {
- const terminal = new XtermTerminal({
- storage,
- profileId,
- enableWebGL: config.webgl,
- });
- return terminal;
- }
- case 'hterm':
- return new HtermTerminal({profileId, storage});
- default:
- throw new Error('incorrect emulator config');
+ if (emulator_type === 'hterm') {
+ return new HtermTerminal({profileId, storage});
}
+
+ return new XtermTerminal({
+ storage,
+ profileId,
+ });
}
class TerminalCopyNotice extends LitElement {
diff --git a/terminal/js/terminal_emulator_tests.js b/terminal/js/terminal_emulator_tests.js
index 18a0a59..29f5dc8 100644
--- a/terminal/js/terminal_emulator_tests.js
+++ b/terminal/js/terminal_emulator_tests.js
@@ -38,7 +38,6 @@
this.terminal = new XtermTerminal({
storage: new lib.Storage.Memory(),
profileId: 'test',
- enableWebGL: true,
testParams: /** @type {!XtermTerminalTestParams} */(testParams),
});
diff --git a/terminal/js/xterm.js b/terminal/js/xterm.js
index 7a53a05..c209e70 100644
--- a/terminal/js/xterm.js
+++ b/terminal/js/xterm.js
@@ -8,5 +8,5 @@
import {xterm} from './deps_xterm.rollup.js';
/** @suppress {undefinedVars} */
-export const {Terminal, Unicode11Addon, WebLinksAddon, WebglAddon}
+export const {Terminal, CanvasAddon, Unicode11Addon, WebLinksAddon, WebglAddon}
= xterm;